|
@@ -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 |
|
|
|
|
|
|
|
|
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. |