Fixed Duplicity Roles

This commit is contained in:
Nis Wechselberg 2024-02-11 16:29:29 +01:00
parent 5ae3a0631c
commit 954420e9de
14 changed files with 1707 additions and 155 deletions

1556
plugins/action/gpg_key.py Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,2 +1,6 @@
---
# defaults file for duplicity-client
# User to run duplicity things under
duplicity_client_user: "backup-user"
# Paths to backup through duplicity
duplicity_client_backup_paths: []

View file

@ -1,2 +0,0 @@
---
# handlers file for duplicity-client

View file

@ -1,2 +1,44 @@
---
# tasks file for duplicity-client
- name: "Install required software on clients"
become: true
ansible.builtin.package:
name: "{{ item }}"
state: "present"
with_items:
- "acl"
- name: "Create backup user on clients"
become: true
ansible.builtin.user:
name: "{{ duplicity_client_user }}"
- name: "Deploy server ssh keys to clients"
become: true
ansible.posix.authorized_key:
user: "{{ duplicity_client_user }}"
state: "present"
key: "{{ item.duplicity_server_user_key }}"
with_items: "{{ groups['duplicityclient'] | flatten(levels=1) }}"
- name: "Set default ACLs on backup data"
become: true
ansible.posix.acl:
path: "{{ item }}"
entity: "{{ duplicity_client_user }}"
etype: "user"
permissions: r-X
default: true
state: present
recursive: true
with_items: "{{ duplicity_client_backup_paths }}"
- name: "Set read ACLs on existing backup data"
become: true
ansible.posix.acl:
path: "{{ item }}"
entity: "{{ duplicity_client_user }}"
etype: "user"
permissions: r-X
state: present
recursive: true
with_items: "{{ duplicity_client_backup_paths }}"

View file

@ -1,2 +0,0 @@
localhost

View file

@ -1,5 +0,0 @@
---
- hosts: localhost
remote_user: root
roles:
- duplicity-client

View file

@ -1,2 +0,0 @@
---
# vars file for duplicity-client

View file

@ -1,2 +1,6 @@
---
# defaults file for duplicity-server
duplicity_server_user: "backup-user"
# The GnuPG key to use for encryption
duplicity_server_gnupg_fingerprint: "C05AD49B790BAC8E3B573B697B25171F921B9E57"

View file

@ -1,2 +0,0 @@
---
# handlers file for duplicity-server

View file

@ -1,144 +1,88 @@
---
# - name: Install required software on servers
# become: true
# ansible.builtin.package:
# name: "{{ item }}"
# state: present
# with_items:
# - duplicity
# - sshfs
# - python3-packaging
# - acl
### BASIC SOFTWARE
- name: "Install required software on servers"
become: true
ansible.builtin.package:
name: "{{ item }}"
state: "present"
with_items:
- "duplicity" # Obviously needed for backup
- "sshfs" # TO be able to mount the remote directory
- "python3-packaging" # ??? For something
- "acl" # To manage the access control on the backup data
- name: Create backup user on servers
### SSH ACCESS (USER/KEYS)
- name: "Create backup user on servers"
become: true
ansible.builtin.user:
name: "{{ duplicity_server_user }}"
generate_ssh_key: true
ssh_key_type: ed25519
generate_ssh_key: true # We want to generate an ssh key to be able to configure the access on the clients later
ssh_key_type: "ed25519"
ssh_key_comment: "{{ duplicity_server_user }}@{{ ansible_hostname }} (generated by ansible)"
register: "duplicity_server_created_user" # Store the return value for the ssh key and home path
- name: Fetch server keys to local system
- name: "Store server ssh key as fact for later usage"
ansible.builtin.set_fact:
duplicity_server_user_key: "{{ duplicity_server_created_user['ssh_public_key'] }}"
- name: "Fetch sshd fingerprints from clients"
ansible.builtin.slurp:
src: "/etc/ssh/ssh_host_ecdsa_key.pub"
delegate_to: "{{ item }}"
with_items: "{{ groups['duplicityclient'] | flatten(levels=1) }}"
changed_when: false
register: "duplicity_client_host_key"
- name: "Register client host keys in server"
become: true
become_user: "{{ duplicity_server_user }}"
ansible.builtin.slurp:
src: ~/.ssh/id_ed25519.pub
register: duplicity_server_key
changed_when: false
ansible.builtin.known_hosts:
name: "{{ item.item }}"
key: "{{ item.item }} {{ item.content | b64decode }}"
with_items: "{{ duplicity_client_host_key.results }}"
# - name: "Deploy server ssh keys to clients"
# when:
# - duplicity_client
# - hostvars[item].duplicity_server is defined and hostvars[item].duplicity_server
# become: true
# ansible.posix.authorized_key:
# user: "{{ duplicity_client_user }}"
# state: "present"
# key: "{{ lookup('file', 'buffer/{{item}}-id_ed25519.pub') }}"
# loop: "{{ groups['duplicity'] }}"
### GNUPG ENCRYPTION
- name: "Ensure gnupg config dir"
become: true
become_user: "{{ duplicity_server_user }}"
ansible.builtin.command:
cmd: "gpg --list-keys"
creates: "{{ duplicity_server_created_user['home'] }}/.gnupg"
# - name: "Fetch sshd fingerprints from clients"
# when: duplicity_client
# ansible.builtin.fetch:
# src: "/etc/ssh/ssh_host_ecdsa_key.pub"
# dest: "buffer/{{ ansible_host }}-ssh_host_ecdsa_key.pub"
# flat: true
# changed_when: false
- name: "Install encryption key for backups"
become: true
become_user: "{{ duplicity_server_user }}"
de_enbewe.duplicity.gpg_key:
fpr: "{{ duplicity_server_gnupg_fingerprint }}"
keyserver: "hkps://keys.openpgp.org"
trust: 5
homedir: "{{ duplicity_server_created_user['home'] }}/.gnupg"
# - name: "Register client host keys in server"
# when:
# - duplicity_server
# - hostvars[item].duplicity_client is defined and hostvars[item].duplicity_client
# become: true
# become_user: "{{ duplicity_server_user }}"
# ansible.builtin.known_hosts:
# name: "{{ item }}"
# key: "{{ item }} {{ lookup('file', 'buffer/{{item}}-ssh_host_ecdsa_key.pub') }}"
# loop: "{{ groups['duplicity'] }}"
### BACKUP SCRIPTS
- name: "Create backup script path"
become: true
ansible.builtin.file:
path: "{{ duplicity_server_created_user['home'] }}/scripts"
state: "directory"
owner: "{{ duplicity_server_user }}"
group: "{{ duplicity_server_user }}"
mode: "u=rwx,g=rx,o=rx"
# - name: "Test ssh connection from server to client"
# when:
# - duplicity_server
# - hostvars[item].duplicity_client is defined and hostvars[item].duplicity_client
# become: true
# become_user: "{{ duplicity_server_user }}"
# ansible.builtin.command: "ssh -o 'BatchMode yes' {{ duplicity_client_user }}@{{ item }} 'echo success'"
# changed_when: false
# loop: "{{ groups['duplicity'] }}"
- name: "Create backup scripts for clients"
become: true
become_user: "{{ duplicity_server_user }}"
ansible.builtin.template:
src: "backup-script.j2"
dest: "{{ duplicity_server_created_user['home'] }}/scripts/backup-{{ item }}.sh"
mode: "u=rwx,g=rx,o=rx"
with_items: "{{ groups['duplicityclient'] }}"
# - name: "Set default ACLs on backup data"
# when: duplicity_client
# become: true
# ansible.posix.acl:
# path: "{{ item }}"
# entity: "{{ duplicity_client_user }}"
# etype: "user"
# permissions: r-X
# default: true
# state: present
# recursive: true
# loop: "{{ duplicity_client_backup_paths }}"
# - name: "Set read ACLs on existing backup data"
# when: duplicity_client
# become: true
# ansible.posix.acl:
# path: "{{ item }}"
# entity: "{{ duplicity_client_user }}"
# etype: "user"
# permissions: r-X
# state: present
# recursive: true
# loop: "{{ duplicity_client_backup_paths }}"
# - name: "Ensure gnupg config dir"
# when: duplicity_server
# become: true
# become_user: "{{ duplicity_server_user }}"
# ansible.builtin.command:
# cmd: "gpg --list-keys"
# creates: "/home/{{ duplicity_server_user }}/.gnupg"
# - name: "Install encryption key for backups"
# when: duplicity_server
# become: true
# gpg_key:
# fpr: "C05AD49B790BAC8E3B573B697B25171F921B9E57"
# keyserver: "hkps://keys.openpgp.org"
# trust: "5"
# homedir: "/home/{{ duplicity_server_user }}/.gnupg"
# - name: "Create backup script path"
# when: duplicity_server
# become: true
# ansible.builtin.file:
# path: "{{ duplicity_server_scriptdir }}"
# state: "directory"
# owner: "{{ duplicity_server_user }}"
# group: "{{ duplicity_server_user }}"
# mode: "u=rwx,g=rx,o=rx"
# - name: "Create backup scripts for clients"
# when:
# - duplicity_server
# - hostvars[item].duplicity_client is defined and hostvars[item].duplicity_client
# become: true
# become_user: "{{ duplicity_server_user }}"
# ansible.builtin.template:
# src: "backup-script.j2"
# dest: "{{ duplicity_server_scriptdir }}/backup-{{ item }}.sh"
# mode: "u=rwx,g=rx,o=rx"
# loop: "{{ groups['duplicity'] }}"
# - name: "Register cronjob for clients"
# when:
# - duplicity_server
# - hostvars[item].duplicity_client is defined and hostvars[item].duplicity_client
# become: true
# ansible.builtin.cron:
# name: "backup-{{ item }}"
# user: "{{ duplicity_server_user }}"
# job: "{{ duplicity_server_scriptdir }}/backup-{{ item }}.sh"
# minute: "{{ hostvars[item].duplicity_client_backup_minute }}"
# hour: "{{ hostvars[item].duplicity_client_backup_hour }}"
# loop: "{{ groups['duplicity'] }}"
- name: "Register cronjob for clients"
become: true
ansible.builtin.cron:
name: "backup-{{ item }}"
user: "{{ duplicity_server_user }}"
job: "{{ duplicity_server_created_user['home'] }}/scripts/backup-{{ item }}.sh"
minute: "{{ hostvars[item].duplicity_client_backup_minute | default(12) }}"
hour: "{{ hostvars[item].duplicity_client_backup_hour | default(1) }}"
with_items: "{{ groups['duplicityclient'] }}"

View file

@ -0,0 +1,24 @@
#!/bin/bash
# Cleanup old backups
duplicity remove-all-inc-of-but-n-full 2 --force file://{{ duplicity_server_storage_root }}/{{item}}
duplicity remove-all-but-n-full 3 --force file://{{ duplicity_server_storage_root }}/{{item}}
# Prepare mount directory
rm -rf {{ duplicity_server_mount_root }}/{{ item }}
mkdir -p {{ duplicity_server_mount_root }}/{{ item }}
cd {{ duplicity_server_mount_root }}/{{ item }}
# mount the client directories through sshfs
{% for path in hostvars[item].duplicity_client_backup_paths %}
mkdir -p .{{ path }}
sshfs {{ hostvars[item].duplicity_client_user | default(duplicity_client_user) }}@{{ item }}:{{path}} .{{ path }}
{% endfor %}
# Perform the backup
duplicity --full-if-older-than 1W --encrypt-key C05AD49B790BAC8E3B573B697B25171F921B9E57 . file://{{ duplicity_server_storage_root }}/{{item}}
# Unmount the directories
{% for path in hostvars[item].duplicity_client_backup_paths %}
fusermount -u .{{ path }}
{% endfor %}

View file

@ -1,2 +0,0 @@
localhost

View file

@ -1,5 +0,0 @@
---
- hosts: localhost
remote_user: root
roles:
- duplicity-server

View file

@ -1,2 +0,0 @@
---
# vars file for duplicity-server