How to Create a Full Backup System with Linux scp and cron

I wanted to create a backup system using tools I already knew, such as scp. I set up a way for it to send a backup to a remote server at home with a 2nd SSH key specifically for the task.

1. Generate the key on the server you’ll be backing up with ssh-keygen. Save the key to something like ~/.ssh/backup-key, and configure it how you like.

2. Transfer the private key to your PC (not any of the servers). Disconnect from the server by typing exit, then scp the key to your PC. This will transfer the private key to your PC so you can copy it to the server you are backing up to.

exit
scp -i ~/.ssh/current-key server-user@server-to-backup.domain:/home/server-user/.ssh/backup-key  ~/.ssh/backup-key

3. Transfer the private key to the server you are backing up to. There’s a few ways to do this, but I used this method since I already had authentication set up with a different SSH key. Replace backup-key with your new key if you used a different name, and replace current-priv-key with your current working key.

scp -i ~/.ssh/current-priv-key ~/.ssh/backup-key bkup-user@the-backup-server.domain:/home/bkup-user/.ssh/backup-key

4. Connect to the server you are backing up to. Create the backup folder /home/bkup-user/backup, then a folder for the server you are backing up, such as /home/bkup-user/backup/server-name.

# ssh into the backup server before doing this, and run it there
mkdir /home/bkup-user/backup
mkdir /home/bkup-user/backup/server-name

5. Create a script that we will use for crontab to run. Use nano to open it.

nano /home/bkup-user/backup-script.sh

6. Copy this script, and change the parts in bold as needed. We will be making a couple scripts on the backup server itself as well after this.

#! /bin/bash
# runs scripts on the server that backs up databases and creates a tar file with all the files needed to be backed up
ssh -i .ssh/backup-key server-user@server-to-backup.domain "./backup.sh"
# once above command runs, it is disconnected
# back on the backup server, downloads temp directory to the backup server
scp -r -i .ssh/backup-key server-user@server-to-backup.domain:/home/server-user/temp /home/bkup-user/backup/server-name
# everything is downloaded to /temp; this will move it down a directory
mv /home/bkup-user/backup/server-name/temp/* /home/bkup-user/backup/server-name
# removes the temp folder
rm -r /home/bkup-user/backup/server-name/temp
# deletes all files older than 30 days
find /home/bkup-user/backup/server-name -type f -mtime +30 -delete
# goes back into the remote server and deletes the backed up file
ssh -i .ssh/backup-key server-user@server-to-backup.domain "./bkup_deltemp.sh"

7. Give the script executable permissions with chmod. Then open the crontab editor.

chmod +x /home/bkup-user/backup-script.sh
crontab -e

8. Add this line to crontab. This will run the script daily at 12am. Then exit crontab with ctrl+x and save the settings.

0 0 * * * /home/bkup-user/backup-script.sh

9. Open up visudo to give the script sudo permissions.

sudo visudo

10. Add this line to the sudoers file that opened, then ctrl+x and save the configuration.

bkup-user ALL=(ALL) NOPASSWD:/home/bkup-user/backup-script.sh

11. Disconnect from the backup server, then connect with ssh to the server you are backing up. Create a temp folder.

# ssh into the server you are backing up before doing this, and run it there
mkdir /home/server-user/temp

12. Open up a new script with nano called backup.sh, then give it this code and save it:

#! /bin/bash
tar -czvf "/home/server-user/temp/server-name-$(date +"%d-%m-%Y").tar.gz" -T backup-list.txt

13. Create another script with nano for deleting the temp contents once the backup is completed. Name it bkup_deltemp.sh and give it this code:

#! /bin/bash
rm /home/server-user/temp/*

14. Create a text file with nano that you will use to set up the directories and files you want to backup. Here is an example text file I use to back up my web server:

/home/server-user/backup-list.txt
/home/server-user/bkup_script.sh
/home/server-user/bkup_deltemp.sh
/etc/systemd/system/website-1.service
/etc/systemd/system/website-2.service
/var/www
/etc/nginx/sites-available
/etc/nginx/sites-enabled

15. The back up should now be set up. You can test this by logging into the backup server and running the backup script, then checking the ~/backup/server-name folder for a .tar.gz file.

./backup-script.sh
cd ~/backup/server-name

This does not include a mysql database backup, as I did not want to add more complexity to this post. If you have a mysql database backup already configured, you can add it to the backup-list.txt.

Otherwise, you can look into creating a separate script to backup mysql, use a cron job on the server to run it an hour before (0 23 * * *), and include the mysql backup files into the backup-list.txt. I used this script from github: GitHub Script

Leave a Reply

Your email address will not be published. Required fields are marked *