====== Restic Backup im Netzwerk ====== Übersicht über alle Backups: ''http://resticinfo.spring.private'' Idee aus perplexity: To protect access to Traefik services from the internet using basic authentication while leaving intranet access unprotected, you can use a combination of Traefik's IPWhiteList middleware and BasicAuth middleware. Here's how to set it up: Configuration Steps Create a BasicAuth middleware for external access: text http: middlewares: basic-auth: basicAuth: users: - "admin:$apr1$h9OxLeY20/5uiXjfPgdRxuFlrfqBf2QifYDgrwsR6rAEgX3/dpOGq" Create an IPWhiteList middleware for internal access: text http: middlewares: internal-whitelist: ipWhiteList: sourceRange: - "192.168.0.0/16" - "10.0.0.0/8" - "172.16.0.0/12" Set up a middleware chain combining both: text http: middlewares: secure-chain: chain: middlewares: - internal-whitelist - basic-auth Apply the middleware chain to your router: text http: routers: my-service: rule: "Host(`example.com`)" service: "my-service" middlewares: - secure-chain This configuration will allow unrestricted access from the specified internal IP ranges while requiring basic authentication for external access2 4 . Additional Considerations Ensure you replace the example BasicAuth credentials with your own securely hashed passwords1 5 . Adjust the IP ranges in the IPWhiteList middleware to match your internal network configuration4 . For enhanced security, consider using more robust authentication methods like Authelia or Authentik for external access6 . By implementing this setup, you can effectively protect your Traefik services from unauthorized external access while maintaining convenient internal access within your network. can the name "basic-auth" in this example be modified or is it fixed? Sources Answer The name "basic-auth" in the example can be modified. It is not a fixed name, but rather a custom identifier for the middleware you're creating1 2 . You can choose any name you prefer for your middleware, as long as it follows Traefik's naming conventions. For example, you could use names like "my-auth", "custom-basic-auth", or "secure-access"5 6 . When defining a middleware, you typically use a structure like: text http: middlewares: your-chosen-name: basicAuth: # configuration details Just remember to reference the middleware using the name you've chosen when applying it to your routers or services2 5 The general format for defining a router in Traefik labels is: text - "traefik.http.routers..rule=" Where is a custom identifier you choose for your router, and is the routing rule you want to apply. ===== Restic Server auf hermes ===== ===== Backup der Server hermes, florapower, netcup ===== hermes macht Pull-Backups von sich selbst und den Servern florapower und netcup mit hilfe des Scripts ''/usr/local/bin/run-restic.sh'' ===== Restic Backups von kudell und denkbrett via systemd ===== ( von https://fedoramagazine.org/automate-backups-with-restic-and-systemd/ ) Systemd erlaubt das Starten von Services auch einmal/Tag. Achtung: Auf Ubuntu prüfen ob restic in /usr/bin oder /usr/local/bin liegt ==== Service-Unitfile anlegen ==== sudo systemctl edit --force --full restic-backup.service # from https://fedoramagazine.org/automate-backups-with-restic-and-systemd/ [Unit] Description=Restic backup service After=network-online.target Wants=network-online.service StartLimitIntervalSec=6000 StartLimitBurst=30 [Service] Type=oneshot ExecStart=/usr/bin/restic backup --host $HOST --verbose --one-file-system --tag systemd.timer $BACKUP_EXCLUDES $BACKUP_PATHS EnvironmentFile=/root/restic-backup.conf Restart=on-failure RestartSec=60 [Install] WantedBy=default.target ==== EnvironmentFile anlegen ==== HOME=/root HOST=denkbrett RESTIC_REPOSITORY=rest:https://:@restic. RESTIC_PASSWORD_FILE=/root/resticpw BACKUP_PATHS="/root /etc /home/springm /root /usr/local /var/spool/cron/crontabs" BACKUP_EXCLUDES="--exclude-file /root/restic-exclude.txt --exclude-if-present .exclude_from_backup" ==== Service starten/stoppen/enablen/prüfen ==== * Änderungen mitteilen mit ''systemctl daemon-reload'' * Starten mit ''systemctl start restic-backup.service'' (führt Backup durch) * Als Dienst einrichten mit ''systemctl enable restic-backup.service'' * Dienst prüfen mit ''systemctl status restic-backup.service'' ==== Timer anlegen ==== sudo systemctl edit --force --full restic-backup.timer [Unit] Description=Backup with restic daily [Timer] OnCalendar=daily OnActiveSec=30 Persistent=true [Install] WantedBy=timers.target * Enablen mit systemctl enable --now restic-backup.timer * Status prüfen mit systemctl status restic-backup.timer ===== Restic Backups von kudell und denkbrett - DEPRECATED - ===== Das Backup sollte im Prinzip täglich von hermes getriggert als Pull-Backup laufen, allerdings sind diese Rechner nicht immer zur festgesetzten Backup-Zeit eingeschaltet. Die Alternative ist ein Push-Backup, das vom Client getriggert entweder nach dem Booten oder nach dem Aufwachen aus dem Suspend/Hibernate stattfindet. Achtung: Das Paket ''at'' muss installiert sein, überprüfen als root am einfachsten mit ''atq'' Das Network-Connect-Script: #!/bin/bash LOCKFILE=/var/lib/restic/run_restic_once_a_day.lock LOG=/tmp/run_restic_backup_once_a_day.log echo "">>$LOG && echo $(date) >> $LOG if [ -e "$LOCKFILE" ]; then echo Check if the lock file is from today >> $LOG if [ "$(date +%Y-%m-%d)" != "$(cat $LOCKFILE)" ]; then echo Lock file is from a previous day, remove it >> $LOG rm "$LOCKFILE" else echo Lock file is from today, exit >> $LOG exit 0 fi fi echo Run restic backup >> $LOG logger -p local0.notice -s "Running restic backup" /usr/bin/date +%Y-%m-%d > $LOCKFILE && /usr/bin/touch $LOCKFILE # create lockfile immediately sleep 30 HOME=/root RESTIC_REPOSITORY=rest:https://test:test@restic.hermes.markus-spring.info /usr/bin/restic -v --password-file /root/resticpw --host denkbrett --exclude-caches --exclude-file=/root/restic-exclude.txt backup /etc /home/springm /root /usr/local /var/spool/cron/crontabs 2>>$LOG if [[$? -eq 0]]; then echo "Backup successful">>$LOG else rm $LOCKFILE fi Das Resume-Script: #!/bin/sh set -e # logger -p local0.notice -s "Running $0 with event $1" RESTIC_START_SCRIPT=/etc/network/if-up.d/run_restic_backup_once_a_day.sh case "$1" in post) logger -p local0.notice -s $0 event $1 submitting restic to at-daemon echo $RESTIC_START_SCRIPT | at now esac Achtung: lt https://man.archlinux.org/man/systemd-sleep.8 : //Note that scripts or binaries dropped in /usr/lib/systemd/system-sleep/ are intended for local use only and should be considered hacks. If applications want to react to system suspend/hibernation and resume, they should rather use the Inhibitor interface[1]// ==== Ubuntu braucht einen Service ==== sudo systemctl edit --force --full restic_run_when_network_up.service [Unit] Description=Run restic backup after network available Wants=network-online.target After=network-online.target [Service] Type=simple User=root #ExecStart=/etc/network/if-up.d/run_restic_backup_once_a_day.sh ExecStart=/usr/local/bin/run_restic_backup_once_a_day.sh [Install] WantedBy=multi-user.target sudo systemctl enable restic_run_when_network_up.service sudo systemctl start restic_run_when_network_up.service from: https://askubuntu.com/questions/41400/how-do-i-make-the-script-to-run-automatically-when-tun0-interface-up-down-events ===== Restic Backups von Windows-Clients ===== siehe [[computer:restic:windows:restic-backup|Restic Backup von Windows-Rechnern]] ===== Übersicht über die Backups ===== ==== Erzeugen der /var/lib/restic/snapshots.json ==== Ein inotify-Eintrag auf das snapshots-Verzeichnis im Restic-Repository triggert das Schreiben einer JSON-Zustandsdatei mit dem Befehl restic snapshots -c --json > /var/lib/restic/snapshots.json Die Automatisierung erfolgt über einen systemd-Service (vgl. https://www.putorius.net/systemd-path-units.html) [Unit] Description="Monitor restic snapshots for changes" [Path] PathModified=/backupdisk/restic-repo/snapshots/ Unit=restic-snapshots-mon.service [Install] WantedBy=multi-user.target [Unit] Description="Recreate /var/lib/restic/snapshots.json when snapshots have changed" [Service] ExecStart=/usr/local/sbin/restic_json.sh #!/bin/bash RESTIC_PASSWORD=abc RESTIC_REPOSITORY=/backupdisk/def /usr/bin/restic snapshots -c --json > /tmp/restic.json Analysieren mit ''systemd-analyze verify /etc/systemd/system/restic-snapshots-mon*'' Starten mit ''systemctl start restic-snapshots-mon.path'' Beim Systemstart hochfahren mit ''systemctl enable restic-snapshots-mon.path'' Status überprüfen mit ''systemctl status restic-snapshots-mon.path'' Log-Einträge ansehen mit ''journalctl -u restic-snapshots-mon.path'' Erzeugen der ''/tmp/restic.json'' beim booten durch einen cron-eintrag @reboot /usr/local/sbin/restic-json.sh ==== Flask-Service zur Visualisierung ==== Ein Docker-Container mit dem Programm restic2html stellt die JSON-Datei als sortierbare und entsprechend des Snapshot-Alters zeilenweise eingefärbte HTML-Tabelle dar. services: restic2html: image: restic2html container_name: restic2html build: context: . dockerfile: Dockerfile restart: always environment: - PUID=1000 - PGID=1000 - TZ=Europe/Berlin volumes: - /tmp:/tmp ports: - 5001:5001 environment: - TZ=${TZ:-Europe/Berlin} labels: - "traefik.enable=true" # <== Enable traefik on itself to view dashboard and assign subdomain to view it - "traefik.http.services.resticinfo.loadbalancer.server.port=5001" - "traefik.http.routers.resticinfo.rule=Host(`resticinfo.local`)" networks: - proxy networks: proxy: external: true Der Container ist nur aus dem Intranet unter https://resticinfo.local erreichbar. ===== Restic Forget/Prune ===== ist nötig, um überflüssige Backups zu löschen. restic forget --keep-daily 6 --keep-weekly 4 --keep-monthly 6 --keep-yearly 99 --keep-tag yearly Auf ''restic forget'' muss ''restic prune'' folgen, um den Löschvorgang durchzuführen ===== Mounten des Repository für ein Restore ===== restic mount /resticrestore Kann z.b. mit ''--host kudell'' eingeschränkt werden. Das Verzeichnis kann über nfs freigegeben werden, z.B. folgender Eintrag in /etc/exports: /resticrestore kudell.fritz.box(ro,async,no_subtree_check,crossmnt,fsid=0) Achtung: dieser Prozess bleibt im Terminal geöffnet. Sicherstellen dass der Mount wieder aufgehoben wird! ===== Importieren historischer Backups ===== ===== Tricks / Links ===== ===== Environment-Variablen ===== Zur Vereinfachung der Befehlseingabe können sowohl Repository als auch Paßwort im Environment gesetzt werden. export RESTIC_REPOSITORY=/repo/restic RESTIC_PASSWORD=hättestduwohlgerne ===== Tags ===== rsnapshot-Sicherungen können importiert werden - das dauert! - und mit dem Tag "historisch" versehen werden. Tags können nachträglich hinzugefügt werden, wenn kein anderer restic-Vorgang läuft. restic tag --set historisch ba37903f Der restic-Befehl "forget" kann mit --keep-tag angewiesen werden, diese historischen Snapshots nicht zu löschen. In einer Übergangszeit müssen dann monatliche, wöchentliche und tägliche Snapshots manuell gelöscht werden. ===== rsnapshot-Daten importieren ===== Das Importieren der historischen rsnapshot-Daten vorbereiten mit export HOST=hermes; \ ls -lt --time-style="+%Y-%m-%d" /backupdisk/$HOST/ | \ grep -v total | \ perl -pe 's!.*\s(\d+-\d+-\d+)\s(.*?)\.(\d+)$!restic backup --host $ENV{HOST} --tag historisch --tag $1 --tag $2 /backupdisk/$ENV{HOST}/$2.$3!' ===== Externe Server ===== Backup-Server induziertes backup mit Example command on the server: ssh -R 127.0.0.1:20022::22 "sudo restic -r 'sftp:127.0.0.1:/path/to/repo' -p .resticpw backup -x /" For that to work you need: a .ssh/config specifying the "Port 20022" for 127.0.0.1 on the client proper known_hosts files ssh pubkeys exchanged between client and server (via 127.0.0.1) ==== Netcup Test ==== Erfolgreich getestet mit RESTIC_PASSWORD=geheim restic -v -v --exclude-file=/root/restic-exclude.txt \ -o sftp.command='ssh hermes.markus-spring.info -p 22022 -s sftp' \ -r sftp:hermes.markus-spring.info:/repo/restic backup /home/springm Aber: * braucht passwortlosen root-Zugang auf hermes * Eventuell geht ein nur-sftp-account * Und eine Nur-Hinzufügen-Konfiguration des Repos ===== Restic-RestServer unter Docker ===== version: '2' services: restserver: image: restic/rest-server:latest container_name: restic-rest environment: - PUID=1000 - PGID=1000 - TZ=Europe/Berlin - "OPTIONS=--append-only" volumes: - /repo/restic:/data ports: - "127.0.0.1:8010:8000" networks: - proxy labels: - "traefik.enable=true" - "traefik.docker.network=proxy" - "traefik.http.routers.restic-rest.rule=Host(`restic.meine.domain`)" - "traefik.http.routers.restic-rest.entrypoints=https" - "traefik.http.routers.restic-rest.tls=true" - "traefik.http.routers.restic-rest.tls.certresolver=cloudflare" - "traefik.http.services.restic-rest.loadBalancer.server.port=8000" networks: proxy: external: true Benutzer anlegen docker exec -it restic-rest create_user user passwort Test auf dem netcup-Server export RESTIC_REPOSITORY="rest:https://user:passwort@restic.meine.domain" restic -v snapshots restic -v --exclude-file=/root/restic-exclude.txt backup /home/springm Backup löschen schlägt fehl, weil das Restic-Repo mit --append-only eingebunden ist. restic forget d50ada2f enter password for repository: repository 01a62565 opened successfully, password is correct Remove() returned error, retrying after 552.330144ms: blob not removed, server response: 403 Forbidden (403) ... unable to remove from the repository [0:45] 0.00% 0 / 1 files deleted blob not removed, server response: 403 Forbidden (403) ===== Importieren alter Backups in chroot-Umgebung ===== Restic arbeitet wesentlich schneller, wenn die Pfade zwischen den Backups gleich sind.Dann werden nur Datei-Metadaten verglichen, anstatt die Datei komplett zu lesen, zu chunken und zu prüfen ob die Chunks schon existieren. Beim Importieren historischer Backups aus rsnapshots ist das aber nicht der Fall. In einer chroot-Umgebung können die historischen Backups mit bind-mounts so zur Verfügung gestellt werden, dass die Wurzelpfade immer gleich sind, d.h., daily.0-n, weekly.0-n etc werden für restic unsichtbar ==== Chroot-Umgebung vorbereiten ==== Chroot-Umgebung erstellen nach Anweisung in https://www.maketecheasier.com/use-chroot-linux/ mkdir /restic-chroot cd /restic-chroot mkdir bin cp /usr/bin/restic bin/ cp /bin/mount bin/ cp /bin/ls bin/ cp /bin/rm bin/ cp /bin/bash bin/ Skript /restic-chroot/copydependancy.sh anlegen und ausführbar machen: #!/bin/bash #Setting the chroot directory mte="/restic-chroot" # enter your binary name echo -e "Please enter your binary name \n" #Reading from terminal input read binaryname # Listing all the dependencies list="$(ldd /bin/$binaryname | egrep -o '/lib.*\.[0-9]')" # Looping through the dependency list for i in $list; do cp -v --parents "$i" "${mte}"; done Dynamic Libraries in die chroot-Umgebung kopieren # für jedes Binary ausser restic ./copydependancy.sh Repo mit Bind-Mount zur Verfügung stellen mount -o bind /restic /restic-chroot/restic Testen RESTIC_PASSWORD=keineAhnung RESTIC_REPOSITORY=/restic/mein_repo chroot /restic-chroot /bin/restic --host kudell snapshots ===== Links ===== * https://restic.readthedocs.io/en/latest/ * https://www.heise.de/tests/Firmen-Backups-mit-dem-Kommandozeilen-Tools-restic-4560152.html?seite=all * https://guy-evans.com/posts/2023-03-27_backups-with-restic/ * https://braincoke.fr/blog/2020/06/your-own-backup-monitoring-system/ (healthcheck, gotify, apprise) * https://petri.com/how-to-use-restic-for-backup/ * https://it-notes.dragas.net/2020/06/30/searching-for-a-perfect-backup-solution-borg-and-restic/ * https://biqubic.com/network-trigger (um Restic auf einem Windows-Rechner zu starten) * https://forum.restic.net/t/remotely-starting-backups-on-windows-boxes/1824 und https://www.poweradmin.com/paexec/ * https://community.spiceworks.com/how_to/109517-psexec-from-linux-ubuntu * http://steronius.blogspot.com/2013/05/psexec-via-linux.html ===== TODO =====