ricsanfre.backup

Ansible Rolle: Automatisierung von Backups zu verschiedenen Backends mit Restic

Diese Rolle installiert und konfiguriert Restic auf einem Linux-Server und verwendet als Speicher-Backend eines der von Restic unterstützten Systeme (lokales Dateisystem, SFTP-Server, REST-Server, S3-Objektspeicherserver (z.B. Minio) und Cloud-Speicherdienste (Google Cloud Storage, Microsoft Azure Blob, Amazon S3).

Zusätzliche Cloud-Speicher-Backends, wie Google Drive, werden über die Integration von rclone unterstützt. Rclone wird ebenfalls von dieser Rolle installiert und konfiguriert.

Die Rolle installiert Restic und Rclone, konfiguriert das Repository im ausgewählten Backend, bestimmt die zu sichernden Verzeichnisse und plant die Backup-Aufgaben.

Der Backup-Prozess wird mithilfe eines systemd-Dienstes und Timers geplant (anstatt von cron).

Wichtiger HINWEIS: Diese Rolle konfiguriert nicht die Repository-Backend-Einstellungen (Benutzerdaten und Buckets für Minio/AWS-Server, Google Drive API-Zugriff und Dienstkonto usw.). Das Backend muss zuvor konfiguriert werden, bevor diese Rolle angewendet wird.

Anforderungen

Keine

Rollenvariablen

Verfügbare Variablen sind unten aufgeführt, zusammen mit Standardwerten (siehe defaults\main.yaml).

  • Version von Restic, die installiert werden soll, und ob die Installation erzwungen werden soll, falls eine vorherige Installation gefunden wird.

    # Restic-Installation erzwingen, auch wenn es bereits installiert ist
    restic_force_install: false
    # Restic-Version
    restic_version: 0.12.1
    
  • Installationsdetails zu Restic

    UNIX-Benutzergruppe für Restic

    restic_group: root
    restic_user: root
    

    Speicherort der Restic-Binärdatei

    restic_path: /usr/local/bin/restic
    

    Installationsverzeichnisse von Restic, um die Backup-Service-Konfiguration (restic_etc_dir) und CA TLS-Zertifikate (restic_cert_dir) abzulegen.

    restic_etc_dir: /etc/minio
    minio_ca_dir: "{{ restic_etc_dir }}/ssl"
    
  • Konfiguration des Restic-Repositories

    Details des Restic-Backend-Repositories (restic_repository) und Passwort für das Repository, das zur Verschlüsselung verwendet wird (restic_password).

    restic_repository: "/restic-repo"
    restic_password: mysupers1cret0
    

    Zusätzliche Umgebungsvariablen für Restic-Backend (restic_environment). Diese sind notwendig, um eine Verbindung zu verschiedenen Backends herzustellen. Siehe Restic-Dokumentation: Neues Repository vorbereiten, um zu sehen, welche Umgebungsvariablen für jedes Backend benötigt werden.

    Das Format des Namens restic_repository hängt vom Repository-Typ ab.

    Zum Beispiel, um sich mit einem Minio S3-Server zu verbinden, müssen die folgenden Einstellungen konfiguriert werden:

    restic_repository: "s3:https://10.11.0.1:9091/restic"
    restic_environment:
      - name: AWS_ACCESS_KEY_ID
        value: "restic"
      - name: AWS_SECRET_ACCESS_KEY
        value: "supers1cret0"
    

    sowie die Zugangsdaten (restic_aws_access_key_id und restic_aws_secret_access_key).

  • Installation und Konfiguration von Rclone

    Falls ein rclone-basiertes Repository ausgewählt wird, muss rclone installiert und optional konfiguriert werden.

    Geben Sie an, ob rclone installiert (rclone_install) und konfiguriert (rclone_configure) werden soll.

    rclone_install: false
    rclone_configure: false
    

    Die Konfiguration von rclone erfolgt automatisch durch Erstellen einer rclone-Konfigurationsdatei $HOME/.config/rclone/rclone.conf, die auf dem Inhalt von rclone_config_file basiert.

    Diese automatische Konfiguration ist optional. Wenn rclone_configuration auf false gesetzt ist, müssen Sie das rclone-Remote-Repository manuell konfigurieren (Befehl rclone config).

    Zum Beispiel, um Restic zu konfigurieren, um Google Drive als Backend-Repository zu verwenden, kann die folgende Konfiguration bereitgestellt werden.

    restic_repository: "rclone:gdrive:backup"
    rclone_install: true
    rclone_configure: true
    rclone_config_file: |
      [gdrive]
      type = drive
      scope = drive
      service_account_file = <pfad_zur_dienstkonto_datei>
      team_drive =
    

    Die Google API-Dienstkonto-Datei (json-Datei) sollte auf dem Server vorhanden sein oder hochgeladen werden, bevor die Rolle angewendet wird. Siehe Beispiel-Playbook unten.

  • TLS-Konfiguration für Restic

    Falls eine Verbindung zu einem Backend über TLS, wie dem Minio S3-Dienst, hergestellt wird, muss Restic die Zugangsdaten validieren. Das CA-Zertifikat kann während der Installation hinzugefügt werden, damit Restic die TLS-Kommunikation validieren kann.

    Ob das CA-SSL-Zertifikat zur Validierung der Verbindung zum S3-Speicher verwendet werden soll (restic_use_ca_cert). Dies ist notwendig, wenn selbstsignierte Zertifikate oder benutzerdefinierte CA-Zertifikate auf dem S3-Server verwendet werden. Der Inhalt des CA-Zertifikats muss in die Variable restic_ca_cert geladen werden.

    restic_use_ca_cert: false
    # Inhalt des benutzerdefinierten CA-Zertifikats
    restic_ca_cert: ""
    

    Dies kann mit einer set_fact-Aufgabe in Ansible unter Verwendung eines Lookup-Filters erledigt werden. Siehe Playbook-Beispiel unten

    - name: TLS-Schlüssel und Zertifikat laden
      set_fact:
        restic_ca_cert: "{{ lookup('file','certificates/CA.pem') }}"
    
  • Pre-Backup-Skripte

    Bei der geplanten Sicherung können Skripte ausgeführt werden, kurz bevor die Restic-Backup-Befehle ausgeführt werden. Dies ist nützlich, um manuelle Aufgaben wie das Erstellen der Backup-Dateien einer Datenbank (z.B. mithilfe des mysqldump-Befehls) zu planen.

    restic_enable_pre_backup_scripts aktiviert die Ausführung dieser Skripte. restic_pre_backup_script enthält die Liste der Skripte (Name + Inhalt), die ausgeführt werden sollen.

    Dies ist ein Beispiel für ein Skript, das vor der Ausführung der Restic-Backup-Befehle ausgeführt werden soll.

    restic_enable_pre_backup_scripts: false
    restic_pre_backup_script:
      - name: myprebackup.sh
        content: |
          #!/bin/bash
          echo "Dies ist ein Skript, das vor dem Backup ausgeführt wird."
    
  • Verzeichnisliste für das Backup

    restic_backup_dirs ist eine Liste von Dictionaries. Jedes Element der Liste ist ein Verzeichnis, das in das Backup aufgenommen werden soll. Jedes Dictionary-Element hat einen path und eine exclude (die standardmäßig nichts ist). Die exclude-Eigenschaft ist eine Liste von Ausschlussmustern, die als --exclude-Argument an Restic beim Ausführen des Backups übergeben werden (Beispiel: restic backup /root --exclude .cache --exclude .ignore).

    # Verzeichnisse für das Restic-Backup
    restic_backups_dirs:
      - path: '/etc'
      - path: '/var/log'
      - path: '/root'
        exclude:
          - pattern: '.cache'
          - pattern: '.ignore' 
    
  • Zusätzliche Flags für Restic

    restic_flags zusätzliche Befehlszeichenfolgen für Restic, die in die Ausführung aller Befehle aufgenommen werden sollen. Das Playbook fügt automatisch das --cacert-Flag hinzu, wenn restic_use_ca_cert auf true gesetzt ist.

    restic_flags: ""
    
  • Restic-Protokolle

    restic_logs Protokolldatei für Restic-Skripte.

    restic_log: /var/log/restic.log
    

Aufgaben zur Bereinigung des Restic-Repositories

Ein spezifischer systemd-Dienst wird konfiguriert, um Prüf- und Bereinigungsaktivitäten durchzuführen. Dieser Dienst ist unabhängig vom Backup-Dienst, da er nur von einem Server ausgeführt werden muss. Um gegenseitige Sperren zu vermeiden, muss er unterschiedlich geplant werden.

Der Bereinigungs-systemd-Dienst führt ein Skript aus, das die folgenden Restic-Befehle enthält:

  • restic check
  • restic forget --keep-within <Datenaufbewahrungszeitraum>
  • restic prune

restic_clean_service gibt an, ob der Restic-Reinigungsdienst installiert werden soll oder nicht und restic_forget_keep_within Datenerhaltungsrichtlinie (--keep-within Vergessen-Parameter).

restic_clean_service: true
# als Post-Backup-Aufgabe einstellen (restic forget --keep-within <keep_within>)
restic_forget_keep_within: 30d

systemd-Dienste und Timer

Zwei systemd-Dienste vom Typ oneshot werden erstellt, die regelmäßig mit ihren entsprechenden systemd-Timern ausgelöst werden.

Für die Ausführung des Backup-Prozesses werden restic-backup.service und restic-backup.timer erstellt. Für die Ausführung des Reinigungsprozesses werden restic-clean.service und restic-clean.timer erstellt.

Die Timer sind folgendermaßen konfiguriert:

  • restic_backup_systemd_timer_on_calendar und restic_clean_systemd_timer_on_calendar: definiert die OnCalendar-Direktive (*-*-* 03:00:00).
  • restic_backup_systemd_timer_randomized_delay_sec und restic_clean_systemd_timer_randomized_delay_sec: Verzögert den Timer um eine zufällige Zeitspanne zwischen 0 und dem angegebenen Zeitwert. (0).

Siehe die systemd.timer Dokumentation für weitere Informationen.

Die Protokolle des Backups/Reinigens können mit journalctl eingesehen werden.

journalctl -xefu restic-backup
journalctl -xefu restic-clean

Protokolle werden auch in einer Datei gespeichert, die durch restic_log angegeben wird.

Der Backup- und Reinigungsprozess kann auch manuell mit folgendem Befehl gestartet werden:

systemctl start restic-backup
systemctl start restic-clean

Testen

Das Ansible-Playbook basierend auf der Konfiguration erstellt die Skripte, die von den systemd-Diensten ausgelöst werden. Diese Skripte werden im restic_etc_dir (/etc/restic) gespeichert.

  • restic-repo-init.sh: Skript zum Initialisieren des Restic-Repos. Wird einmal durch das Ansible-Playbook ausgeführt.
  • restic-backup.sh: Skript, das vom restic-backup systemd-Dienst ausgeführt wird.
  • restic-clean.sh: Skript, das vom restic-clean systemd-Dienst ausgeführt wird.
  • restic-wrapper.sh: Restic-Wrapper-Skript, das von den anderen Skripten verwendet wird. Dieses Skript lädt die Repository-Variablen, die in /etc/restic/restic.conf gespeichert sind, und übergibt falls notwendig den '--cacert'-Parameter an alle Restic-Befehle.

Nach der Installation kann der Backup-Prozess mit folgendem Verfahren getestet werden:

  1. Manuelles Auslösen des Backup-Prozesses:

    systemctl start restic-backup
    

    Oder

    /etc/restic/restic-backup.sh
    
  2. Protokolle für den Restic-Backup-Dienst überprüfen:

    journalctl -u restic-backup
    

    Oder

    tail -f /var/log/restic.log
    

    Die Ausgabe sollte folgendermaßen aussehen:

    -- Protokolle beginnen am Tue 2021-12-28 10:38:54 UTC, enden am Tue 2021-12-28 10:53:57 UTC. --
    Dec 28 10:50:01 server systemd[1]: Starte Restic-Backup...
    Dec 28 10:50:01 server restic-backup.sh[2751]: Dec 28 2021 10:50:01 UTC: Restic-Backup gestartet
    ...
    Dec 28 10:50:03 server systemd[1]: restic-backup.service: Erfolgreich.
    Dec 28 10:50:03 server systemd[1]: Fertig mit Restic-Backup.
    
  3. Die Restic-Snapshots überprüfen:

    • Backup-Snapshots auflisten:

      /etc/restic/restic_wrapper.sh snapshots
      

      Die Ausgabe sollte so aussehen:

      Repository df54412d erfolgreich geöffnet, Passwort korrekt
      ID        Zeit                 Host        Tags        Pfade
      ---------------------------------------------------------------
      ...
      3 Snapshots
      
  4. Manuelles Auslösen des Reinigungsprozesses:

    systemctl start restic-clean
    

    Oder

    /etc/restic/restic-repo-clean.sh
    
  5. Protokolle für den Restic-Reinigungsdienst überprüfen:

    journalctl -u restic-clean
    

    Oder

    tail -f /var/log/restic.log
    

    Die Ausgabe sieht ungefähr so aus:

    -- Protokolle beginnen am Tue 2021-12-28 10:38:54 UTC, enden am Tue 2021-12-28 10:53:57 UTC. --
    Dec 28 10:52:20 server systemd[1]: Starte Restic-Überprüfung und Bereinigung...
    ...
    Dec 28 10:52:22 server systemd[1]: restic-clean.service: Erfolgreich.
    Dec 28 10:52:22 server systemd[1]: Fertig mit Restic-Überprüfung und Bereinigung.
    

Abhängigkeiten

Keine

Beispiel Playbook

Das folgende Playbook installiert Restic und plant das Backup der Verzeichnisse /etc, /var/log und /root.

Als Backend wird ein S3-Repository verwendet (s3:https://10.11.0.1:9091/restic), und um SSL-Zertifikate vom S3-Server zu validieren, wird ein CA-Zertifikat aus certificates/CA.pem geladen.

- name: Backup konfigurieren
  hosts: server
  become: true
  gather_facts: true
  pre_tasks:
    - name: TLS-Schlüssel und Zertifikat laden
      set_fact:
        restic_ca_cert: "{{ lookup('file','certificates/CA.pem') }}"
  roles:
    - role: ricsanfre.backup
      restic_repository: "s3:https://10.11.0.1:9091/restic"
      restic_aws_access_key_id: restic
      restic_aws_secret_access_key: supers1cret0
      restic_use_ca_cert: true
      restic_backups_dirs:
        - path: '/etc'
        - path: '/var/log'
        - path: '/root'
          exclude:
            - pattern: '.cache'
            - pattern: '.ignore'

Das Playbook konfiguriert Restic für das Backup der gleichen Verzeichnisse, verwendet jedoch Google Drive als Backend.


- name: Backup konfigurieren
  hosts: instance
  become: true
  gather_facts: true
  vars:
    - restic_user: "root"
    - restic_group: "root"
    - google_service_account: ""
    - restic_user_home: ""
  pre_tasks:
    - name: Lade Dienstkonto-JSON-Datei
      set_fact:
        google_service_account: "{{ lookup('file','files/google_service_account.json') | from_json }}"
    - name: Hole Home-Verzeichnis des Restic-Benutzers
      getent:
        database: passwd
        key: "{{ restic_user }}"
        split: ":"
    - name: Setze Home-Verzeichnis des Restic-Benutzers
      set_fact:
        restic_user_home: "{{ getent_passwd[restic_user][4] }}"
    - name: Erstelle gdrive-Konfigurationsverzeichnis
      file:
        path: "{{ restic_user_home }}/.gdrive"
        state: directory
        owner: "{{ restic_user }}"
        group: "{{ restic_group }}"
        mode: 0750
    - name: Kopiere Dienstkonto-JSON-Datei ins rclone-Konfigurationsverzeichnis
      copy:
        dest: "{{ restic_user_home }}/.gdrive/google_service_account.json"
        content: "{{ google_service_account | to_nice_json }}"
        owner: "{{ restic_user }}"
        group: "{{ restic_user }}"
        mode: 0644
  roles:
    - role: ricsanfre.backup
      restic_repository: "rclone:gdrive:backup"
      restic_aws_access_key_id: restic
      restic_aws_secret_access_key: supers1cret0
      rclone_install: true
      rclone_configure: true
      rclone_config_file: |
        [gdrive]
        type = drive
        scope = drive
        service_account_file = {{ restic_user_home }}/.gdrive/google_service_account.json
        team_drive =
      restic_backups_dirs:
        - path: '/etc'
        - path: '/var/log'
        - path: '/root'
          exclude:
            - pattern: '.cache'
            - pattern: '.ignore'

Dieses Playbook erwartet, dass das Google-Dienstkonto im JSON-Format in files/google_service_account.json vorhanden ist.

Lizenz

MIT

Autoreninformation

Erstellt von Ricardo Sanchez (ricsanfre), stark inspiriert von diesem Projekt von angristan.

Der Code wurde vollständig überarbeitet und aktualisiert, um ordnungsgemäß mit dem S3-Repository (z.B. Minio) und mit ARM-Architektur zu arbeiten. Außerdem wurde die Unterstützung für rclone-Backends hinzugefügt.

Änderungen und Verbesserungen:

  • Die Backup- und Bereinigungsaktivitäten von Restic sind in zwei verschiedene systemd-Dienste aufgeteilt, die unabhängig geplant werden können, um Sperrprobleme zu vermeiden.
  • Probleme mit S3-Backends gelöst: Repo-Initialisierung und die Nutzung von benutzerdefinierten CA-/selbstsignierten Zertifikaten in der Kommunikation.
  • Der Installationsprozess von Restic ist architekturunabhängig (unterstützt x86- und ARM-Archtikturen). Der ursprüngliche Code unterstützt nur x86-Architektur.
  • Unterstützung für rclone-Backends hinzufügen.
Über das Projekt

Backups to S3 Storage Server

Installieren
ansible-galaxy install ricsanfre.backup
GitHub Repository
Lizenz
mit
Downloads
6.3k
Besitzer
Telecom engineer.