diff options
Diffstat (limited to 'docs/deployment/central-backup-server.rst')
-rw-r--r-- | docs/deployment/central-backup-server.rst | 221 |
1 files changed, 221 insertions, 0 deletions
diff --git a/docs/deployment/central-backup-server.rst b/docs/deployment/central-backup-server.rst new file mode 100644 index 000000000..26e718985 --- /dev/null +++ b/docs/deployment/central-backup-server.rst @@ -0,0 +1,221 @@ +.. include:: ../global.rst.inc +.. highlight:: none + +Central repository server with Ansible or Salt +============================================== + +This section will give an example how to setup a borg repository server for multiple +clients. + +Machines +-------- + +There are multiple machines used in this section and will further be named by their +respective fully qualified domain name (fqdn). + +* The backup server: `backup01.srv.local` +* The clients: + + - John Doe's desktop: `johndoe.clnt.local` + - Webserver 01: `web01.srv.local` + - Application server 01: `app01.srv.local` + +User and group +-------------- + +The repository server needs to have only one UNIX user for all the clients. +Recommended user and group with additional settings: + +* User: `backup` +* Group: `backup` +* Shell: `/bin/bash` (or other capable to run the `borg serve` command) +* Home: `/home/backup` + +Most clients shall initiate a backup from the root user to catch all +users, groups and permissions (e.g. when backing up `/home`). + +Folders +------- + +The following folder tree layout is suggested on the repository server: + +* User home directory, /home/backup +* Repositories path (storage pool): /home/backup/repos +* Clients restricted paths (`/home/backup/repos/<client fqdn>`): + + - johndoe.clnt.local: `/home/backup/repos/johndoe.clnt.local` + - web01.srv.local: `/home/backup/repos/web01.srv.local` + - app01.srv.local: `/home/backup/repos/app01.srv.local` + +Restrictions +------------ + +Borg is instructed to restrict clients into their own paths: +``borg serve --restrict-to-path /home/backup/repos/<client fqdn>`` + +The client will be able to access any file or subdirectory inside of ``/home/backup/repos/<client fqdn>`` +but no other directories. You can allow a client to access several separate directories by passing multiple +``--restrict-to-path`` flags, for instance: ``borg serve --restrict-to-path /home/backup/repos/<client fqdn> --restrict-to-path /home/backup/repos/<other client fqdn>``, +which could make sense if multiple machines belong to one person which should then have access to all the +backups of their machines. + +There is only one ssh key per client allowed. Keys are added for ``johndoe.clnt.local``, ``web01.srv.local`` and +``app01.srv.local``. But they will access the backup under only one UNIX user account as: +``backup@backup01.srv.local``. Every key in ``$HOME/.ssh/authorized_keys`` has a +forced command and restrictions applied as shown below: + +:: + + command="cd /home/backup/repos/<client fqdn>; + borg serve --restrict-to-path /home/backup/repos/<client fqdn>", + restrict <keytype> <key> <host> + +.. note:: The text shown above needs to be written on a single line! + +The options which are added to the key will perform the following: + +1. Change working directory +2. Run ``borg serve`` restricted to the client base path +3. Restrict ssh and do not allow stuff which imposes a security risk + +Due to the ``cd`` command we use, the server automatically changes the current +working directory. Then client doesn't need to have knowledge of the absolute +or relative remote repository path and can directly access the repositories at +``<user>@<host>:<repo>``. + +.. note:: The setup above ignores all client given commandline parameters + which are normally appended to the `borg serve` command. + +Client +------ + +The client needs to initialize the `pictures` repository like this: + + borg init backup@backup01.srv.local:pictures + +Or with the full path (should actually never be used, as only for demonstrational purposes). +The server should automatically change the current working directory to the `<client fqdn>` folder. + + borg init backup@backup01.srv.local:/home/backup/repos/johndoe.clnt.local/pictures + +When `johndoe.clnt.local` tries to access a not restricted path the following error is raised. +John Doe tries to backup into the Web 01 path: + + borg init backup@backup01.srv.local:/home/backup/repos/web01.srv.local/pictures + +:: + + ~~~ SNIP ~~~ + Remote: borg.remote.PathNotAllowed: /home/backup/repos/web01.srv.local/pictures + ~~~ SNIP ~~~ + Repository path not allowed + +Ansible +------- + +Ansible takes care of all the system-specific commands to add the user, create the +folder. Even when the configuration is changed the repository server configuration is +satisfied and reproducible. + +Automate setting up an repository server with the user, group, folders and +permissions a Ansible playbook could be used. Keep in mind the playbook +uses the Arch Linux `pacman <https://www.archlinux.org/pacman/pacman.8.html>`_ +package manager to install and keep borg up-to-date. + +:: + + - hosts: backup01.srv.local + vars: + user: backup + group: backup + home: /home/backup + pool: "{{ home }}/repos" + auth_users: + - host: johndoe.clnt.local + key: "{{ lookup('file', '/path/to/keys/johndoe.clnt.local.pub') }}" + - host: web01.clnt.local + key: "{{ lookup('file', '/path/to/keys/web01.clnt.local.pub') }}" + - host: app01.clnt.local + key: "{{ lookup('file', '/path/to/keys/app01.clnt.local.pub') }}" + tasks: + - pacman: name=borg state=latest update_cache=yes + - group: name="{{ group }}" state=present + - user: name="{{ user }}" shell=/bin/bash home="{{ home }}" createhome=yes group="{{ group }}" groups= state=present + - file: path="{{ home }}" owner="{{ user }}" group="{{ group }}" mode=0700 state=directory + - file: path="{{ home }}/.ssh" owner="{{ user }}" group="{{ group }}" mode=0700 state=directory + - file: path="{{ pool }}" owner="{{ user }}" group="{{ group }}" mode=0700 state=directory + - authorized_key: user="{{ user }}" + key="{{ item.key }}" + key_options='command="cd {{ pool }}/{{ item.host }};borg serve --restrict-to-path {{ pool }}/{{ item.host }}",restrict' + with_items: "{{ auth_users }}" + - file: path="{{ home }}/.ssh/authorized_keys" owner="{{ user }}" group="{{ group }}" mode=0600 state=file + - file: path="{{ pool }}/{{ item.host }}" owner="{{ user }}" group="{{ group }}" mode=0700 state=directory + with_items: "{{ auth_users }}" + +Salt +---- + +This is a configuration similar to the one above, configured to be deployed with +Salt running on a Debian system. + +:: + + Install borg backup from pip: + pkg.installed: + - pkgs: + - python3 + - python3-dev + - python3-pip + - python-virtualenv + - libssl-dev + - openssl + - libacl1-dev + - libacl1 + - liblz4-dev + - liblz4-1 + - build-essential + - libfuse-dev + - fuse + - pkg-config + pip.installed: + - pkgs: ["borgbackup"] + - bin_env: /usr/bin/pip3 + + Setup backup user: + user.present: + - name: backup + - fullname: Backup User + - home: /home/backup + - shell: /bin/bash + # CAUTION! + # If you change the ssh command= option below, it won't necessarily get pushed to the backup + # server correctly unless you delete the ~/.ssh/authorized_keys file and re-create it! + {% for host in backupclients %} + Give backup access to {{host}}: + ssh_auth.present: + - user: backup + - source: salt://conf/ssh-pubkeys/{{host}}-backup.id_ecdsa.pub + - options: + - command="cd /home/backup/repos/{{host}}; borg serve --restrict-to-path /home/backup/repos/{{host}}" + - restrict + {% endfor %} + + +Enhancements +------------ + +As this section only describes a simple and effective setup it could be further +enhanced when supporting (a limited set) of client supplied commands. A wrapper +for starting `borg serve` could be written. Or borg itself could be enhanced to +autodetect it runs under SSH by checking the `SSH_ORIGINAL_COMMAND` environment +variable. This is left open for future improvements. + +When extending ssh autodetection in borg no external wrapper script is necessary +and no other interpreter or application has to be deployed. + +See also +-------- + +* `SSH Daemon manpage <http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man8/sshd.8>`_ +* `Ansible <https://docs.ansible.com>`_ +* `Salt <https://docs.saltstack.com/>`_ |