As a Linux administrator, you understand the significance of regular backups for your servers. Having backups is like having an insurance policy for your data – it’s always better to have it, just in case. And what’s even better? Automating this process with a Bash script and the rsync tool.

This tutorial will guide you through the creation of a Bash script to backup an entire Linux server to another Linux server using rsync. You’ll learn to design the script efficiently to avoid any potential issues during the backup process.

We’ll begin by discussing the rsync options:

  • “-a” option preserves permissions, ownership, timestamps of the files/directories transferred, equivalent to the options -rlptgoD.
  • “-A” option saves Access Control Lists (ACLs) to specify fine-grained permissions for files/directories.
  • “-X” option retains extended attributes, metadata for files/directories beyond the standard permissions and timestamps.
  • “-H” option keeps hard links between files, which point to the same file data on the file system.
  • “-v” option provides detailed output to monitor the transfer process.
  • “–delete” option deletes files from the target that are missing from the source, keeping the backup in sync with the source.

With these options, your backup will be a complete and accurate representation of the source server.

PID & Exclude

Next, we’ll add an exclusion list to exclude unneeded directories like /sys/, /proc/, /dev/ , /srv/, /mnt/, /media/ and /lost+found/. These are system directories that don’t contain valuable data. Excluding them will speed up the backup and reduce storage space on the target server. (Please note that /mnt might include external mounts and /media attached USB storage devices on your server, if needed remove them from the exclude list.)

Moving on to the script itself, it starts by checking if another instance of the script is running by looking for a PID file. When found, the script reads the PID and checks if the process is running. If another instance is running, the script exits with code 1 to indicate failure.

If another instance is not running, the script writes the current PID to the PID file to indicate it is running. The script then sets the source and target servers and the exclusion list for the rsync transfer.

Finally, the script runs the rsync command with the specified options and exclusion list. After the transfer, it checks the exit code of the rsync command to determine success or failure. If successful, it removes the PID file and exits with code 0. If not, it removes the PID file and exits with a non-zero exit code to indicate failure.

SSH Keys

We’ll then set up the SSH keys for rsync. The script checks for the presence of a key in $HOME/.ssh/ directory. If not found, it generates a new key using ssh-keygen.

The new or existing key is then copied to the target server with ssh-copy-id. This step is necessary for the source server to connect to the target server without a password. The rsync command uses the “-e” option and the “ssh -i $HOME/.ssh/id_rsa” argument to specify the private key for the ssh connection.

By using SSH keys, the script ensures secure and automated transfers. You won’t need to enter a password, making the backup process more efficient and less prone to human error.

And that’s it! A simple and efficient way to automate backups for your Linux servers using rsync and a Bash script.

Script

#!/bin/bash
# 01-02-2023 scripting[at]w-solutions[dot]dev

####################################################################
# Define the source and target servers
source_server=user@source.server.com:/
target_server=user@target.server.com:/backup/

####################################################################
# Check if screen is installed
if ! command -v screen &> /dev/null; then
  echo "Screen is not installed, installing it now..."
  # Install screen package using the system's package manager
  if [ "$(which apt-get)" != "" ]; then
    sudo apt-get install screen -y
  elif [ "$(which yum)" != "" ]; then
    sudo yum install screen -y
  elif [ "$(which pkg)" != "" ]; then
    sudo pkg install screen -y
  elif [ "$(which apk)" != "" ]; then
    sudo apk add screen -y
  else
    echo "Your system's package manager is not supported. Please install screen manually."
    exit 1
  fi
else
  echo "Screen is already installed."
fi

####################################################################
# Check if rsync is installed
if ! command -v rsync &> /dev/null; then
  echo "Screen is not installed, installing it now..."
  # Install screen package using the system's package manager
  if [ "$(which apt-get)" != "" ]; then
    sudo apt-get install rsync -y
  elif [ "$(which yum)" != "" ]; then
    sudo yum install rsync -y
  elif [ "$(which pkg)" != "" ]; then
    sudo pkg install rsync -y
  elif [ "$(which apk)" != "" ]; then
    sudo apk add rsync -y
  else
    echo "Your system's package manager is not supported. Please install rsync manually."
    exit 1
  fi
else
  echo "rsync is already installed."
fi

####################################################################
# Check if ssh key is present
if [ ! -f "$HOME/.ssh/id_rsa" ]; then
  echo "SSH key not found, generating one now..."
  ssh-keygen -t rsa -b 4096 -f "$HOME/.ssh/id_rsa" -q -N ""
fi

# Copy ssh key to target server
echo "Copying ssh key to target server... Please enter your password once."
ssh-copy-id -i "$HOME/.ssh/id_rsa.pub" "$target_server"

####################################################################
# Define the excluded directories
excluded_dirs=(
  "sys/*"
  "proc/*"
  "dev/*"
  "tmp/*"
  "run/*"
  "mnt/*"
  "media/*"
  "lost+found/*"
)

excluded_options=""
for dir in "${excluded_dirs[@]}"; do
  excluded_options="$excluded_options --exclude=$dir"
done

####################################################################
# Check if another instance of the script is already running
pid_file="/var/run/rsync_backup.pid"
if [ -f $pid_file ]; then
    pid=$(cat $pid_file)
    if kill -0 &> /dev/null $pid; then
        echo "Another instance of the script is already running."
        exit 1
    else
        #Remove stale pid file
        rm $pid_file
    fi
fi
echo $$ > $pid_file

####################################################################
# Synchronize files using rsync with ssh keys
screen -dmS rsync_backup
screen -S rsync_backup -p 0 -X eval 'rsync -aAXHv --delete $excluded_options -e "ssh -i ~/.ssh/id_rsa" $source_server $target_server'
screen -X -S "rsync_backup" quit

####################################################################
# Remove the pid file
echo "Backup complete, removing lock file..."
rm $pid_file

####################################################################
# Check the exit code of the rsync command
if [ $? -eq 0 ]; then
  echo "The rsync backup was successful."
  exit_code=0
else
  echo "The rsync backup failed."
  exit_code=1
fi

####################################################################
# Exit with the appropriate exit code
exit $exit_code

Do you need help with Linux servers? Reach out and see what we can do for you or visit our store to browse through the different support packages we offer.


0 Comments

Leave a Reply

en_USEnglish