From 957a72a1c4a1e35133135495dd7d55a474259665 Mon Sep 17 00:00:00 2001 From: Dashamir Hoxha Date: Sun, 19 Jul 2020 17:22:42 +0000 Subject: [PATCH] Update 'infrastructure/server-backup-with-rsync.md' --- infrastructure/server-backup-with-rsync.md | 157 +++++++++++++++------ 1 file changed, 112 insertions(+), 45 deletions(-) diff --git a/infrastructure/server-backup-with-rsync.md b/infrastructure/server-backup-with-rsync.md index 7c617f4..a650ce9 100644 --- a/infrastructure/server-backup-with-rsync.md +++ b/infrastructure/server-backup-with-rsync.md @@ -1,77 +1,144 @@ -# Server Backup +# Server Backup With Rsync -There are many ways to make a server backup, but we will use `rsync` (remote sync), `bindfs`, and `rssh` (restricted shell). +1. Make sure that rsync is installed on the server: -## Create a backup user with restricted shell access + ``` + apt install rsync + ``` -1. Install rssh: +1. Create a backup user, for example `backup1`: - ```console - apt list rssh - apt show rssh - apt install rssh + ``` + useradd backup1 -m + ls -al /home/backup1/ ``` -2. Create a user for backups that uses the restricted shell: +1. Create a ssh key-pair for this user: + + ``` + ssh-keygen -t ecdsa -P '' -q -f key1 - ```console - useradd apps_backup -m -s /usr/bin/rssh - ls -al /home/apps_backup/ - grep apps_backup /etc/passwd + ls -l key1* + cat key1 + cat key1.pub ``` -3. Edit `/etc/rssh.conf` to allow `rsync` and use a chroot jail for restricting access: +1. Add the public key to `/home/backup1/.ssh/authorized_keys`: - ```console - allowrsync - chrootpath = /home/apps_backup ``` + mkdir -p /home/backup1/.ssh + chown backup1: /home/backup1/.ssh + chmod 700 /home/backup1/.ssh -4. Test that the shell of the user `apps_backup` is restricted: + cat key1.pub >> /home/backup1/.ssh/authorized_keys + chown backup1: /home/backup1/.ssh/authorized_keys + chmod 600 /home/backup1/.ssh/authorized_keys - ```console - su apps_backup + ls -al /home/backup1/.ssh/ + cat /home/backup1/.ssh/authorized_keys + ``` + +1. Try to login with this key: + + ``` + ssh -p 22 -i key1 backup1@localhost ``` -## Create a read-only view of the parts of the filesystem that need to be backed up + You should be able to login without a password. -1. Install `bindfs`: +1. Try to copy something: - ```console - apt list bindfs - apt show bindfs - apt install bindfs ``` + mkdir -p /home/backup1/test1 + touch /home/backup1/test1/file1.txt + touch /home/backup1/test1/file2.txt + ls -al /home/backup1/test1 -2. Create mount directories: + rsync -a -e "ssh -p 22 -i key1" backup1@localhost:~/test1 . - ```console - mkdir -p /home/apps_backup/opt-scripts - mkdir -p /home/apps_backup/var-ds + ls -al test1 ``` -3. Add these lines to `/etc/fstab` for mounting directories read-only: +1. Let's find out the command that the client is sending to the server through SSH. + Let's try the same rsync command again, with the added SSH switch `-v` (verbose): - ```console - /opt/docker-scripts /home/apps_backup/opt-scripts fuse.bindfs perms=0000:u=rD,force-user=apps_backup,force-group=nogroup 0 0 - /var/ds /home/apps_backup/var-ds fuse.bindfs perms=0000:u=rD,force-user=apps_backup,force-group=nogroup 0 0 + ``` + rsync -a -e "ssh -p 22 -i key1 -v" backup1@localhost:~/test1 . ``` -4. Mount them: + Then let's look for the debug line that says "Sending command": - ```console - mount -a - ls -al /home/apps_backup/opt-scripts - ls -al /home/apps_backup/var-ds + ``` + rsync -a -e "ssh -p 22 -i key1 -v" backup1@localhost:~/test1 . 2>&1 | grep "Sending command" ``` -5. Test that they are read-only: + It should be something like this: - ```console - sudo -u apps_backup ls -al /home/apps_backup/var-ds - sudo -u apps_backup touch /home/apps_backup/var-ds/test1.txt ``` + rsync --server --sender -logDtpre.iLsfxC . ~/test1 + ``` + +1. We can restrict the SSH key `key1` to execute only this command and nothing else. + For this we need to add something like this before the public key on `/home/backup1/.ssh/authorized_keys`: + + ``` + command="rsync --server --sender -logDtpre.iLsfxC . ~/test1" ecdsa-sha2-nistp256 AAAAE2Vj.... + ``` + + To make it even more secure, we can also add the options `no-agent-forwarding,no-port-forwarding,no-pty,no-user-rc,no-X11-forwarding`. The file `/home/backup1/.ssh/authorized_keys` now should look like this: + + ``` + command="rsync --server --sender -logDtpre.iLsfxC . ~/test1",no-agent-forwarding,no-port-forwarding,no-pty,no-user-rc,no-X11-forwarding ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBMbMdR9uW4SMeinpVvr6UQZaFybkiVZxm2DRYxFlCuxHchpTMGR7U4gZGZwY4D5LQDDy1Py4TWSsEizda4LecgQ= root@server + ``` + +1. Let's check that now we cannot login with `key1` anymore, but we can still use it to `rsync`: + + ``` + ssh -p 22 -i key1 backup1@localhost # should fail + + rm -rf test1 + rsync -a -e "ssh -p 22 -i key1" backup1@localhost:~/test1 . + ls -l test1 + + rm -rf test1 + rsync -a -e "ssh -p 22 -i key1" backup1@localhost: . + ls -l test1 + ``` + +1. For convenience, we can combine the command and the key in a bash script that looks like this: + + ``` + #!/bin/bash + + server=127.0.0.1 + port=22 + + rsync -a -e "ssh -p $port -i $0" backup1@${server}: . + + exit 0 + + -----BEGIN EC PRIVATE KEY----- + MHcCAQEEIGHMv+mlPZg/V6TmLADsfZcpMRcfxykJGzXAF65tuQ4AoAoGCCqGSM49 + AwEHoUQDQgAExsx1H25bhIx6KelW+vpRBloXJuSJVnGbYNFjEWUK7EdyGlMwZHtT + iBkZnBjgPktAMPLU/LhNZKwSLN1rgt5yBA== + -----END EC PRIVATE KEY----- + ``` + + Let's try it: + + ``` + chmod 700 backup1.sh + rm -rf test1/ + ./backup1.sh + ls -l test1/ + ``` + +1. Now we can move this script to the client (backup server), making sure to change + the variable `server` with the IP of the server, and it should work. -# References +1. To change the directory on the server that is being backed up, we should change it + on `/home/backup1/.ssh/authorized_keys` (for example from `~/test1` to `/var/backup`, + or anything else where the user `backup1` has read access). -- http://jorgenmodin.net/index_html/how-to-create-a-read-only-view-of-files-to-back-up-with-e.g.-rsync \ No newline at end of file +1. To backup a second directory we can create a second SSH key, append it to + `/home/backup1/.ssh/authorized_keys`, and create a second backup script. \ No newline at end of file