pull-backup.rst 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504
  1. .. include:: ../global.rst.inc
  2. .. highlight:: none
  3. .. _pull_backup:
  4. =======================
  5. Backing up in pull mode
  6. =======================
  7. Typically the borg client connects to a backup server using SSH as a transport
  8. when initiating a backup. This is referred to as push mode.
  9. If you however require the backup server to initiate the connection or prefer
  10. it to initiate the backup run, one of the following workarounds is required to
  11. allow such a pull mode setup.
  12. A common use case for pull mode is to back up a remote server to a local personal
  13. computer.
  14. SSHFS
  15. =====
  16. Assuming you have a pull backup system set up with borg, where a backup server
  17. pulls the data from the target via SSHFS. In this mode, the backup client's file
  18. system is mounted remotely on the backup server. Pull mode is even possible if
  19. the SSH connection must be established by the client via a remote tunnel. Other
  20. network file systems like NFS or SMB could be used as well, but SSHFS is very
  21. simple to set up and probably the most secure one.
  22. There are some restrictions caused by SSHFS. For example, unless you define UID
  23. and GID mappings when mounting via ``sshfs``, owners and groups of the mounted
  24. file system will probably change, and you may not have access to those files if
  25. BorgBackup is not run with root privileges.
  26. SSHFS is a FUSE file system and uses the SFTP protocol, so there may be also
  27. other unsupported features that the actual implementations of sshfs, libfuse and
  28. sftp on the backup server do not support, like file name encodings, ACLs, xattrs
  29. or flags. So there is no guarantee that you are able to restore a system
  30. completely in every aspect from such a backup.
  31. .. warning::
  32. To mount the client's root file system you will need root access to the
  33. client. This contradicts to the usual threat model of BorgBackup, where
  34. clients don't need to trust the backup server (data is encrypted). In pull
  35. mode the server (when logged in as root) could cause unlimited damage to the
  36. client. Therefore, pull mode should be used only from servers you do fully
  37. trust!
  38. .. warning::
  39. Additionally, while being chrooted into the client's root file system,
  40. code from the client will be executed. Thus, you should only do that when
  41. fully trusting the client.
  42. .. warning::
  43. The chroot method was chosen to get the right user and group name-id
  44. mappings, assuming they only come from files (/etc/passwd and group).
  45. This assumption might be wrong, e.g. if users/groups also come from
  46. ldap or other providers.
  47. Thus, it might be better to use ``--numeric-ids`` and not archive any
  48. user or group names (but just the numeric IDs) and not use chroot.
  49. Creating a backup
  50. -----------------
  51. Generally, in a pull backup situation there is no direct way for borg to know
  52. the client's original UID:GID name mapping of files, because Borg would use
  53. ``/etc/passwd`` and ``/etc/group`` of the backup server to map the names. To
  54. derive the right names, Borg needs to have access to the client's passwd and
  55. group files and use them in the backup process.
  56. The solution to this problem is chrooting into an sshfs mounted directory. In
  57. this example the whole client root file system is mounted. We use the
  58. stand-alone BorgBackup executable and copy it into the mounted file system to
  59. make Borg available after entering chroot; this can be skipped if Borg is
  60. already installed on the client.
  61. ::
  62. # Mount client root file system.
  63. mkdir /tmp/sshfs
  64. sshfs root@host:/ /tmp/sshfs
  65. # Mount BorgBackup repository inside it.
  66. mkdir /tmp/sshfs/borgrepo
  67. mount --bind /path/to/repo /tmp/sshfs/borgrepo
  68. # Make borg executable available.
  69. cp /usr/local/bin/borg /tmp/sshfs/usr/local/bin/borg
  70. # Mount important system directories and enter chroot.
  71. cd /tmp/sshfs
  72. for i in dev proc sys; do mount --bind /$i $i; done
  73. chroot /tmp/sshfs
  74. Now we are on the backup system but inside a chroot with the client's root file
  75. system. We have a copy of Borg binary in ``/usr/local/bin`` and the repository
  76. in ``/borgrepo``. Borg will back up the client's user/group names, and we can
  77. create the backup, retaining the original paths, excluding the repository:
  78. ::
  79. borg create --exclude borgrepo --files-cache ctime,size /borgrepo::archive /
  80. For the sake of simplicity only ``borgrepo`` is excluded here. You may want to
  81. set up an exclude file with additional files and folders to be excluded. Also
  82. note that we have to modify Borg's file change detection behaviour – SSHFS
  83. cannot guarantee stable inode numbers, so we have to supply the
  84. ``--files-cache`` option.
  85. Finally, we need to exit chroot, unmount all the stuff and clean up:
  86. ::
  87. exit # exit chroot
  88. rm /tmp/sshfs/usr/local/bin/borg
  89. cd /tmp/sshfs
  90. for i in dev proc sys borgrepo; do umount ./$i; done
  91. rmdir borgrepo
  92. cd ~
  93. umount /tmp/sshfs
  94. rmdir /tmp/sshfs
  95. Thanks to secuser on IRC for this how-to!
  96. Restore methods
  97. ---------------
  98. The counterpart of a pull backup is a push restore. Depending on the type of
  99. restore – full restore or partial restore – there are different methods to make
  100. sure the correct IDs are restored.
  101. Partial restore
  102. ~~~~~~~~~~~~~~~
  103. In case of a partial restore, using the archived UIDs/GIDs might lead to wrong
  104. results if the name-to-ID mapping on the target system has changed compared to
  105. backup time (might be the case e.g. for a fresh OS install).
  106. The workaround again is chrooting into an sshfs mounted directory, so Borg is
  107. able to map the user/group names of the backup files to the actual IDs on the
  108. client. This example is similar to the backup above – only the Borg command is
  109. different:
  110. ::
  111. # Mount client root file system.
  112. mkdir /tmp/sshfs
  113. sshfs root@host:/ /tmp/sshfs
  114. # Mount BorgBackup repository inside it.
  115. mkdir /tmp/sshfs/borgrepo
  116. mount --bind /path/to/repo /tmp/sshfs/borgrepo
  117. # Make borg executable available.
  118. cp /usr/local/bin/borg /tmp/sshfs/usr/local/bin/borg
  119. # Mount important system directories and enter chroot.
  120. cd /tmp/sshfs
  121. for i in dev proc sys; do mount --bind /$i $i; done
  122. chroot /tmp/sshfs
  123. Now we can run
  124. ::
  125. borg extract /borgrepo::archive PATH
  126. to restore whatever we like partially. Finally, do the clean-up:
  127. ::
  128. exit # exit chroot
  129. rm /tmp/sshfs/usr/local/bin/borg
  130. cd /tmp/sshfs
  131. for i in dev proc sys borgrepo; do umount ./$i; done
  132. rmdir borgrepo
  133. cd ~
  134. umount /tmp/sshfs
  135. rmdir /tmp/sshfs
  136. Full restore
  137. ~~~~~~~~~~~~
  138. When doing a full restore, we restore all files (including the ones containing
  139. the ID-to-name mapping, ``/etc/passwd`` and ``/etc/group``). Everything will be
  140. consistent automatically if we restore the numeric IDs stored in the archive. So
  141. there is no need for a chroot environment; we just mount the client file system
  142. and extract a backup, utilizing the ``--numeric-ids`` option:
  143. ::
  144. sshfs root@host:/ /mnt/sshfs
  145. cd /mnt/sshfs
  146. borg extract --numeric-ids /path/to/repo::archive
  147. cd ~
  148. umount /mnt/sshfs
  149. Simple (lossy) full restore
  150. ~~~~~~~~~~~~~~~~~~~~~~~~~~~
  151. Using ``borg export-tar`` it is possible to stream a backup to the client and
  152. directly extract it without the need of mounting with SSHFS:
  153. ::
  154. borg export-tar /path/to/repo::archive - | ssh root@host 'tar -C / -x'
  155. Note that in this scenario the tar format is the limiting factor – it cannot
  156. restore all the advanced features that BorgBackup supports. See
  157. :ref:`borg_export-tar` for limitations.
  158. socat
  159. =====
  160. In this setup a SSH connection from the backup server to the client is
  161. established that uses SSH reverse port forwarding to tunnel data
  162. transparently between UNIX domain sockets on the client and server and the socat
  163. tool to connect these with the borg client and server processes, respectively.
  164. The program socat has to be available on the backup server and on the client
  165. to be backed up.
  166. When **pushing** a backup the borg client (holding the data to be backed up)
  167. connects to the backup server via ssh, starts ``borg serve`` on the backup
  168. server and communicates via standard input and output (transported via SSH)
  169. with the process on the backup server.
  170. With the help of socat this process can be reversed. The backup server will
  171. create a connection to the client (holding the data to be backed up) and will
  172. **pull** the data.
  173. In the following example *borg-server* connects to *borg-client* to pull a backup.
  174. To provide a secure setup sockets should be stored in ``/run/borg``, only
  175. accessible to the users that run the backup process. So on both systems,
  176. *borg-server* and *borg-client* the folder ``/run/borg`` has to be created::
  177. sudo mkdir -m 0700 /run/borg
  178. On *borg-server* the socket file is opened by the user running the ``borg
  179. serve`` process writing to the repository
  180. so the user has to have read and write permissions on ``/run/borg``::
  181. borg-server:~$ sudo chown borgs /run/borg
  182. On *borg-client* the socket file is created by ssh, so the user used to connect
  183. to *borg-client* has to have read and write permissions on ``/run/borg``::
  184. borg-client:~$ sudo chown borgc /run/borg
  185. On *borg-server*, we have to start the command ``borg serve`` and make its
  186. standard input and output available to a unix socket::
  187. borg-server:~$ socat UNIX-LISTEN:/run/borg/reponame.sock,fork EXEC:"borg serve --append-only --restrict-to-path /path/to/repo"
  188. Socat will wait until a connection is opened. Then socat will execute the
  189. command given, redirecting Standard Input and Output to the unix socket. The
  190. optional arguments for ``borg serve`` are not necessary but a sane default.
  191. .. note::
  192. When used in production you may also use systemd socket-based activation
  193. instead of socat on the server side. You would wrap the ``borg serve`` command
  194. in a `service unit`_ and configure a matching `socket unit`_
  195. to start the service whenever a client connects to the socket.
  196. .. _service unit: https://www.freedesktop.org/software/systemd/man/systemd.service.html
  197. .. _socket unit: https://www.freedesktop.org/software/systemd/man/systemd.socket.html
  198. Now we need a way to access the unix socket on *borg-client* (holding the
  199. data to be backed up), as we created the unix socket on *borg-server*
  200. Opening a SSH connection from the *borg-server* to the *borg-client* with reverse port
  201. forwarding can do this for us::
  202. borg-server:~$ ssh -R /run/borg/reponame.sock:/run/borg/reponame.sock borgc@borg-client
  203. .. note::
  204. As the default value of OpenSSH for ``StreamLocalBindUnlink`` is ``no``, the
  205. socket file created by sshd is not removed. Trying to connect a second time,
  206. will print a short warning, and the forwarding does **not** take place::
  207. Warning: remote port forwarding failed for listen path /run/borg/reponame.sock
  208. When you are done, you have to remove the socket file manually, otherwise
  209. you may see an error like this when trying to execute borg commands::
  210. Remote: YYYY/MM/DD HH:MM:SS socat[XXX] E connect(5, AF=1 "/run/borg/reponame.sock", 13): Connection refused
  211. Connection closed by remote host. Is borg working on the server?
  212. When a process opens the socket on *borg-client*, SSH will forward all
  213. data to the socket on *borg-server*.
  214. The next step is to tell borg on *borg-client* to use the unix socket to communicate with the
  215. ``borg serve`` command on *borg-server* via the socat socket instead of SSH::
  216. borg-client:~$ export BORG_RSH="sh -c 'exec socat STDIO UNIX-CONNECT:/run/borg/reponame.sock'"
  217. The default value for ``BORG_RSH`` is ``ssh``. By default Borg uses SSH to create
  218. the connection to the backup server. Therefore Borg parses the repo URL
  219. and adds the server name (and other arguments) to the SSH command. Those
  220. arguments can not be handled by socat. We wrap the command with ``sh`` to
  221. ignore all arguments intended for the SSH command.
  222. All Borg commands can now be executed on *borg-client*. For example to create a
  223. backup execute the ``borg create`` command::
  224. borg-client:~$ borg create ssh://borg-server/path/to/repo::archive /path_to_backup
  225. When automating backup creation, the
  226. interactive ssh session may seem inappropriate. An alternative way of creating
  227. a backup may be the following command::
  228. borg-server:~$ ssh \
  229. -R /run/borg/reponame.sock:/run/borg/reponame.sock \
  230. borgc@borg-client \
  231. borg create \
  232. --rsh "sh -c 'exec socat STDIO UNIX-CONNECT:/run/borg/reponame.sock'" \
  233. ssh://borg-server/path/to/repo::archive /path_to_backup \
  234. ';' rm /run/borg/reponame.sock
  235. This command also automatically removes the socket file after the ``borg
  236. create`` command is done.
  237. ssh-agent
  238. =========
  239. In this scenario *borg-server* initiates an SSH connection to *borg-client* and forwards the authentication
  240. agent connection.
  241. After that, it works similar to the push mode:
  242. *borg-client* initiates another SSH connection back to *borg-server* using the forwarded authentication agent
  243. connection to authenticate itself, starts ``borg serve`` and communicates with it.
  244. Using this method requires ssh access of user *borgs* to *borgc@borg-client*, where:
  245. * *borgs* is the user on the server side with read/write access to local borg repository.
  246. * *borgc* is the user on the client side with read access to files meant to be backed up.
  247. Applying this method for automated backup operations
  248. ----------------------------------------------------
  249. Assume that the borg-client host is untrusted.
  250. Therefore we do some effort to prevent a hostile user on the borg-client side to do something harmful.
  251. In case of a fully trusted borg-client the method could be simplified.
  252. Preparing the server side
  253. ~~~~~~~~~~~~~~~~~~~~~~~~~
  254. Do this once for each client on *borg-server* to allow *borgs* to connect itself on *borg-server* using a
  255. dedicated ssh key:
  256. ::
  257. borgs@borg-server$ install -m 700 -d ~/.ssh/
  258. borgs@borg-server$ ssh-keygen -N '' -t rsa -f ~/.ssh/borg-client_key
  259. borgs@borg-server$ { echo -n 'command="borg serve --append-only --restrict-to-repo ~/repo",restrict '; cat ~/.ssh/borg-client_key.pub; } >> ~/.ssh/authorized_keys
  260. borgs@borg-server$ chmod 600 ~/.ssh/authorized_keys
  261. ``install -m 700 -d ~/.ssh/``
  262. Create directory ~/.ssh with correct permissions if it does not exist yet.
  263. ``ssh-keygen -N '' -t rsa -f ~/.ssh/borg-client_key``
  264. Create an ssh key dedicated to communication with borg-client.
  265. .. note::
  266. Another more complex approach is using a unique ssh key for each pull operation.
  267. This is more secure as it guarantees that the key will not be used for other purposes.
  268. ``{ echo -n 'command="borg serve --append-only --restrict-to-repo ~/repo",restrict '; cat ~/.ssh/borg-client_key.pub; } >> ~/.ssh/authorized_keys``
  269. Add borg-client's ssh public key to ~/.ssh/authorized_keys with forced command and restricted mode.
  270. The borg client is restricted to use one repo at the specified path and to append-only operation.
  271. Commands like *delete*, *prune* and *compact* have to be executed another way, for example directly on *borg-server*
  272. side or from a privileged, less restricted client (using another authorized_keys entry).
  273. ``chmod 600 ~/.ssh/authorized_keys``
  274. Fix permissions of ~/.ssh/authorized_keys.
  275. Pull operation
  276. ~~~~~~~~~~~~~~
  277. Initiating borg command execution from *borg-server* (e.g. init)::
  278. borgs@borg-server$ (
  279. eval $(ssh-agent) > /dev/null
  280. ssh-add -q ~/.ssh/borg-client_key
  281. echo 'your secure borg key passphrase' | \
  282. ssh -A -o StrictHostKeyChecking=no borgc@borg-client "BORG_PASSPHRASE=\$(cat) borg --rsh 'ssh -o StrictHostKeyChecking=no' init --encryption repokey ssh://borgs@borg-server/~/repo"
  283. kill "${SSH_AGENT_PID}"
  284. )
  285. Parentheses around commands are needed to avoid interference with a possibly already running ssh-agent.
  286. Parentheses are not needed when using a dedicated bash process.
  287. ``eval $(ssh-agent) > /dev/null``
  288. Run the SSH agent in the background and export related environment variables to the current bash session.
  289. ``ssh-add -q ~/.ssh/borg-client_key``
  290. Load the SSH private key dedicated to communication with the borg-client into the SSH agent.
  291. Look at ``man 1 ssh-add`` for a more detailed explanation.
  292. .. note::
  293. Care needs to be taken when loading keys into the SSH agent. Users on the *borg-client* having read/write permissions
  294. to the agent's UNIX-domain socket (at least borgc and root in our case) can access the agent on *borg-server* through
  295. the forwarded connection and can authenticate using any of the identities loaded into the agent
  296. (look at ``man 1 ssh`` for more detailed explanation). Therefore there are some security considerations:
  297. * Private keys loaded into the agent must not be used to enable access anywhere else.
  298. * The keys meant to be loaded into the agent must be specified explicitly, not from default locations.
  299. * The *borg-client*'s entry in *borgs@borg-server:~/.ssh/authorized_keys* must be as restrictive as possible.
  300. ``echo 'your secure borg key passphrase' | ssh -A -o StrictHostKeyChecking=no borgc@borg-client "BORG_PASSPHRASE=\$(cat) borg --rsh 'ssh -o StrictHostKeyChecking=no' init --encryption repokey ssh://borgs@borg-server/~/repo"``
  301. Run the *borg init* command on *borg-client*.
  302. *ssh://borgs@borg-server/~/repo* refers to the repository *repo* within borgs's home directory on *borg-server*.
  303. *StrictHostKeyChecking=no* is used to add host keys automatically to *~/.ssh/known_hosts* without user intervention.
  304. ``kill "${SSH_AGENT_PID}"``
  305. Kill ssh-agent with loaded keys when it is not needed anymore.
  306. Remote forwarding
  307. =================
  308. The standard ssh client allows to create tunnels to forward local ports to a remote server (local forwarding) and also
  309. to allow remote ports to be forwarded to local ports (remote forwarding).
  310. This remote forwarding can be used to allow remote backup clients to access the backup server even if the backup server
  311. cannot be reached by the backup client.
  312. This can even be used in cases where neither the backup server can reach the backup client and the backup client cannot
  313. reach the backup server, but some intermediate host can access both.
  314. A schematic approach is as follows
  315. ::
  316. Backup Server (backup@mybackup) Intermediate Machine (john@myinter) Backup Client (bob@myclient)
  317. 1. Establish SSH remote forwarding -----------> SSH listen on local port
  318. 2. Starting ``borg create`` establishes
  319. 3. SSH forwards to intermediate machine <------- SSH connection to the local port
  320. 4. Receives backup connection <------- and further on to backup server
  321. via SSH
  322. So for the backup client the backup is done via SSH to a local port and for the backup server there is a normal backup
  323. performed via ssh.
  324. In order to achieve this, the following commands can be used to create the remote port forwarding:
  325. 1. On machine ``myinter``
  326. ``ssh bob@myclient -v -C -R 8022:mybackup:22 -N``
  327. This will listen for ssh-connections on port ``8022`` on ``myclient`` and forward connections to port 22 on ``mybackup``.
  328. You can also remove the need for machine ``myinter`` and create the port forwarding on the backup server directly by
  329. using ``localhost`` instead of ``mybackup``
  330. 2. On machine ``myclient``
  331. ``borg create -v --progress --stats ssh://backup@localhost:8022/home/backup/repos/myclient /``
  332. Make sure to use port ``8022`` and ``localhost`` for the repository as this instructs borg on ``myclient`` to use the
  333. remote forwarded ssh connection.
  334. SSH Keys
  335. --------
  336. If you want to automate backups when using this method, the ssh ``known_hosts`` and ``authorized_keys`` need to be set up
  337. to allow connections.
  338. Security Considerations
  339. -----------------------
  340. Opening up SSH access this way can pose a security risk as it effectively opens remote access to your
  341. backup server on the client even if it is located outside of your company network.
  342. To reduce the chances of compromise, you should configure a forced command in ``authorized_keys`` to prevent
  343. anyone from performing any other action on the backup server.
  344. This can be done e.g. by adding the following in ``$HOME/.ssh/authorized_keys`` on ``mybackup`` with proper
  345. path and client-fqdn:
  346. ::
  347. command="cd /home/backup/repos/<client fqdn>;borg serve --restrict-to-path /home/backup/repos/<client fqdn>"
  348. All the additional security considerations for borg should be applied, see :ref:`central-backup-server` for some additional
  349. hints.
  350. More information
  351. ----------------
  352. See `remote forwarding`_ and the `ssh man page`_ for more information about remote forwarding.
  353. .. _remote forwarding: https://linuxize.com/post/how-to-setup-ssh-tunneling/
  354. .. _ssh man page: https://manpages.debian.org/testing/manpages-de/ssh.1.de.html