| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281 | .. include:: ../global.rst.inc.. highlight:: noneBacking up in pull mode=======================Assuming you have a pull backup system set up with borg, where a backup serverpulls the data from the target via SSHFS. In this mode, the backup client's filesystem is mounted remotely on the backup server. Pull mode is even possible ifthe SSH connection must be established by the client via a remote tunnel. Othernetwork file systems like NFS or SMB could be used as well, but SSHFS is verysimple to set up and probably the most secure one.There are some restrictions caused by SSHFS. For example, unless you define UIDand GID mappings when mounting via ``sshfs``, owners and groups of the mountedfile system will probably change, and you may not have access to those files ifBorgBackup is not run with root privileges.SSHFS is a FUSE file system and uses the SFTP protocol, so there may be alsoother unsupported features that the actual implementations of ssfs, libfuse andsftp on the backup server do not support, like file name encodings, ACLs, xattrsor bsdflags. So there is no guarantee that you are able to restore a systemcompletely in every aspect from such a backup... warning::    To mount the client's root file system you will need root access to the    client. This contradicts to the usual threat model of BorgBackup, where    clients don't need to trust the backup server (data is encrypted). In pull    mode the server (when logged in as root) could cause unlimited damage to the    client. Therefore, pull mode should be used only from servers you do fully    trust!Creating a backup-----------------Generally, in a pull backup situation there is no direct way for borg to knowthe client's original UID:GID name mapping of files, because Borg would use``/etc/passwd`` and ``/etc/group`` of the backup server to map the names. Toderive the right names, Borg needs to have access to the client's passwd andgroup files and use them in the backup process.The solution to this problem is chrooting into an sshfs mounted directory. Inthis example the whole client root file system is mounted. We use thestand-alone BorgBackup executable and copy it into the mounted file system tomake Borg available after entering chroot; this can be skipped if Borg isalready installed on the client.::    # Mount client root file system.    mkdir /tmp/sshfs    sshfs root@host:/ /tmp/sshfs    # Mount BorgBackup repository inside it.    mkdir /tmp/sshfs/borgrepo    mount --bind /path/to/repo /tmp/sshfs/borgrepo    # Make borg executable available.    cp /usr/local/bin/borg /tmp/sshfs/usr/local/bin/borg    # Mount important system directories and enter chroot.    cd /tmp/sshfs    for i in dev proc sys; do mount --bind /$i $i; done    chroot /tmp/sshfsNow we are on the backup system but inside a chroot with the client's root filesystem. We have a copy of Borg binary in ``/usr/local/bin`` and the repositoryin ``/borgrepo``. Borg will back up the client's user/group names, and we cancreate the backup, retaining the original paths, excluding the repository:::    borg create --exclude /borgrepo --files-cache ctime,size /borgrepo::archive /For the sake of simplicity only ``/borgrepo`` is excluded here. You may want toset up an exclude file with additional files and folders to be excluded. Alsonote that we have to modify Borg's file change detection behaviour – SSHFScannot guarantee stable inode numbers, so we have to supply the``--files-cache`` option.Finally, we need to exit chroot, unmount all the stuff and clean up:::    exit # exit chroot    rm /tmp/sshfs/usr/local/bin/borg    cd /tmp/sshfs    for i in dev proc sys borgrepo; do umount ./$i; done    rmdir borgrepo    cd ~    umount /tmp/sshfs    rmdir /tmp/sshfsThanks to secuser on IRC for this how-to!Restore methods---------------The counterpart of a pull backup is a push restore. Depending on the type ofrestore – full restore or partial restore – there are different methods to makesure the correct IDs are restored.Partial restore~~~~~~~~~~~~~~~In case of a partial restore, using the archived UIDs/GIDs might lead to wrongresults if the name-to-ID mapping on the target system has changed compared tobackup time (might be the case e.g. for a fresh OS install).The workaround again is chrooting into an sshfs mounted directory, so Borg isable to map the user/group names of the backup files to the actual IDs on theclient. This example is similar to the backup above – only the Borg command isdifferent:::    # Mount client root file system.    mkdir /tmp/sshfs    sshfs root@host:/ /tmp/sshfs    # Mount BorgBackup repository inside it.    mkdir /tmp/sshfs/borgrepo    mount --bind /path/to/repo /tmp/sshfs/borgrepo    # Make borg executable available.    cp /usr/local/bin/borg /tmp/sshfs/usr/local/bin/borg    # Mount important system directories and enter chroot.    cd /tmp/sshfs    for i in dev proc sys; do mount --bind /$i $i; done    chroot /tmp/sshfsNow we can run::    borg extract /borgrepo::archive PATHto partially restore whatever we like. Finally, do the clean-up:::    exit # exit chroot    rm /tmp/sshfs/usr/local/bin/borg    cd /tmp/sshfs    for i in dev proc sys borgrepo; do umount ./$i; done    rmdir borgrepo    cd ~    umount /tmp/sshfs    rmdir /tmp/sshfsFull restore~~~~~~~~~~~~When doing a full restore, we restore all files (including the ones containingthe ID-to-name mapping, ``/etc/passwd`` and ``/etc/group``). Everything will beconsistent automatically if we restore the numeric IDs stored in the archive. Sothere is no need for a chroot environment; we just mount the client file systemand extract a backup, utilizing the ``--numeric-owner`` option:::    sshfs root@host:/ /mnt/sshfs    cd /mnt/sshfs    borg extract --numeric-owner /path/to/repo::archive    cd ~    umount /mnt/sshfsSimple (lossy) full restore~~~~~~~~~~~~~~~~~~~~~~~~~~~Using ``borg export-tar`` it is possible to stream a backup to the client anddirectly extract it without the need of mounting with SSHFS:::    borg export-tar /path/to/repo::archive - | ssh root@host 'tar -C / -x'Note that in this scenario the tar format is the limiting factor – it cannotrestore all the advanced features that BorgBackup supports. See:ref:`borg_export-tar` for limitations.ssh-agent=========In this scenario *borg-server* initiates an SSH connection to *borg-client* and forwards the authenticationagent connection.After that, it works similar to the push mode:*borg-client* initiates another SSH connection back to *borg-server* using the forwarded authentication agentconnection to authenticate itself, starts ``borg serve`` and communicates with it.Using this method requires ssh access of user *borgs* to *borgc@borg-client*, where:* *borgs* is the user on the server side with read/write access to local borg repository.* *borgc* is the user on the client side with read access to files meant to be backed up.Applying this method for automated backup operations----------------------------------------------------Assume that the borg-client host is untrusted.Therefore we do some effort to prevent a hostile user on the borg-client side to do something harmful.In case of a fully trusted borg-client the method could be simplified.Preparing the server side~~~~~~~~~~~~~~~~~~~~~~~~~Do this once for each client on *borg-server* to allow *borgs* to connect itself on *borg-server* using adedicated ssh key:::  borgs@borg-server$ install -m 700 -d ~/.ssh/  borgs@borg-server$ ssh-keygen -N '' -t rsa  -f ~/.ssh/borg-client_key  borgs@borg-server$ { echo -n 'command="borg serve --append-only --restrict-to-repo ~/repo",restrict '; cat ~/.ssh/borg-client_key.pub; } >> ~/.ssh/authorized_keys  borgs@borg-server$ chmod 600 ~/.ssh/authorized_keys``install -m 700 -d ~/.ssh/``  Create directory ~/.ssh with correct permissions if it does not exist yet.``ssh-keygen -N '' -t rsa  -f ~/.ssh/borg-client_key``  Create an ssh key dedicated to communication with borg-client... note::  Another more complex approach is using a unique ssh key for each pull operation.  This is more secure as it guarantees that the key will not be used for other purposes.``{ echo -n 'command="borg serve --append-only --restrict-to-repo ~/repo",restrict '; cat ~/.ssh/borg-client_key.pub; } >> ~/.ssh/authorized_keys``  Add borg-client's ssh public key to ~/.ssh/authorized_keys with forced command and restricted mode.  The borg client is restricted to use one repo at the specified path and to append-only operation.  Commands like *delete*, *prune* and *compact* have to be executed another way, for example directly on *borg-server*  side or from a privileged, less restricted client (using another authorized_keys entry).``chmod 600 ~/.ssh/authorized_keys``  Fix permissions of ~/.ssh/authorized_keys.Pull operation~~~~~~~~~~~~~~Initiating borg command execution from *borg-server* (e.g. init)::  borgs@borg-server$ (    eval $(ssh-agent) > /dev/null    ssh-add -q ~/.ssh/borg-client_key    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"    kill "${SSH_AGENT_PID}"  )Parentheses around commands are needed to avoid interference with a possibly already running ssh-agent.Parentheses are not needed when using a dedicated bash process.``eval $(ssh-agent) > /dev/null``  Run the SSH agent in the background and export related environment variables to the current bash session.``ssh-add -q ~/.ssh/borg-client_key``  Load the SSH private key dedicated to communication with the borg-client into the SSH agent.  Look at ``man 1 ssh-add`` for a more detailed explanation... note::  Care needs to be taken when loading keys into the SSH agent. Users on the *borg-client* having read/write permissions  to the agent's UNIX-domain socket (at least borgc and root in our case) can access the agent on *borg-server* through  the forwarded connection and can authenticate using any of the identities loaded into the agent  (look at ``man 1 ssh`` for more detailed explanation). Therefore there are some security considerations:  * Private keys loaded into the agent must not be used to enable access anywhere else.  * The keys meant to be loaded into the agent must be specified explicitly, not from default locations.  * The *borg-client*'s entry in *borgs@borg-server:~/.ssh/authorized_keys* must be as restrictive as possible.``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"``  Run the *borg init* command on *borg-client*.  *ssh://borgs@borg-server/~/repo* refers to the repository *repo* within borgs's home directory on *borg-server*.  *StrictHostKeyChecking=no* is used to automatically add host keys to *~/.ssh/known_hosts* without user intervention.``kill "${SSH_AGENT_PID}"``  Kill ssh-agent with loaded keys when it is not needed anymore.
 |