diff --git a/docs/divers/server/index.md b/docs/divers/server/index.md index ea9d502e..95746069 100644 --- a/docs/divers/server/index.md +++ b/docs/divers/server/index.md @@ -12,4 +12,5 @@ - [Capturer le traffic réseau avec Wireshark](wireshark.md) - [Créer un certificat pour une wildcard](wildcard_certificates.md) - [Calculer les adresses d'un réseau](calculer-adresses-reseau.md) -- [Installer et gérer un VPN avec Wireguard](wireguard/) \ No newline at end of file +- [Installer et gérer un VPN avec Wireguard](wireguard/) +- [Installer un serveur de sauvegarde (Vykar)](vykar.md) \ No newline at end of file diff --git a/docs/divers/server/vykar.md b/docs/divers/server/vykar.md new file mode 100644 index 00000000..32d95211 --- /dev/null +++ b/docs/divers/server/vykar.md @@ -0,0 +1,624 @@ +# VYKAR BACKUP + ZFS + +Sauvegarde chiffrée, dédupliquée et basée sur des snapshots ZFS vers un serveur REST dédié. + +--- + +## Architecture + +``` +┌─────────────────────┐ HTTPS/TLS ┌───────────────────────────────┐ +│ serveur-prod-1 │ ──────────────────►│ backup-prod-1.example.com │ +│ │ │ vykar-server :8585 │ +│ stack: blog │ │ /var/lib/vykar/serveur-prod-1│ +│ stack: shop │ │ token: prod-1-xxxx │ +│ /etc, /opt/stacks │ │ quota: 200G │ +└─────────────────────┘ └───────────────────────────────┘ + +┌─────────────────────┐ HTTPS/TLS ┌───────────────────────────────┐ +│ serveur-prod-2 │ ──────────────────► │ backup-prod-2.example.com │ +│ │ │ vykar-server :8586 │ +│ stack: api │ │ /var/lib/vykar/serveur-prod-2│ +│ stack: monitoring │ │ token: prod-2-xxxx │ +└─────────────────────┘ │ quota: 150G │ + └───────────────────────────────┘ + +┌─────────────────────┐ HTTPS/TLS ┌──────────────────────────────┐ +│ serveur-staging │ ──────────────────► │ backup-staging.example.com │ +│ │ │ vykar-server :8587 │ +│ stack: blog-dev │ │ /var/lib/vykar/serveur-stag │ +│ stack: shop-dev │ │ token: staging-xxxx │ +└─────────────────────┘ │ quota: 50G │ + └──────────────────────────────┘ +``` + +--- + +## Serveur de destination + +### 1. Préparer les partitions ZFS + +??? example "Installer ZFS et créer les datasets" + + ```bash + # Installer ZFS + sudo apt install zfsutils-linux + + # Créer un pool sur disque dédié (ou en miroir) + sudo zpool create tank /dev/sdb + # sudo zpool create tank mirror /dev/sdb /dev/sdc + + # Créer les datasets + sudo zfs create tank/www + sudo zfs create tank/mysql + sudo zfs create tank/data + + # Définir les points de montage + sudo zfs set mountpoint=/var/www tank/www + sudo zfs set mountpoint=/var/lib/mysql tank/mysql + + # Rendre les snapshots accessibles à Vykar + sudo zfs set snapdir=visible tank/www + sudo zfs set snapdir=visible tank/mysql + sudo zfs set snapdir=visible tank/data + ``` + +--- + +### 2. Installer vykar-server + +??? example "Télécharger et installer le binaire" + + ```bash + # Télécharger le binaire (adapter la version) + wget https://github.com/borgbase/vykar/releases/download/v0.12.1/vykar-v0.12.1-x86_64-unknown-linux-gnu.tar.gz + tar xzf vykar-v0.12.1-x86_64-unknown-linux-gnu.tar.gz + sudo mv vykar-server /usr/local/bin/ + + # Créer l'utilisateur dédié + sudo useradd -r -s /usr/sbin/nologin -d /var/lib/vykar vykar + sudo mkdir -p /var/lib/vykar + sudo chown vykar:vykar /var/lib/vykar + ``` + +--- + +### 3. Configurer les tokens et répertoires + +??? example "Créer la structure et générer les tokens par serveur" + + ```bash + # Créer les répertoires par serveur + sudo mkdir -p /var/lib/vykar/serveur-prod-1 + sudo mkdir -p /var/lib/vykar/serveur-prod-2 + sudo mkdir -p /var/lib/vykar/serveur-staging + sudo chown -R vykar:vykar /var/lib/vykar/ + + # Générer un token unique par serveur + openssl rand -hex 32 # → token serveur-prod-1 + openssl rand -hex 32 # → token serveur-prod-2 + openssl rand -hex 32 # → token serveur-staging + ``` + +??? example "Fichiers d'environnement — `/etc/vykar/*.env`" + + ```bash + # /etc/vykar/serveur-prod-1.env + sudo tee /etc/vykar/serveur-prod-1.env << 'EOF' + VYKAR_TOKEN=token-prod-1-xxxxxxxxxxxxxxxx + VYKAR_PORT=8585 + VYKAR_QUOTA=200G + EOF + + # /etc/vykar/serveur-prod-2.env + sudo tee /etc/vykar/serveur-prod-2.env << 'EOF' + VYKAR_TOKEN=token-prod-2-xxxxxxxxxxxxxxxx + VYKAR_PORT=8586 + VYKAR_QUOTA=150G + EOF + + # /etc/vykar/serveur-staging.env + sudo tee /etc/vykar/serveur-staging.env << 'EOF' + VYKAR_TOKEN=token-staging-xxxxxxxxxxxxxxxx + VYKAR_PORT=8587 + VYKAR_QUOTA=50G + EOF + + sudo chmod 600 /etc/vykar/*.env + sudo chown vykar:vykar /etc/vykar/*.env + ``` + +--- + +### 4. Lancer les services systemd + +??? example "Template systemd — `/etc/systemd/system/vykar-server@.service`" + + ```ini + sudo tee /etc/systemd/system/vykar-server@.service << 'EOF' + [Unit] + Description=Vykar backup server - %i + After=network-online.target + + [Service] + Type=simple + User=vykar + Group=vykar + EnvironmentFile=/etc/vykar/%i.env + ExecStart=/usr/local/bin/vykar-server \ + --data-dir /var/lib/vykar/%i \ + --append-only \ + --quota ${VYKAR_QUOTA} + Restart=on-failure + RestartSec=5 + NoNewPrivileges=true + PrivateTmp=true + ProtectSystem=strict + ProtectHome=true + ReadWritePaths=/var/lib/vykar/%i + + [Install] + WantedBy=multi-user.target + EOF + ``` + +??? example "Activer les instances" + + ```bash + sudo systemctl daemon-reload + sudo systemctl enable --now vykar-server@serveur-prod-1 + sudo systemctl enable --now vykar-server@serveur-prod-2 + sudo systemctl enable --now vykar-server@serveur-staging + ``` + +--- + +### 5. Reverse proxy TLS + +??? example "Configuration Nginx — `/etc/nginx/sites-available/vykar`" + + ```nginx + # Serveur prod-1 + server { + listen 443 ssl http2; + server_name backup-prod-1.example.com; + + ssl_certificate /etc/letsencrypt/live/backup-prod-1.example.com/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/backup-prod-1.example.com/privkey.pem; + + client_max_body_size 600m; + proxy_request_buffering off; + proxy_read_timeout 300s; + + location / { + proxy_pass http://127.0.0.1:8585; + } + } + + # Serveur prod-2 + server { + listen 443 ssl http2; + server_name backup-prod-2.example.com; + + ssl_certificate /etc/letsencrypt/live/backup-prod-2.example.com/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/backup-prod-2.example.com/privkey.pem; + + client_max_body_size 600m; + proxy_request_buffering off; + proxy_read_timeout 300s; + + location / { + proxy_pass http://127.0.0.1:8586; + } + } + + # Serveur staging + server { + listen 443 ssl http2; + server_name backup-staging.example.com; + + ssl_certificate /etc/letsencrypt/live/backup-staging.example.com/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/backup-staging.example.com/privkey.pem; + + client_max_body_size 600m; + proxy_request_buffering off; + + location / { + proxy_pass http://127.0.0.1:8587; + } + } + ``` + +--- + +## Serveur source + +### 1. Installer Vykar + +??? example "Télécharger et installer le client" + + ```bash + wget https://github.com/borgbase/vykar/releases/download/v0.12.1/vykar-v0.12.1-x86_64-unknown-linux-gnu.tar.gz + tar xzf vykar-v0.12.1-x86_64-unknown-linux-gnu.tar.gz + sudo mv vykar /usr/local/bin/ + + # Permissions de lecture sans root complet (optionnel) + sudo setcap cap_dac_read_search+ep /usr/local/bin/vykar + ``` + +--- + +### 2. Configuration Vykar + +??? example "Fichier de configuration — `/etc/vykar/vykar.yaml`" + + ```yaml + repositories: + - label: "backup-principal" + url: "https://backup.example.com" + access_token: "votre-token-secret-long" + + encryption: + mode: "auto" + + compression: + algorithm: lz4 + + limits: + threads: 2 + nice: 19 + upload_mib_per_sec: 50 + + schedule: + enabled: true + every: "24h" # ou cron : "0 2 * * *" + + sources: + + # Fichiers web + - label: "www" + path: /var/www/.zfs/snapshot/vykar-tmp + hooks: + before: "zfs snapshot tank/www@vykar-tmp" + after: "zfs destroy tank/www@vykar-tmp" + retention: + keep_daily: 7 + keep_weekly: 4 + keep_monthly: 6 + + # Base de données MySQL (dump streamé) + - label: "mysql" + command_dumps: + - name: "all.dump" + command: "mysqldump -u root -p\"$MYSQL_ROOT_PASSWORD\" --all-databases" + retention: + keep_hourly: 12 + keep_daily: 30 + keep_weekly: 12 + keep_monthly: 12 + + # Données applicatives + - label: "data" + path: /var/data/.zfs/snapshot/vykar-tmp + hooks: + before: "zfs snapshot tank/data@vykar-tmp" + after: "zfs destroy tank/data@vykar-tmp" + retention: + keep_daily: 14 + keep_weekly: 8 + + # Configuration système + - label: "config" + path: "/etc" + retention: + keep_daily: 30 + keep_monthly: 24 + + hooks: + after_backup: | + { + echo "Serveur : $(hostname)" + echo "Date : $(date)" + echo "Statut : ✅ Succès" + echo "" + vykar list | tail -10 + } | msmtp -a "Subject: ✅ Backup OK [$(hostname)]" admin@example.com + + failed: | + { + echo "Serveur : $(hostname)" + echo "Date : $(date)" + echo "Statut : ⚠️ ÉCHEC" + echo "" + echo "Vérifiez les logs : journalctl -u vykar-backup" + } | msmtp -a "Subject: ⚠️ Backup ÉCHOUÉ [$(hostname)]" admin@example.com + ``` + +--- + +### 3. Initialisation et premier backup + +??? example "Initialiser le dépôt et lancer le premier backup" + + ```bash + # Initialiser le dépôt distant (une seule fois) + vykar init --config /etc/vykar/vykar.yaml + + # Tester le premier backup manuellement + vykar backup --config /etc/vykar/vykar.yaml + + # Vérifier les snapshots créés + vykar list --config /etc/vykar/vykar.yaml + ``` + +--- + +### 4. Automatisation via systemd + +??? example "Service — `/etc/systemd/system/vykar-backup.service`" + + ```ini + [Unit] + Description=Vykar Backup + After=network-online.target + + [Service] + Type=oneshot + ExecStart=/usr/local/bin/vykar backup --config /etc/vykar/vykar.yaml + User=root + StandardOutput=journal + StandardError=journal + ``` + +??? example "Timer — `/etc/systemd/system/vykar-backup.timer`" + + ```ini + [Unit] + Description=Vykar Backup quotidien + + [Timer] + OnCalendar=*-*-* 02:00:00 + Persistent=true + + [Install] + WantedBy=timers.target + ``` + +??? example "Activer le timer" + + ```bash + sudo systemctl enable --now vykar-backup.timer + + # Vérifier le timer + sudo systemctl list-timers vykar-backup.timer + ``` + +--- + +## Commandes utiles + +??? tip "Lister et inspecter les snapshots" + + ```bash + # Lister les snapshots + vykar list + + # Inspecter le contenu d'un snapshot + vykar snapshot list latest + vykar snapshot list a1b2c3d4 + + # Chercher un fichier dans les 7 derniers jours + vykar snapshot find --name '*.conf' --since 7d + ``` + +??? tip "Restaurer et monter" + + ```bash + # Restaurer le dernier snapshot + vykar restore latest /tmp/restauration + + # Restaurer un snapshot précis + vykar restore a1b2c3d4 /tmp/restauration + + # Monter un snapshot en lecture seule (WebDAV) + vykar mount latest /mnt/snapshot + umount /mnt/snapshot + ``` + +??? tip "Vérifier l'intégrité et libérer de l'espace" + + ```bash + # Vérifier l'intégrité du dépôt + vykar check + vykar check --verify-data # plus complet, plus long + + # Libérer l'espace manuellement + vykar prune + vykar compact + + # Santé du serveur REST + curl https://backup.example.com/health + ``` + +--- + +## Sécurité + +!!! warning "Points d'attention" + + - Vykar tourne en **root sur la source** pour lire tous les fichiers localement + - `backupuser`/`vykar` sur le serveur de destination a des **droits limités** à `/var/lib/vykar` + - Le mode **append-only** empêche toute suppression ou écrasement des données depuis le client + - Les données sont **chiffrées côté client** — le serveur ne voit que des blobs opaques + - Pensez à sauvegarder la **passphrase de chiffrement** dans un endroit sûr séparé (gestionnaire de mots de passe, coffre-fort physique) + +--- + +## Annexes + +??? example "Stack applicative à sauvegarder — `docker-compose.yml`" + + ```yaml + services: + app: + image: monapp:latest + volumes: + - app-data:/var/www/html + + postgres: + image: postgres:16 + environment: + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + volumes: + - pg-data:/var/lib/postgresql/data + + redis: + image: redis:7 + volumes: + - redis-data:/data + + volumes: + app-data: + pg-data: + redis-data: + ``` + +??? example "Configuration Vykar pour stack Docker — `vykar.yaml`" + + ```yaml + repositories: + - label: "backup-distant" + url: "https://backup.example.com" + access_token: "votre-token" + + sources: + # App — snapshot ZFS direct (fichiers statiques, cohérence non critique) + - label: "app-data" + path: /var/lib/docker/volumes/app-data/_data/.zfs/snapshot/vykar-tmp + hooks: + before: "zfs snapshot tank/docker-volumes@vykar-tmp" + after: "zfs destroy tank/docker-volumes@vykar-tmp" + retention: + keep_daily: 7 + keep_weekly: 4 + + # PostgreSQL — dump cohérent via docker exec + - label: "postgres" + command_dumps: + - name: "all.dump" + command: "docker exec postgres pg_dumpall -U postgres" + retention: + keep_hourly: 12 + keep_daily: 30 + keep_weekly: 12 + keep_monthly: 6 + + # Redis — save + lecture du fichier + - label: "redis" + command_dumps: + - name: "dump.rdb" + command: | + docker exec redis redis-cli SAVE && + docker exec redis cat /data/dump.rdb + retention: + keep_daily: 7 + keep_weekly: 4 + + hooks: + after_backup: | + { + echo "Serveur : $(hostname)" + echo "Date : $(date)" + echo "Statut : ✅ Succès" + echo "" + vykar list | tail -10 + } | msmtp -a "Subject: ✅ Backup OK [$(hostname)]" admin@example.com + + failed: | + { + echo "Serveur : $(hostname)" + echo "Date : $(date)" + echo "Statut : ⚠️ ÉCHEC" + echo "" + echo "Vérifiez les logs : journalctl -u vykar-backup" + } | msmtp -a "Subject: ⚠️ Backup ÉCHOUÉ [$(hostname)]" admin@example.com + ``` + +??? example "Configuration msmtp — `/etc/msmtprc`" + + ```bash + # Installer msmtp + sudo apt install msmtp msmtp-mta + + # Configurer /etc/msmtprc + sudo tee /etc/msmtprc << 'EOF' + defaults + auth on + tls on + tls_trust_file /etc/ssl/certs/ca-certificates.crt + logfile /var/log/msmtp.log + + account smtp-principal + host smtp.gmail.com # ou smtp.ovh.net, smtp.ionos.fr... + port 587 + from backup@example.com + user backup@example.com + password votre-mot-de-passe-app + + account default : smtp-principal + EOF + + sudo chmod 600 /etc/msmtprc + + # Test + echo "Test backup" | msmtp admin@example.com + ``` + +??? example "Restauration des données" + + ```bash + # PostgreSQL + vykar restore latest /tmp/restauration + docker exec -i mon-postgres \ + psql -U postgres < /tmp/restauration/all.dump + + # MySQL + docker exec -i mon-mysql \ + mysql -u root -p"${MYSQL_ROOT_PASSWORD}" \ + < /tmp/restauration/all.sql + + # MongoDB + cat /tmp/restauration/all.archive.gz | \ + docker exec -i mon-mongodb \ + mongorestore --archive --gzip + + # Redis + docker cp /tmp/restauration/dump.rdb mon-redis:/data/dump.rdb + docker restart mon-redis + ``` + +??? example "Déploiement Docker — `docker-compose.yml`" + + ```yaml + services: + vykar: + image: ghcr.io/borgbase/vykar:latest + hostname: my-server + restart: unless-stopped + environment: + - VYKAR_PASSPHRASE=${VYKAR_PASSPHRASE} + - TZ=UTC + volumes: + - ./vykar.yaml:/etc/vykar/config.yaml:ro + - /home/user/documents:/data/documents:ro + - ./vykar-cache:/cache + volumes: + vykar-cache: + ``` + +--- + +## Documentation + +- **Projet** : [https://github.com/borgbase/vykar](https://github.com/borgbase/vykar) +- **Documentation** : [https://vykar.borgbase.com/](https://vykar.borgbase.com/) diff --git a/mkdocs.yml b/mkdocs.yml index 27f0a105..b2474232 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -112,7 +112,7 @@ nav: - "LVM" : divers/cmd/lvm.md - "Chroot" : divers/cmd/chroot.md - "Zfs" : divers/cmd/zfs.md - - "Les tutos Admin Sys": + - "Les tutos divers": - divers/admin/index.md - "Installer Adobe pdf reader": divers/admin/acroread-debian.md - "Configurer Gnome AppFolders": divers/admin/gnome-appfolders.md @@ -138,6 +138,7 @@ nav: - Serveur: divers/server/wireguard/serveur/index.md - Clients: divers/server/wireguard/clients/index.md - Gestion & Samba: divers/server/wireguard/gestion/index.md + - "Installer un système de sauvegarde (Vykar)": divers/server/vykar.md - "Les guides DevOps": - divers/devops/index.md - "Hugo":