From 7f3f811afb74bcdd745f2e4ef3c7c71934b453b4 Mon Sep 17 00:00:00 2001 From: HgO Date: Sun, 29 Nov 2020 13:04:38 +0100 Subject: [PATCH] allow access to backups through sftp in ro mode --- inventories/group_vars/all/main.yml | 4 -- .../mastodon.pirateparty.be/main.yml | 3 +- .../host_vars/wiki.pirateparty.be/main.yml | 3 +- playbooks/files/ssh/backup-sync/batato.pub | 1 + roles/common/defaults/main.yml | 12 +++--- .../default/files/ssh/backup-sync/ppbe.pub | 1 + .../molecule/default/group_vars/all.yml | 17 ++++++++ roles/common/tasks/backup.yml | 43 ++++++++----------- roles/common/tasks/backup_borg.yml | 10 ++--- roles/common/tasks/backup_storage_box.yml | 14 ++++++ roles/common/tasks/openssh.yml | 2 +- roles/common/templates/openssh/sshd_config.j2 | 8 +++- 12 files changed, 75 insertions(+), 43 deletions(-) create mode 100644 playbooks/files/ssh/backup-sync/batato.pub create mode 100644 roles/common/molecule/default/files/ssh/backup-sync/ppbe.pub create mode 100644 roles/common/molecule/default/group_vars/all.yml diff --git a/inventories/group_vars/all/main.yml b/inventories/group_vars/all/main.yml index 251ea7a..b15f421 100644 --- a/inventories/group_vars/all/main.yml +++ b/inventories/group_vars/all/main.yml @@ -19,13 +19,9 @@ storage_box_host: storage.pirateparty.be storage_box_username: "{{ vault_storage_box_username }}" storage_box_password: "{{ vault_storage_box_password }}" -borg_passphrase: "{{ vault_borg_passphrase }}" - # Add SSH keys in playbooks/files/ssh// users: - name: hgo - name: tierce -- name: backup - groups: [] acme_email: it@pirateparty.be \ No newline at end of file diff --git a/inventories/host_vars/mastodon.pirateparty.be/main.yml b/inventories/host_vars/mastodon.pirateparty.be/main.yml index c56fc8c..52bfd48 100644 --- a/inventories/host_vars/mastodon.pirateparty.be/main.yml +++ b/inventories/host_vars/mastodon.pirateparty.be/main.yml @@ -11,7 +11,8 @@ borgmatic_config: - "{{ mastodon_home }}/elasticsearch" - "{{ mastodon_home }}/redis" storage: - encryption_passphrase: "{{ borg_passphrase }}" + umask: "{{ borg_umask }}" + encryption_passphrase: "{{ vault_borg_passphrase }}" compression: zlib,7 retention: keep_hourly: 24 diff --git a/inventories/host_vars/wiki.pirateparty.be/main.yml b/inventories/host_vars/wiki.pirateparty.be/main.yml index 7e8dd77..5c1cbdd 100644 --- a/inventories/host_vars/wiki.pirateparty.be/main.yml +++ b/inventories/host_vars/wiki.pirateparty.be/main.yml @@ -6,7 +6,8 @@ borgmatic_config: repositories: - "{{ borg_repository }}" storage: - encryption_passphrase: "{{ borg_passphrase }}" + umask: "{{ borg_umask }}" + encryption_passphrase: "{{ vault_borg_passphrase }}" compression: zlib,7 retention: keep_hourly: 24 diff --git a/playbooks/files/ssh/backup-sync/batato.pub b/playbooks/files/ssh/backup-sync/batato.pub new file mode 100644 index 0000000..584f6d9 --- /dev/null +++ b/playbooks/files/ssh/backup-sync/batato.pub @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIcLrF84oKOGw5zahiEbmugh5BYhsnFwJSEX+EAVZcwj root@batato.be \ No newline at end of file diff --git a/roles/common/defaults/main.yml b/roles/common/defaults/main.yml index 02ff7ef..8675b3f 100644 --- a/roles/common/defaults/main.yml +++ b/roles/common/defaults/main.yml @@ -18,15 +18,16 @@ user_default_groups: openssh_port: "22" -backup_owner: backup +backup_owner: backup-sync backup_group: "{{ backup_owner }}" +backup_chroot_dir: /mnt/backup storage_box_enabled: no storage_box_host: storage.example.com storage_box_port: 23 storage_box_path: /home/backup storage_box_mount: - path: "/mnt/backup" + path: "{{ backup_chroot_dir }}" owner: "{{ backup_owner }}" group: "{{ backup_group }}" options: [rw,default_permissions] @@ -34,14 +35,14 @@ storage_box_username: u123456-sub1 storage_box_password: somesecret borg_encryption_mode: keyfile -borg_passphrase: "{{ vault_borg_passphrase }}" borg_repository: |- {%- if storage_box_enabled -%} {{ storage_box_host }}:{{ storage_box_path }}/borg {%- else -%} - {{ storage_box_mount.path }}/borg + {{ backup_chroot_dir }}/borg {%- endif -%} +borgmatic_config_dir: /etc/borgmatic borgmatic_config: location: source_directories: @@ -69,7 +70,8 @@ borgmatic_config: - /var/snap exclude_caches: true storage: - encryption_passphrase: "{{ borg_passphrase }}" + umask: "{{ borg_umask }}" + encryption_passphrase: "{{ vault_borg_passphrase }}" compression: zlib,7 retention: keep_hourly: 24 diff --git a/roles/common/molecule/default/files/ssh/backup-sync/ppbe.pub b/roles/common/molecule/default/files/ssh/backup-sync/ppbe.pub new file mode 100644 index 0000000..2edc0eb --- /dev/null +++ b/roles/common/molecule/default/files/ssh/backup-sync/ppbe.pub @@ -0,0 +1 @@ +ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIM210TheGfg4/YnQxbopJ41Q2ADv3uPViWtv8+4MoAAy ppbe@vagrant \ No newline at end of file diff --git a/roles/common/molecule/default/group_vars/all.yml b/roles/common/molecule/default/group_vars/all.yml new file mode 100644 index 0000000..83ca34b --- /dev/null +++ b/roles/common/molecule/default/group_vars/all.yml @@ -0,0 +1,17 @@ +borgmatic_config: + location: + source_directories: + - /home + - /root + repositories: + - "{{ borg_repository }}" + exclude_caches: true + storage: + umask: "{{ borg_umask }}" + encryption_passphrase: "{{ vault_borg_passphrase }}" + compression: zlib,7 + retention: + keep_hourly: 24 + keep_daily: 7 + keep_weekly: 4 + keep_monthly: 6 \ No newline at end of file diff --git a/roles/common/tasks/backup.yml b/roles/common/tasks/backup.yml index 5bcb82a..4d7f4f0 100644 --- a/roles/common/tasks/backup.yml +++ b/roles/common/tasks/backup.yml @@ -1,34 +1,27 @@ # 1. Backup incrémental tous les jours vers la storage box: -# 1. Dans /mnt/backups, accessible en ro pour l'user system "backup" -# -> un seul backup host = celui de la storage box en sftp (pourrait être autre chose à terme) +# 1. Dans /mnt/backups, accessible en ro pour l'user "backup-sync" +# -> un seul backup repository = celui de la storage box en sftp (ou via le point de montage en sshfs) # -> via autofs + sshfs (permet de libérer la connexion en dehors de la phase de backups) -# 2. Chiffrement avec clé symétrique. La clé n'est connue que par l'host. +# 2. Chiffrement avec clé symétrique. La clé n'est connue que par l'host +# -> Stocker la clé dans un lieu sûr # 2. D'autres machines se connectent pour récupérer les backups (rsync): -# 1. En sftp chrooté via l'user system "backup" -# 2. Donner accès SSH pour ces machines à l'user system "backup" +# 1. En sftp chrooté via l'user "backup-sync" +# 2. Donner accès SSH pour ces machines à l'user "backup-sync" +# Note: L'user "backup" est déjà utilisé par Ubuntu, donc ne pas l'utiliser pour éviter des conflits (mauvais home, etc.) -- name: Create SSH directory +- include_tasks: user.yml + vars: + user: + name: "{{ backup_owner }}" + groups: [] + +- name: Ensure backup directory is read-only for backup user file: - path: "{{ ssh_config_dir }}" + path: "{{ backup_chroot_dir }}" state: directory - mode: "700" - -- name: Create SSH config file - file: - path: "{{ ssh_config_dir }}/config" - state: touch - access_time: preserve - modification_time: preserve - mode: "600" - -- name: Create backup user - user: - name: "{{ backup_owner }}" - shell: /bin/bash - # See https://unix.stackexchange.com/questions/193066/how-to-unlock-account-for-public-key-ssh-authorization-but-not-for-password-aut/193131#193131 - password: '*' - state: present - update_password: always + owner: root + group: root + mode: "og=rx" - name: Include Storage Box backup tasks import_tasks: backup_storage_box.yml diff --git a/roles/common/tasks/backup_borg.yml b/roles/common/tasks/backup_borg.yml index dee8c68..7baeb2f 100644 --- a/roles/common/tasks/backup_borg.yml +++ b/roles/common/tasks/backup_borg.yml @@ -7,25 +7,25 @@ loop_var: borg_package - name: Initialize Borg repository - command: borg init --make-parent-dirs -e "{{ borg_encryption_mode }}" "{{ borg_repository }}" + command: borg init --make-parent-dirs --umask "{{ borgmatic_config.storage.umask }}" -e "{{ borg_encryption_mode }}" "{{ borg_repository }}" environment: - BORG_PASSPHRASE: "{{ borg_passphrase }}" + BORG_PASSPHRASE: "{{ borgmatic_config.storage.encryption_passphrase }}" changed_when: "'A repository already exists' not in _borg_backup_init.stderr" failed_when: _borg_backup_init.rc >= 2 and 'A repository already exists' not in _borg_backup_init.stderr register: _borg_backup_init - name: Create Borgmatic config directory file: - path: /etc/borgmatic + path: "{{ borgmatic_config_dir }}" state: directory owner: root group: root mode: "755" -- name: Copy Borgmatic config file +- name: Copy Borgmatic config files copy: content: "{{ borgmatic_config | to_nice_yaml(indent=2) }}" - dest: /etc/borgmatic/config.yaml + dest: "{{ borgmatic_config_dir }}/config.yaml" owner: root group: root mode: "600" diff --git a/roles/common/tasks/backup_storage_box.yml b/roles/common/tasks/backup_storage_box.yml index cfbd412..2101f6b 100644 --- a/roles/common/tasks/backup_storage_box.yml +++ b/roles/common/tasks/backup_storage_box.yml @@ -6,11 +6,25 @@ loop_control: loop_var: storage_box_package +- name: Create SSH directory + file: + path: "{{ ssh_config_dir }}" + state: directory + mode: "700" + - name: Generate SSH key pair for storage box {{ storage_box_host }} openssh_keypair: path: "{{ ssh_config_dir }}/{{ storage_box_prefix }}" type: ed25519 +- name: Create SSH config file + file: + path: "{{ ssh_config_dir }}/config" + state: touch + access_time: preserve + modification_time: preserve + mode: "600" + - name: Update SSH config file for storage box {{ storage_box_host }} blockinfile: path: "{{ ssh_config_dir }}/config" diff --git a/roles/common/tasks/openssh.yml b/roles/common/tasks/openssh.yml index 3cabe7c..2da0cb2 100644 --- a/roles/common/tasks/openssh.yml +++ b/roles/common/tasks/openssh.yml @@ -8,7 +8,7 @@ owner: "0" group: "0" mode: "0644" - validate: '/usr/sbin/sshd -T -f %s' + validate: '/usr/sbin/sshd -T -C user=root -C host=localhost -C addr=localhost -f %s' notify: restart openssh - name: Trigger OpenSSH handlers diff --git a/roles/common/templates/openssh/sshd_config.j2 b/roles/common/templates/openssh/sshd_config.j2 index ca70fb7..7b00c99 100644 --- a/roles/common/templates/openssh/sshd_config.j2 +++ b/roles/common/templates/openssh/sshd_config.j2 @@ -14,4 +14,10 @@ PrintMotd no AcceptEnv LANG LC_* -Subsystem sftp /usr/lib/openssh/sftp-server +Subsystem sftp internal-sftp + +Match Group {{ backup_owner }} + X11Forwarding no + AllowTcpForwarding no + ChrootDirectory {{ backup_chroot_dir }} + ForceCommand internal-sftp