Managing projects
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

server-backup-with-rsync.md 5.5 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. # Server Backup With Rsync
  2. First of all make sure that rsync is installed on the server: `apt install rsync`
  3. ## 1. Create a backup user with ssh-key access
  4. 1. Create a backup user, for example `backup1` (in ubuntu there is already a user named `backup`):
  5. ```
  6. useradd backup1 -m
  7. ls -al /home/backup1/
  8. ```
  9. 1. Create a ssh key-pair for this user:
  10. ```
  11. ssh-keygen -t ecdsa -P '' -q -f key1
  12. ls -l key1*
  13. cat key1
  14. cat key1.pub
  15. ```
  16. 1. Add the public key to `/home/backup1/.ssh/authorized_keys`:
  17. ```
  18. mkdir -p /home/backup1/.ssh
  19. chown backup1: /home/backup1/.ssh
  20. chmod 700 /home/backup1/.ssh
  21. cat key1.pub >> /home/backup1/.ssh/authorized_keys
  22. chown backup1: /home/backup1/.ssh/authorized_keys
  23. chmod 600 /home/backup1/.ssh/authorized_keys
  24. ls -al /home/backup1/.ssh/
  25. cat /home/backup1/.ssh/authorized_keys
  26. ```
  27. 1. Try to login with this key:
  28. ```
  29. ssh -p 22 -i key1 backup1@localhost
  30. ```
  31. You should be able to login without a password.
  32. 1. Try to copy something:
  33. ```
  34. mkdir -p /home/backup1/test1
  35. touch /home/backup1/test1/file1.txt
  36. touch /home/backup1/test1/file2.txt
  37. ls -al /home/backup1/test1
  38. rsync -a -e "ssh -p 22 -i key1" backup1@localhost:~/test1 .
  39. ls -al test1
  40. ```
  41. ## 2. Restrict the ssh key of the backup user for using only rsync
  42. 1. Let's find out the command that the client is sending to the server through SSH.
  43. Let's try the same rsync command again, with the added SSH switch `-v` (verbose):
  44. ```
  45. rsync -a -e "ssh -p 22 -i key1 -v" backup1@localhost:~/test1 .
  46. ```
  47. Then let's look for the debug line that says "Sending command":
  48. ```
  49. rsync -a -e "ssh -p 22 -i key1 -v" backup1@localhost:~/test1 . 2>&1 | grep "Sending command"
  50. ```
  51. It should be something like this:
  52. ```
  53. rsync --server --sender -logDtpre.iLsfxC . ~/test1
  54. ```
  55. 1. We can restrict the SSH key `key1` to execute only this command and nothing else.
  56. For this we need to add something like this before the public key on `/home/backup1/.ssh/authorized_keys`:
  57. ```
  58. command="rsync --server --sender -logDtpre.iLsfxC . ~/test1" ecdsa-sha2-nistp256 AAAAE2Vj....
  59. ```
  60. 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:
  61. ```
  62. 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
  63. ```
  64. 1. Let's check that now we cannot login with `key1` anymore, but we can still use it to `rsync`:
  65. ```
  66. ssh -p 22 -i key1 backup1@localhost # should fail
  67. rm -rf test1
  68. rsync -a -e "ssh -p 22 -i key1" backup1@localhost:~/test1 .
  69. ls -l test1
  70. rm -rf test1
  71. rsync -a -e "ssh -p 22 -i key1" backup1@localhost: .
  72. ls -l test1
  73. ```
  74. ## 3. Create a read-only view of the parts of the filesystem that need to be backed up
  75. 1. Install `bindfs`:
  76. ```
  77. apt list bindfs
  78. apt show bindfs
  79. apt install bindfs
  80. ```
  81. 2. Create mount directories:
  82. ```
  83. mkdir -p /mnt/backup-server/scripts
  84. mkdir -p /mnt/backup-server/apps
  85. ```
  86. 3. Add these lines to `/etc/fstab` for mounting directories read-only:
  87. ```console
  88. /opt/docker-scripts /mnt/backup-server/scripts fuse.bindfs perms=0000:u=rD,force-user=backup1,force-group=nogroup 0 0
  89. /var/ds /mnt/backup-server/apps fuse.bindfs perms=0000:u=rD,force-user=backup1,force-group=nogroup 0 0
  90. ```
  91. Since we are using **docker-scripts** for installing and managing apps, these two directories
  92. are what we need to backup: `/opt/docker-scripts` and `/var/ds`.
  93. 4. Mount them:
  94. ```console
  95. mount -a
  96. ls -al /mnt/backup-server/scripts
  97. ls -al /mnt/backup-server/apps
  98. ```
  99. 5. Test that they are read-only:
  100. ```console
  101. sudo -u backup1 ls -al /mnt/backup-server/scripts
  102. sudo -u backup1 touch /mnt/backup-server/scripts/test1.txt
  103. ```
  104. ## 4. Create and use a backup script
  105. 1. For convenience, we can combine the command and the key in a bash script named `backup-server.sh`
  106. that looks like this:
  107. ```
  108. #!/bin/bash
  109. server=127.0.0.1
  110. port=22
  111. cd $(dirname $0)
  112. rsync -a -e "ssh -p $port -i $0" backup1@${server}: .
  113. exit 0
  114. -----BEGIN EC PRIVATE KEY-----
  115. MHcCAQEEIGHMv+mlPZg/V6TmLADsfZcpMRcfxykJGzXAF65tuQ4AoAoGCCqGSM49
  116. AwEHoUQDQgAExsx1H25bhIx6KelW+vpRBloXJuSJVnGbYNFjEWUK7EdyGlMwZHtT
  117. iBkZnBjgPktAMPLU/LhNZKwSLN1rgt5yBA==
  118. -----END EC PRIVATE KEY-----
  119. ```
  120. Let's try it:
  121. ```
  122. chmod 700 backup-server.sh
  123. rm -rf test1/
  124. ./backup-server.sh
  125. ls -l test1/
  126. ```
  127. 1. Now we can move this script to the client (backup server), making sure to set
  128. the proper values for the variables `server` and `port`, and it should work.
  129. 1. Let's also fix the directory on the server that is being backed up. We should edit
  130. `/home/backup1/.ssh/authorized_keys` and change `~/test1` to `/mnt/backup-server`
  131. 1. On the client (computer that is receiving the backup), let's place the script `backup-server.sh`
  132. on a directory like `/var/backup`:
  133. ```
  134. mkdir -p /var/backup
  135. mv backup-server.sh /var/backup/
  136. cd /var/backup/
  137. ./backup-server.sh
  138. ```
  139. 1. Let's also create a cron job that runs this script periodically each week:
  140. ```
  141. cat <<EOF > /etc/cron.d/backup-server
  142. # backup the server each tuesday
  143. 0 0 * * TUE root /var/backup/backup-server.sh
  144. EOF
  145. ```