From 99072361c559d280f2b7d6a90dfc4a6471be6f24 Mon Sep 17 00:00:00 2001 From: Matthieu Date: Mon, 9 Mar 2026 17:20:13 +0100 Subject: [PATCH 1/5] =?UTF-8?q?docs:=20ajout=20de=20la=20revue=20de=20code?= =?UTF-8?q?=20compl=C3=A8te=20du=20d=C3=A9p=C3=B4t?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Revue couvrant les 4 scripts (backup-vaultwarden, check-storage, backup-bdd-recette, check-statut-recette) avec identification des problèmes de sécurité, qualité et suggestions d'amélioration. Co-Authored-By: Claude Opus 4.6 --- CODE_REVIEW.md | 212 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 212 insertions(+) create mode 100644 CODE_REVIEW.md diff --git a/CODE_REVIEW.md b/CODE_REVIEW.md new file mode 100644 index 0000000..33f8e74 --- /dev/null +++ b/CODE_REVIEW.md @@ -0,0 +1,212 @@ +# Code Review - Scripts Serveur (MALIO) + +**Date** : 2026-03-09 +**Reviewer** : Claude (Opus 4.6) +**Scope** : Revue complète de tout le code du dépôt + +--- + +**Note** : Le fichier `CheckStorage/.env` contient un webhook Discord en local mais n'est **pas commité** dans le dépôt (correctement ignoré par le `.gitignore`). Pas de fuite de secret. + +--- + +## 1. BackupVaultWarden/backup-vaultwarden.sh + +### Qualite globale : Bonne + +Le script est bien structuré, utilise `set -euo pipefail`, et gère correctement les erreurs. + +### Problemes + +| Severite | Ligne | Description | +|----------|-------|-------------| +| **CRITIQUE** | 8 | Chemin `.env` en dur (`/home/matt/vaultwarden/scripts/...`) au lieu d'utiliser `$SCRIPT_DIR`. Ce script ne fonctionnera **que sur la machine de matt**. | +| **HAUTE** | 80-83 | **Injection de code** dans le message Discord. La variable `$msg` est injectée directement dans du code Python via un heredoc. Si le contenu du backup contient des guillemets triples `"""` ou du code Python, il sera exécuté. | +| **MOYENNE** | 7 | `SCRIPT_DIR` est calculé mais jamais utilisé (variable morte). | +| **BASSE** | 36 | `WEBHOOK_URL` utilise `:=` (valeur par défaut vide) au lieu de `:-`. Ce n'est pas un bug mais c'est incohérent avec les autres variables qui utilisent `:?`. | + +### Suggestions + +- **Ligne 8** : Remplacer par `ENV_FILE="${SCRIPT_DIR}/.env"` comme dans les autres scripts. +- **Ligne 80-83** : Utiliser `jq` ou `python3 -c` avec passage par argument au lieu d'interpoler dans un heredoc Python : + ```bash + printf '%s' "$msg" | python3 -c 'import sys,json; print(json.dumps({"content": sys.stdin.read()}))' | curl ... + ``` +- Ajouter une rotation des backups distants (pas de purge des anciens backups actuellement). + +--- + +## 2. CheckStorage/check-storage.sh + +### Qualite globale : Faible + +Ce script est le moins mature du dépôt. Pas de `set -euo pipefail`, pas de gestion d'erreurs, et des pratiques fragiles. + +### Problemes + +| Severite | Ligne | Description | +|----------|-------|-------------| +| **HAUTE** | 1 | Pas de `set -euo pipefail`. Le script continue silencieusement en cas d'erreur. | +| **HAUTE** | 10 | Lecture du `.env` avec `grep | cut` au lieu de `source`. Fragile : ne supporte pas les valeurs avec `=`, les espaces, ou les guillemets. | +| **HAUTE** | 39-45 | **Injection JSON** : le message Discord est construit par interpolation directe dans du JSON. Si une variable contient `"` ou `\`, le JSON sera invalide ou pire. | +| **MOYENNE** | 10 | Chemin `.env` relatif sans `cd` vers le répertoire du script. Le script cassera s'il est exécuté depuis un autre répertoire (ex: via cron). | +| **MOYENNE** | 37 | Pas de notification quand tout va bien (aucun message si usage < limite). Impossible de savoir si le cron fonctionne. | +| **BASSE** | - | Pas de shebang `#!/usr/bin/env bash`, utilise `#!/bin/bash` directement (moins portable). | +| **BASSE** | - | Pas de logging dans un fichier, seulement `echo` sur stdout. | + +### Suggestions + +- Aligner sur le pattern des scripts RecetteScripts : `set -euo pipefail`, `source .env`, `SCRIPT_DIR`, gestion d'erreurs. +- Utiliser `jq` ou Python pour construire le JSON Discord de maniere sure. +- Ajouter un chemin absolu vers le `.env` base sur `$SCRIPT_DIR`. +- Ajouter un mode `--verbose` ou un log file. + +--- + +## 3. RecetteScripts/backup-bdd-recette.sh + +### Qualite globale : Tres bonne + +C'est le script le plus mature du dépôt. Bien structure, bonne gestion d'erreurs, verrou d'execution, messages Discord granulaires. + +### Problemes + +| Severite | Ligne | Description | +|----------|-------|-------------| +| **HAUTE** | 92 | `export PGPASSWORD` : le mot de passe PostgreSQL est expose dans l'environnement. Tout process fils peut le lire (visible dans `/proc/*/environ`). Preferer un fichier `.pgpass` avec permissions 600. | +| **HAUTE** | 106-107 | **Injection JSON** dans `discord_send()` : la variable `$msg` est interpolee directement dans le JSON curl. Meme probleme que les autres scripts. | +| **MOYENNE** | 223 | Les noms de dossiers distants (`ferme`, `sirh`, `inventory`, `user`) sont en dur au lieu d'etre derives de `$DBS`. Si on ajoute une base dans `.env`, le dossier distant ne sera pas cree. | +| **MOYENNE** | 237-239 | L'export des "roles" fait en realite un simple `SELECT rolname` : ca ne sauvegarde que les **noms** des roles, pas leurs privileges, mots de passe, ou attributs. Utiliser `pg_dumpall --roles-only` pour un vrai backup des roles. | +| **BASSE** | 336 | `exit 2` en fin de script en cas d'erreur partielle : c'est bien, mais pas documente dans le README. | +| **BASSE** | 85 | Le `TMP_DIR` est sous `/tmp` : sur un systeme multi-utilisateur, un autre user pourrait pre-creer le dossier (race condition / symlink attack). Utiliser `mktemp -d`. | + +### Suggestions + +- Remplacer `export PGPASSWORD` par un fichier `.pgpass`. +- Deriver les dossiers distants de `$DBS_ARRAY` au lieu de les hardcoder. +- Utiliser `pg_dumpall --roles-only` pour un vrai export des roles. +- Utiliser `mktemp -d` pour le repertoire temporaire. + +--- + +## 4. RecetteScripts/check-statut-recette.sh + +### Qualite globale : Bonne + +Script bien ecrit, bonne separation des responsabilites, gestion propre des erreurs curl. + +### Problemes + +| Severite | Ligne | Description | +|----------|-------|-------------| +| **HAUTE** | 92-94 | **Injection JSON** dans Discord (meme pattern que partout). | +| **MOYENNE** | 1 | `set -u` sans `set -e`. Les erreurs non gerees ne stopperont pas le script. C'est voulu (le script doit continuer pour checker tous les sites), mais `set -o pipefail` manque. | +| **MOYENNE** | 52 | Schema HTTP en dur (`http`). Pas de support HTTPS. Si les apps passent en HTTPS, le script retournera des redirections 301/302 au lieu de verifier le vrai endpoint. | +| **BASSE** | 134 | Le `mktemp` pour stderr n'est pas nettoye en cas d'interruption (pas de `trap`). Fuite mineure de fichiers temp. | + +### Suggestions + +- Ajouter le support HTTPS (configurable par URL dans le `.env`, ou suivre les redirections avec `-L`). +- Ajouter `set -o pipefail`. +- Nettoyer le fichier `stderr` temporaire dans un `trap`. + +--- + +## 5. Problemes transversaux + +### 5.1 Injection JSON dans les notifications Discord + +**Tous les scripts** construisent le payload JSON Discord par interpolation de chaines. C'est le probleme le plus repandu. + +**Pattern actuel (dangereux)** : +```bash +curl -d "{\"content\":\"$msg\"}" "$WEBHOOK_URL" +``` + +**Pattern corrige** : +```bash +jq -n --arg msg "$msg" '{content: $msg}' | curl -d @- ... +``` + +Ou si `jq` n'est pas disponible : +```bash +python3 -c "import sys,json; print(json.dumps({'content': sys.argv[1]}))" "$msg" | curl -d @- ... +``` + +### 5.2 Pas de rotation des sauvegardes + +Aucun script ne gere la purge des anciens backups sur le serveur distant. L'espace disque distant finira par se remplir. + +**Suggestion** : ajouter une commande SSH pour supprimer les backups de plus de N jours : +```bash +ssh "$REMOTE" "find '$REMOTE_DIR' -name '*.dump' -mtime +30 -delete" +``` + +### 5.3 Incoherence de style entre les scripts + +| Aspect | check-storage | backup-vaultwarden | backup-bdd-recette | check-statut-recette | +|--------|--------------|--------------------|--------------------|---------------------| +| `set -euo pipefail` | Non | Oui | Oui | Partiel (`set -u`) | +| Chargement .env | `grep\|cut` | `source` (chemin dur) | `source` (SCRIPT_DIR) | `source` (SCRIPT_DIR) | +| Logging | `echo` | `tee` + fichier | `tee` + fichier | `tee` + fichier | +| Gestion erreurs | Aucune | `fail()` | Granulaire | `log_line()` | +| Shebang | `#!/bin/bash` | `#!/usr/bin/env bash` | `#!/usr/bin/env bash` | `#!/usr/bin/env bash` | + +`check-storage.sh` est clairement en retard sur les conventions adoptees dans les autres scripts. + +### 5.4 README du BackupVaultWarden desynchronise + +Le README de BackupVaultWarden decrit l'ancien code (lecture `.env` avec `grep | cut`) alors que le script actuel utilise `source`. La documentation ne correspond plus au code. + +--- + +## 6. .gitignore + +### Problemes + +Le `.gitignore` est **trop complexe** et redondant. Les regles se contredisent : + +```gitignore +.env +.env.* +!.env.example +!.env.exemple +RecetteScripts/.env # redondant avec .env +CheckStorage/.env # redondant avec .env +``` + +Les regles fonctionnent correctement (les fichiers `.env` ne sont pas commites), mais la redondance rend le fichier difficile a maintenir. + +**Suggestion** : simplifier le `.gitignore` : +```gitignore +# Secrets +.env +!.env.exemple +!.env.example +``` + +--- + +## 7. Resume et priorites + +### Actions immediates (a faire maintenant) + +1. Corriger le chemin `.env` en dur dans `backup-vaultwarden.sh` (ligne 8) +2. Corriger l'injection JSON dans **tous** les scripts (utiliser `jq`) + +### Actions a court terme + +3. Remonter `check-storage.sh` au niveau des autres scripts (set -euo, source .env, SCRIPT_DIR, logging) +4. Remplacer `export PGPASSWORD` par `.pgpass` dans `backup-bdd-recette.sh` +5. Utiliser `pg_dumpall --roles-only` au lieu du simple `SELECT rolname` + +### Actions a moyen terme + +8. Ajouter la rotation des backups distants +9. Ajouter le support HTTPS dans `check-statut-recette.sh` +10. Mettre a jour le README de BackupVaultWarden +11. Simplifier le `.gitignore` + +--- + +*Revue generee par Claude (Opus 4.6) - Co-Authored-By: Claude Opus 4.6 * From f72328e0ce8316125962e1c99e7fe5bb5b95c2e6 Mon Sep 17 00:00:00 2001 From: AkiNoKure Date: Tue, 10 Mar 2026 15:54:22 +0100 Subject: [PATCH 2/5] fix : code review --- .gitignore | 15 +- BackupVaultWarden/README.md | 358 ++++++++++++++++++++---- BackupVaultWarden/backup-vaultwarden.sh | 8 +- CheckStorage/check-storage.sh | 33 ++- README.md | 2 +- RecetteScripts/.env.exemple | 8 +- RecetteScripts/backup-bdd-recette.sh | 30 +- RecetteScripts/check-statut-recette.sh | 9 +- 8 files changed, 356 insertions(+), 107 deletions(-) diff --git a/.gitignore b/.gitignore index b4b4c53..105bda5 100644 --- a/.gitignore +++ b/.gitignore @@ -2,22 +2,9 @@ # Environment / secrets ######################################## -# Fichiers .env réels (contiennent des secrets) .env -.env.* -!.env.example !.env.exemple -# Sous-dossiers -RecetteScripts/.env -CheckStorage/.env -BackupVaultWarden/.env - -# Garder les fichiers exemple -!*.env.exemple -!*.env.example -!CheckStorage/.env.exemple -!RecetteScripts/.env.exemple -!BackupVaultWarden/.env.exemple +!.env.example ######################################## # Logs diff --git a/BackupVaultWarden/README.md b/BackupVaultWarden/README.md index 9844000..5184598 100644 --- a/BackupVaultWarden/README.md +++ b/BackupVaultWarden/README.md @@ -1,54 +1,259 @@ -# FONCTIONNEMENT DU SCRIPT VAULTWARDEN -Le script de backup de vaultwarden permet une sauvegarde périodique des mots de passe et utilisateurs de celui-ci. +markdown +# README — Mise en place du script de sauvegarde Vaultwarden -## INITIALISATION DES VARIABLES DE MANIÈRE SÉCURISÉ +Ce script permet d’automatiser la sauvegarde de Vaultwarden afin de conserver une copie du dossier `data`, de la transférer vers un serveur distant et d’envoyer une notification Discord en cas de succès ou d’échec. -1. Les informations sensibles ne sont pas stockées directement dans le script. Elles sont placées dans un fichier .env +--- + +# 1. Objectif du script + +Le script de sauvegarde Vaultwarden permet de : + +- sauvegarder les données de Vaultwarden ; +- compresser l’archive avec un nom daté ; +- transférer la sauvegarde vers un serveur distant ; +- envoyer une notification Discord ; +- automatiser l’exécution via `cron`. + +Ce mécanisme permet de sécuriser les mots de passe, les utilisateurs et la configuration stockés dans le dossier `data` de Vaultwarden. + +--- + +# 2. Pré-requis + +Avant de mettre en place le script, vérifier que les éléments suivants sont disponibles sur la machine Vaultwarden : + +- `bash` +- `tar` +- `scp` +- `ssh` +- `curl` +- `cron` + +Installation sur Debian / Ubuntu : ```bash -WEBHOOK_URL=... -REMOTE_USER=... -REMOTE_HOST=... -SSH_KEY=... -DATA_DIR=... +sudo apt update +sudo apt install -y tar openssh-client curl cron +```` + +--- + +# 3. Emplacement du script + +Le script est situé dans : + +```bash +/home/matt/vaultwarden/Malio-ops/BackupVaultWarden/ ``` -2. on récupère les variables dans le script +Structure recommandée : + +```bash +/home/matt/vaultwarden/Malio-ops/BackupVaultWarden/ +├── backup-vaultwarden.sh +├── .env +└── README.md +``` + +--- + +# 4. Configuration sécurisée avec le fichier .env + +Les informations sensibles ne doivent pas être stockées directement dans le script. +Elles doivent être placées dans un fichier `.env`. + +## Exemple de fichier `.env` + +```bash +WEBHOOK_URL=https://discord.com/api/webhooks/... +REMOTE_USER=backup +REMOTE_HOST=192.168.1.50 +SSH_KEY=/home/matt/.ssh/id_ed25519_vaultwarden_backup +DATA_DIR=/opt/vaultwarden/data +REMOTE_DIR=/home/backup/backups/vaultwarden +``` + +## Description des variables + +| Variable | Description | +| ----------- | ------------------------------------------------------ | +| WEBHOOK_URL | Webhook Discord pour les notifications | +| REMOTE_USER | Utilisateur du serveur distant | +| REMOTE_HOST | Adresse IP ou DNS du serveur de sauvegarde | +| SSH_KEY | Chemin vers la clé SSH utilisée pour le transfert | +| DATA_DIR | Dossier `data` de Vaultwarden | +| REMOTE_DIR | Dossier de stockage des backups sur le serveur distant | + +--- + +# 5. Chargement des variables dans le script + +Le script récupère les variables du fichier `.env`. + +Exemple : + ```bash REMOTE_USER=$(grep -E '^REMOTE_USER=' .env | cut -d '=' -f2-) ``` -Explication: +Explication : -- grep recherche la variable dans le fichier .env -- cut récupère uniquement la valeur après = -- REMOTE_USER="user" Le script récupère >> "user" +* `grep` recherche la variable dans `.env` +* `cut` récupère uniquement la valeur après `=` +* la variable shell reçoit la valeur correspondante -Cela permet: +Cela permet : -- d’améliorer la sécurité -- d’éviter de modifier le script si un paramètre change +* d'améliorer la sécurité +* de modifier la configuration sans toucher au script -## RÉCUPÉRATION DES DONNÉES +--- + +# 6. Connexion au serveur de sauvegarde (Machine IA) + +Le transfert des sauvegardes vers la machine IA repose sur une **authentification par clé SSH**. +Cette méthode permet au script de se connecter automatiquement au serveur distant sans mot de passe. + +La clé utilisée pour ce script est : + +``` +~/.ssh/id_ed25519_bitwarden + +```` + +--- + +## 6.1 Vérifier la présence de la clé SSH + +Sur la machine exécutant le script, vérifier que la clé existe : + +```bash +ls ~/.ssh/id_ed25519_bitwarden* +```` + +Les fichiers attendus sont : + +``` +~/.ssh/id_ed25519_bitwarden +~/.ssh/id_ed25519_bitwarden.pub +``` + +* `id_ed25519_bitwarden` → clé privée utilisée par le script +* `id_ed25519_bitwarden.pub` → clé publique autorisée sur la machine IA + +--- + +## 6.2 Copier la clé publique sur la machine IA + +Envoyer la clé publique vers la machine IA : + +```bash +ssh-copy-id -i ~/.ssh/id_ed25519_bitwarden.pub backup@192.168.0.179 +``` + +Cette commande ajoute automatiquement la clé dans : + +``` +~/.ssh/authorized_keys +``` + +sur la machine IA. + +--- + +## 6.3 Ajout manuel de la clé (si ssh-copy-id n'est pas disponible) + +Afficher la clé publique : + +```bash +cat ~/.ssh/id_ed25519_bitwarden.pub +``` + +Copier son contenu puis l’ajouter sur la machine IA dans : + +``` +~/.ssh/authorized_keys +``` + +--- + +## 6.4 Vérifier les permissions SSH + +Sur la machine locale : + +```bash +chmod 700 ~/.ssh +chmod 600 ~/.ssh/id_ed25519_bitwarden +chmod 644 ~/.ssh/id_ed25519_bitwarden.pub +``` + +Sur la machine IA : + +```bash +chmod 700 ~/.ssh +chmod 600 ~/.ssh/authorized_keys +``` + +--- + +## 6.5 Tester la connexion + +Tester la connexion SSH avec la clé : + +```bash +ssh -i ~/.ssh/id_ed25519_bitwarden backup@192.168.0.179 +``` + +Si la configuration est correcte : + +* la connexion se fait **sans mot de passe** +* la machine IA accepte la clé SSH +* le script pourra envoyer les sauvegardes automatiquement + +--- + +## 6.6 Déclaration dans le fichier `.env` + +La clé utilisée par le script doit être déclarée dans `.env` : + +```bash +SSH_KEY=/home/matt/.ssh/id_ed25519_bitwarden +``` + +Cette clé sera utilisée automatiquement par `scp` lors du transfert des sauvegardes. + + +# 7. Sauvegarde des données Vaultwarden + +Le script crée une archive compressée du dossier `data` : -1. Le dossier data de Vaultwarden est dupliqué puis compressé afin de créer une archive : ```bash tar -czf "$LOCAL_BACKUP" -C "$(dirname "$DATA_DIR")" "$(basename "$DATA_DIR")" ``` -2. Transfer vers le serveur de backup +Cela permet d’obtenir une sauvegarde portable et compressée. + +--- + +# 8. Transfert vers le serveur distant + +Une fois l’archive créée : + ```bash scp "${SSH_OPTS[@]}" "$LOCAL_BACKUP" "$REMOTE_USER@$REMOTE_HOST:$REMOTE_DIR/" ``` -La sauvegarde est envoyée vers une machine dédiée grâce à SCP. Pour éviter de saisir un mot de passe à chaque fois, une clé SSH est utilisée. -Cette clé SSH est générée sur la machine de backup et autorisée sur la machine Vaultwarden. +Le fichier est envoyé vers le serveur de sauvegarde via SCP. -## NOTIFICATION DISCORD +--- -Le script envoie une notification sur un salon Discord pour informer de l’état de la sauvegarde. Cela se fait grâce à un webhook Discord. +# 9. Notification Discord + +Le script envoie une notification Discord pour informer de l’état de la sauvegarde. + +Construction du message : -1. on défini le message ```bash local msg="**@here Backup Vaultwarden $color**\n" msg+="Backup: ${BACKUP_NAME}\n" @@ -56,61 +261,96 @@ msg+="Data transfer: $dumps_display\n" [[ -n "$details" ]] && msg+="Details: $details" ``` -2. on envoie le message sur discord avec le message et le webhook +Envoi du message : + ```bash curl -fsS -H "Content-Type: application/json" \ -d "{\"content\":\"$msg\"}" \ -"$DISCORD_WEBHOOK_URL" +"$WEBHOOK_URL" ``` -Le message indique: -- si la sauvegarde a réussi 🟢 -- si elle a échoué 🔴 -- le nom du backup -- les détails de l’erreur si nécessaire +Le message indique : -## PLANIFICATION AVEC CRON +* si la sauvegarde a réussi +* si elle a échoué +* le nom du backup +* les détails de l’erreur -Le script est exécuté automatiquement chaque jour grâce à cron. +--- + +# 10. Planification avec cron + +Le script est exécuté automatiquement tous les jours à 19h. + +Ouvrir le crontab : -1. Ouvrez le crontab pour l'édition : - ```bash - crontab -e - ``` -2. Ajoutez la ligne suivante pour exécuter le script tous les jours à 19h : ```bash - 0 19 * * * /chemin/vers/le/script/check_storage.sh +crontab -e ``` -Signification: +Ajouter : -- 0 minute 0 -- 19 19h -- * tous les jours du mois -- * tous les mois -- * tous les jours de la semaine +```bash +0 19 * * * /home/matt/vaultwarden/Malio-ops/BackupVaultWarden/backup-vaultwarden.sh >> /var/log/vaultwarden_backup.log 2>&1 +``` -Tous les jours à 19h, le script est exécuté et les logs sont enregistrés dans backup.log ce qui permet d’analyser les erreurs si un problème survient. +Signification : -## NETTOYAGE +| Champ | Valeur | +| ------------ | ------ | +| minute | 0 | +| heure | 19 | +| jour du mois | * | +| mois | * | +| jour semaine | * | -Une fois la sauvegarde envoyée sur la machine distante, le fichier temporaire est supprimé : +Le script s’exécute donc **tous les jours à 19h00**. + +--- + +# 11. Nettoyage + +Une fois la sauvegarde transférée : ```bash rm -f "$LOCAL_BACKUP" ``` -Cela permet de garder le serveur propre et éviter de remplir le disque. +Cela évite de remplir le disque de la machine Vaultwarden. -## RÉSUMÉ +--- -Le script automatise complètement les sauvegardes Vaultwarden : +# 12. Test manuel -- sauvegarde du dossier data -- compression et datation -- transfert sécurisé via SSH -- notification Discord -- exécution automatique avec cron -- sécurisation des paramètres via .env +Avant de mettre le script en cron, tester : -Cela permet d’avoir une sauvegarde quotidienne fiable et surveillée. +```bash +bash /home/matt/vaultwarden/Malio-ops/BackupVaultWarden/backup-vaultwarden.sh +``` + +--- + +# 13. Vérification des logs + +Logs : + +```bash +cat /var/log/vaultwarden_backup.log +``` + +--- + +# 14. Résumé + +Le script automatise : + +* la sauvegarde du dossier `data` +* la compression et la datation du backup +* le transfert sécurisé via SSH +* la notification Discord +* l’exécution automatique via cron +* la configuration sécurisée via `.env` + +Ce système permet d’obtenir **une sauvegarde fiable, centralisée et surveillée de Vaultwarden**. + +``` diff --git a/BackupVaultWarden/backup-vaultwarden.sh b/BackupVaultWarden/backup-vaultwarden.sh index 21e8de5..8947f9b 100644 --- a/BackupVaultWarden/backup-vaultwarden.sh +++ b/BackupVaultWarden/backup-vaultwarden.sh @@ -5,7 +5,7 @@ set -euo pipefail # Chemins fixes du script ####################################### SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -ENV_FILE="/home/matt/vaultwarden/scripts/Scripts-Serveur/backup_vaultwarden/.env" +ENV_FILE="/home/matt/vaultwarden/Malio-ops/BackupVaultWarden/.env" LOG_FILE="/var/log/vaultwarden_backup.log" mkdir -p "$(dirname "$LOG_FILE")" @@ -68,13 +68,15 @@ discord_ping() { if [[ "$success" == "true" ]]; then icon="🟢" status_line="✅" + ping="" else icon="🔴" status_line="❌" + ping="@here " fi local msg - msg="**@here ${icon} Backup Vaultwarden**\n" + msg="**${ping}Backup Vaultwarden ${icon}**\n" msg+="Backup: ${BACKUP_NAME}\n" msg+="Data transfer: ${status_line}\n" [[ -n "$details" ]] && msg+="Détails: ${details}" @@ -147,4 +149,4 @@ rm -f "$LOCAL_BACKUP_FILE" || fail "Impossible de supprimer le backup local $LOC ####################################### log "Backup $BACKUP_NAME terminé et envoyé sur $REMOTE_HOST:$REMOTE_DIR" discord_ping "true" "Backup envoyé avec succès vers $REMOTE_HOST" -echo "Backup $BACKUP_NAME terminé et envoyé sur $REMOTE_HOST:$REMOTE_DIR" +echo "Backup $BACKUP_NAME terminé et envoyé sur $REMOTE_HOST:$REMOTE_DIR" \ No newline at end of file diff --git a/CheckStorage/check-storage.sh b/CheckStorage/check-storage.sh index 20b1c5a..8f6326f 100644 --- a/CheckStorage/check-storage.sh +++ b/CheckStorage/check-storage.sh @@ -1,4 +1,23 @@ #!/bin/bash +set -euo pipefail + +############################################################################### +# CHARGEMENT DU .env +############################################################################### + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +ENV_FILE="${SCRIPT_DIR}/.env" + +if [[ ! -f "$ENV_FILE" ]]; then + echo "ERROR: fichier .env introuvable : $ENV_FILE" >&2 + exit 1 +fi + +set -a +# shellcheck disable=SC1090 +source "$ENV_FILE" +set +a + ############################################################################### # CONFIGURATION ############################################################################### @@ -6,14 +25,10 @@ # Limite maximale d'utilisation du disque en pourcentage limit=70 -# Récupération du webhook Discord depuis le fichier .env -WEBHOOK_URL=$(grep -E '^WEBHOOK_URL=' .env | cut -d '=' -f2-) - ############################################################################### # RÉCUPÉRATION DES INFORMATIONS DISQUE ############################################################################### -# extraction des informations read -r total_bytes used_bytes avail_bytes usage <<<"$(df -B1 / | awk 'NR==2 {gsub(/%/,"",$5); print $2, $3, $4, $5}')" # Calcul du pourcentage d'espace libre @@ -23,25 +38,24 @@ free=$((100 - usage)) # CONVERSION EN GIGAOCTETS ############################################################################### -# Conversion bytes → gigaoctets pour un affichage plus lisible used_gb=$(awk -v b="$used_bytes" 'BEGIN {printf "%.2f", b/1024/1024/1024}') total_gb=$(awk -v b="$total_bytes" 'BEGIN {printf "%.2f", b/1024/1024/1024}') avail_gb=$(awk -v b="$avail_bytes" 'BEGIN {printf "%.2f", b/1024/1024/1024}') - ############################################################################### # VÉRIFICATION DU SEUIL D'UTILISATION ############################################################################### -# Si l'utilisation dépasse la limite définie, une alerte est envoyée sur Discord if [ "$usage" -ge "$limit" ]; then msgLimit="@here\n**CHECK STOCKAGE :red_circle:**\nLimite autorisé : ${limit}%\nUtilisation actuelle: ${usage}%\nEspace restant: ${free}%\nUtilise / total: ${used_gb} GB / ${total_gb} GB\nDisponible: ${avail_gb} GB\nHeure: $(date)" + payload="$(jq -n --arg content "$msgLimit" '{content: $content}')" + curl -X POST \ -H "Accept: application/json" \ -H "Content-Type: application/json; charset=utf-8" \ - -d "{\"content\":\"$msgLimit\"}" \ + -d "$payload" \ "$WEBHOOK_URL" fi @@ -50,9 +64,6 @@ fi # AFFICHAGE DES INFORMATIONS STOCKAGE ############################################################################### -# Affichage des informations disque dans la console echo "Espace disponible : ${avail_gb} GB" echo "Espace utilise / espace total : ${used_gb} GB / ${total_gb} GB" - -# Nom de la machine exécutant le script echo "Name: ${HOSTNAME}" \ No newline at end of file diff --git a/README.md b/README.md index 5e9853d..cac788c 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Scripts Serveur MALIO +# Malio-Ops MALIO Ce dépôt sert au **versionnement des scripts utilisés dans l’infrastructure du projet Ferme**. L’objectif est de conserver un historique clair des scripts, suivre les évolutions et permettre leur amélioration progressive. diff --git a/RecetteScripts/.env.exemple b/RecetteScripts/.env.exemple index 7f1218a..c0ca24f 100644 --- a/RecetteScripts/.env.exemple +++ b/RecetteScripts/.env.exemple @@ -16,7 +16,7 @@ PGHOST=localhost PGPORT=5432 # Utilisateur utilisé pour les dumps -PGUSER=backup_user +PGUSER=nom_de_user # Mot de passe PostgreSQL PGPASSWORD=change_me_secure_password @@ -29,20 +29,20 @@ DBS="sirh inventory ferme" ############################################# # Utilisateur du serveur distant -BACKUP_REMOTE_USER=backup +BACKUP_REMOTE_USER=nom_de_user # Host ou IP du serveur distant BACKUP_REMOTE_HOST=192.168.1.50 # Dossier distant pour stocker les backups -BACKUP_REMOTE_DIR=/home/backup/backups +BACKUP_REMOTE_DIR=/home/nom_de_user/backups/bdd-recette ############################################# # SSH ############################################# # Clé SSH utilisée pour envoyer les dumps -SSH_KEY=/home/backup/.ssh/id_ed25519_backup +SSH_KEY=/home/nom_de_user/.ssh/id_ed25519_backup # Timeout SSH (secondes) SSH_TIMEOUT=10 diff --git a/RecetteScripts/backup-bdd-recette.sh b/RecetteScripts/backup-bdd-recette.sh index c242f05..03a1a15 100644 --- a/RecetteScripts/backup-bdd-recette.sh +++ b/RecetteScripts/backup-bdd-recette.sh @@ -10,14 +10,15 @@ set -euo pipefail # # Fonctionnement global : # 1. charge la configuration depuis le fichier .env ; -# 2. prépare les chemins, logs et variables de connexion ; -# 3. empêche l’exécution simultanée grâce à un verrou ; -# 4. crée les dossiers de destination sur la machine distante ; -# 5. exporte les rôles PostgreSQL ; -# 6. dump chaque base au format personnalisé PostgreSQL ; -# 7. transfère chaque fichier vers le serveur distant ; -# 8. applique une rotation distante sur 10 jours ; -# 9. envoie un bilan sur Discord : +# 2. vérifie les dépendances nécessaires ; +# 3. prépare les chemins, logs et variables de connexion ; +# 4. empêche l’exécution simultanée grâce à un verrou ; +# 5. crée les dossiers de destination sur la machine distante ; +# 6. exporte les rôles PostgreSQL ; +# 7. dump chaque base au format personnalisé PostgreSQL ; +# 8. transfère chaque fichier vers le serveur distant ; +# 9. applique une rotation distante sur 10 jours ; +# 10. envoie un bilan sur Discord : # - 1 message global si tout est OK ; # - en cas d’erreur partielle : # * USERS OK -> message simple ; @@ -102,10 +103,17 @@ DISCORD_PING="${DISCORD_PING:-@here}" discord_send() { local msg="$1" - [[ -z "${DISCORD_WEBHOOK_URL:-}" ]] && return + [[ -z "${DISCORD_WEBHOOK_URL:-}" ]] && return 0 - curl -fsS -H "Content-Type: application/json" \ - -d "{\"content\":\"$msg\"}" \ + local payload + payload="$(jq -n --arg content "$msg" '{content: $content}')" || { + log "ERROR: impossible de construire le payload JSON Discord" + return 1 + } + + curl -fsS \ + -H "Content-Type: application/json" \ + -d "$payload" \ "$DISCORD_WEBHOOK_URL" >/dev/null || true } diff --git a/RecetteScripts/check-statut-recette.sh b/RecetteScripts/check-statut-recette.sh index 2eae821..380a30f 100644 --- a/RecetteScripts/check-statut-recette.sh +++ b/RecetteScripts/check-statut-recette.sh @@ -1,5 +1,5 @@ #!/usr/bin/env bash -set -u +set -uo pipefail ############################################################################### # check-statut-recette.sh @@ -89,8 +89,11 @@ discord_ping() { msg+="Application: ${site}\n" msg+="Details: ${detail}" + local payload + payload="$(jq -n --arg content "$msg" '{content: $content}')" + curl -fsS -H "Content-Type: application/json" \ - -d "{\"content\":\"$msg\"}" \ + -d "$payload" \ "$DISCORD_WEBHOOK_URL" >/dev/null || true } @@ -99,11 +102,9 @@ discord_ping() { ####################################### log_line() { - # 2026-03-04 14:12:33 | LEVEL | site | message printf "%s | %s | %s | %s\n" \ "$(date +'%Y-%m-%d %H:%M:%S')" "$1" "$2" "$3" | tee -a "$LOG_FILE" - # Envoi Discord par application discord_ping "$2" "$1" "$3" } From c257270982533d012601f381ad4bef922240df4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matt=C3=A9o=20Dunoyer?= Date: Tue, 10 Mar 2026 15:14:25 +0000 Subject: [PATCH 3/5] Actualiser CODE_REVIEW.md --- CODE_REVIEW.md | 211 ------------------------------------------------- 1 file changed, 211 deletions(-) diff --git a/CODE_REVIEW.md b/CODE_REVIEW.md index 33f8e74..8b13789 100644 --- a/CODE_REVIEW.md +++ b/CODE_REVIEW.md @@ -1,212 +1 @@ -# Code Review - Scripts Serveur (MALIO) -**Date** : 2026-03-09 -**Reviewer** : Claude (Opus 4.6) -**Scope** : Revue complète de tout le code du dépôt - ---- - -**Note** : Le fichier `CheckStorage/.env` contient un webhook Discord en local mais n'est **pas commité** dans le dépôt (correctement ignoré par le `.gitignore`). Pas de fuite de secret. - ---- - -## 1. BackupVaultWarden/backup-vaultwarden.sh - -### Qualite globale : Bonne - -Le script est bien structuré, utilise `set -euo pipefail`, et gère correctement les erreurs. - -### Problemes - -| Severite | Ligne | Description | -|----------|-------|-------------| -| **CRITIQUE** | 8 | Chemin `.env` en dur (`/home/matt/vaultwarden/scripts/...`) au lieu d'utiliser `$SCRIPT_DIR`. Ce script ne fonctionnera **que sur la machine de matt**. | -| **HAUTE** | 80-83 | **Injection de code** dans le message Discord. La variable `$msg` est injectée directement dans du code Python via un heredoc. Si le contenu du backup contient des guillemets triples `"""` ou du code Python, il sera exécuté. | -| **MOYENNE** | 7 | `SCRIPT_DIR` est calculé mais jamais utilisé (variable morte). | -| **BASSE** | 36 | `WEBHOOK_URL` utilise `:=` (valeur par défaut vide) au lieu de `:-`. Ce n'est pas un bug mais c'est incohérent avec les autres variables qui utilisent `:?`. | - -### Suggestions - -- **Ligne 8** : Remplacer par `ENV_FILE="${SCRIPT_DIR}/.env"` comme dans les autres scripts. -- **Ligne 80-83** : Utiliser `jq` ou `python3 -c` avec passage par argument au lieu d'interpoler dans un heredoc Python : - ```bash - printf '%s' "$msg" | python3 -c 'import sys,json; print(json.dumps({"content": sys.stdin.read()}))' | curl ... - ``` -- Ajouter une rotation des backups distants (pas de purge des anciens backups actuellement). - ---- - -## 2. CheckStorage/check-storage.sh - -### Qualite globale : Faible - -Ce script est le moins mature du dépôt. Pas de `set -euo pipefail`, pas de gestion d'erreurs, et des pratiques fragiles. - -### Problemes - -| Severite | Ligne | Description | -|----------|-------|-------------| -| **HAUTE** | 1 | Pas de `set -euo pipefail`. Le script continue silencieusement en cas d'erreur. | -| **HAUTE** | 10 | Lecture du `.env` avec `grep | cut` au lieu de `source`. Fragile : ne supporte pas les valeurs avec `=`, les espaces, ou les guillemets. | -| **HAUTE** | 39-45 | **Injection JSON** : le message Discord est construit par interpolation directe dans du JSON. Si une variable contient `"` ou `\`, le JSON sera invalide ou pire. | -| **MOYENNE** | 10 | Chemin `.env` relatif sans `cd` vers le répertoire du script. Le script cassera s'il est exécuté depuis un autre répertoire (ex: via cron). | -| **MOYENNE** | 37 | Pas de notification quand tout va bien (aucun message si usage < limite). Impossible de savoir si le cron fonctionne. | -| **BASSE** | - | Pas de shebang `#!/usr/bin/env bash`, utilise `#!/bin/bash` directement (moins portable). | -| **BASSE** | - | Pas de logging dans un fichier, seulement `echo` sur stdout. | - -### Suggestions - -- Aligner sur le pattern des scripts RecetteScripts : `set -euo pipefail`, `source .env`, `SCRIPT_DIR`, gestion d'erreurs. -- Utiliser `jq` ou Python pour construire le JSON Discord de maniere sure. -- Ajouter un chemin absolu vers le `.env` base sur `$SCRIPT_DIR`. -- Ajouter un mode `--verbose` ou un log file. - ---- - -## 3. RecetteScripts/backup-bdd-recette.sh - -### Qualite globale : Tres bonne - -C'est le script le plus mature du dépôt. Bien structure, bonne gestion d'erreurs, verrou d'execution, messages Discord granulaires. - -### Problemes - -| Severite | Ligne | Description | -|----------|-------|-------------| -| **HAUTE** | 92 | `export PGPASSWORD` : le mot de passe PostgreSQL est expose dans l'environnement. Tout process fils peut le lire (visible dans `/proc/*/environ`). Preferer un fichier `.pgpass` avec permissions 600. | -| **HAUTE** | 106-107 | **Injection JSON** dans `discord_send()` : la variable `$msg` est interpolee directement dans le JSON curl. Meme probleme que les autres scripts. | -| **MOYENNE** | 223 | Les noms de dossiers distants (`ferme`, `sirh`, `inventory`, `user`) sont en dur au lieu d'etre derives de `$DBS`. Si on ajoute une base dans `.env`, le dossier distant ne sera pas cree. | -| **MOYENNE** | 237-239 | L'export des "roles" fait en realite un simple `SELECT rolname` : ca ne sauvegarde que les **noms** des roles, pas leurs privileges, mots de passe, ou attributs. Utiliser `pg_dumpall --roles-only` pour un vrai backup des roles. | -| **BASSE** | 336 | `exit 2` en fin de script en cas d'erreur partielle : c'est bien, mais pas documente dans le README. | -| **BASSE** | 85 | Le `TMP_DIR` est sous `/tmp` : sur un systeme multi-utilisateur, un autre user pourrait pre-creer le dossier (race condition / symlink attack). Utiliser `mktemp -d`. | - -### Suggestions - -- Remplacer `export PGPASSWORD` par un fichier `.pgpass`. -- Deriver les dossiers distants de `$DBS_ARRAY` au lieu de les hardcoder. -- Utiliser `pg_dumpall --roles-only` pour un vrai export des roles. -- Utiliser `mktemp -d` pour le repertoire temporaire. - ---- - -## 4. RecetteScripts/check-statut-recette.sh - -### Qualite globale : Bonne - -Script bien ecrit, bonne separation des responsabilites, gestion propre des erreurs curl. - -### Problemes - -| Severite | Ligne | Description | -|----------|-------|-------------| -| **HAUTE** | 92-94 | **Injection JSON** dans Discord (meme pattern que partout). | -| **MOYENNE** | 1 | `set -u` sans `set -e`. Les erreurs non gerees ne stopperont pas le script. C'est voulu (le script doit continuer pour checker tous les sites), mais `set -o pipefail` manque. | -| **MOYENNE** | 52 | Schema HTTP en dur (`http`). Pas de support HTTPS. Si les apps passent en HTTPS, le script retournera des redirections 301/302 au lieu de verifier le vrai endpoint. | -| **BASSE** | 134 | Le `mktemp` pour stderr n'est pas nettoye en cas d'interruption (pas de `trap`). Fuite mineure de fichiers temp. | - -### Suggestions - -- Ajouter le support HTTPS (configurable par URL dans le `.env`, ou suivre les redirections avec `-L`). -- Ajouter `set -o pipefail`. -- Nettoyer le fichier `stderr` temporaire dans un `trap`. - ---- - -## 5. Problemes transversaux - -### 5.1 Injection JSON dans les notifications Discord - -**Tous les scripts** construisent le payload JSON Discord par interpolation de chaines. C'est le probleme le plus repandu. - -**Pattern actuel (dangereux)** : -```bash -curl -d "{\"content\":\"$msg\"}" "$WEBHOOK_URL" -``` - -**Pattern corrige** : -```bash -jq -n --arg msg "$msg" '{content: $msg}' | curl -d @- ... -``` - -Ou si `jq` n'est pas disponible : -```bash -python3 -c "import sys,json; print(json.dumps({'content': sys.argv[1]}))" "$msg" | curl -d @- ... -``` - -### 5.2 Pas de rotation des sauvegardes - -Aucun script ne gere la purge des anciens backups sur le serveur distant. L'espace disque distant finira par se remplir. - -**Suggestion** : ajouter une commande SSH pour supprimer les backups de plus de N jours : -```bash -ssh "$REMOTE" "find '$REMOTE_DIR' -name '*.dump' -mtime +30 -delete" -``` - -### 5.3 Incoherence de style entre les scripts - -| Aspect | check-storage | backup-vaultwarden | backup-bdd-recette | check-statut-recette | -|--------|--------------|--------------------|--------------------|---------------------| -| `set -euo pipefail` | Non | Oui | Oui | Partiel (`set -u`) | -| Chargement .env | `grep\|cut` | `source` (chemin dur) | `source` (SCRIPT_DIR) | `source` (SCRIPT_DIR) | -| Logging | `echo` | `tee` + fichier | `tee` + fichier | `tee` + fichier | -| Gestion erreurs | Aucune | `fail()` | Granulaire | `log_line()` | -| Shebang | `#!/bin/bash` | `#!/usr/bin/env bash` | `#!/usr/bin/env bash` | `#!/usr/bin/env bash` | - -`check-storage.sh` est clairement en retard sur les conventions adoptees dans les autres scripts. - -### 5.4 README du BackupVaultWarden desynchronise - -Le README de BackupVaultWarden decrit l'ancien code (lecture `.env` avec `grep | cut`) alors que le script actuel utilise `source`. La documentation ne correspond plus au code. - ---- - -## 6. .gitignore - -### Problemes - -Le `.gitignore` est **trop complexe** et redondant. Les regles se contredisent : - -```gitignore -.env -.env.* -!.env.example -!.env.exemple -RecetteScripts/.env # redondant avec .env -CheckStorage/.env # redondant avec .env -``` - -Les regles fonctionnent correctement (les fichiers `.env` ne sont pas commites), mais la redondance rend le fichier difficile a maintenir. - -**Suggestion** : simplifier le `.gitignore` : -```gitignore -# Secrets -.env -!.env.exemple -!.env.example -``` - ---- - -## 7. Resume et priorites - -### Actions immediates (a faire maintenant) - -1. Corriger le chemin `.env` en dur dans `backup-vaultwarden.sh` (ligne 8) -2. Corriger l'injection JSON dans **tous** les scripts (utiliser `jq`) - -### Actions a court terme - -3. Remonter `check-storage.sh` au niveau des autres scripts (set -euo, source .env, SCRIPT_DIR, logging) -4. Remplacer `export PGPASSWORD` par `.pgpass` dans `backup-bdd-recette.sh` -5. Utiliser `pg_dumpall --roles-only` au lieu du simple `SELECT rolname` - -### Actions a moyen terme - -8. Ajouter la rotation des backups distants -9. Ajouter le support HTTPS dans `check-statut-recette.sh` -10. Mettre a jour le README de BackupVaultWarden -11. Simplifier le `.gitignore` - ---- - -*Revue generee par Claude (Opus 4.6) - Co-Authored-By: Claude Opus 4.6 * From 049574ffebfec14f86bf551bf1e08f525f25ac8c Mon Sep 17 00:00:00 2001 From: AkiNoKure Date: Tue, 10 Mar 2026 16:15:21 +0100 Subject: [PATCH 4/5] fix : code review --- CODE_REVIEW.md | 212 ------------------------------------------------- 1 file changed, 212 deletions(-) delete mode 100644 CODE_REVIEW.md diff --git a/CODE_REVIEW.md b/CODE_REVIEW.md deleted file mode 100644 index 33f8e74..0000000 --- a/CODE_REVIEW.md +++ /dev/null @@ -1,212 +0,0 @@ -# Code Review - Scripts Serveur (MALIO) - -**Date** : 2026-03-09 -**Reviewer** : Claude (Opus 4.6) -**Scope** : Revue complète de tout le code du dépôt - ---- - -**Note** : Le fichier `CheckStorage/.env` contient un webhook Discord en local mais n'est **pas commité** dans le dépôt (correctement ignoré par le `.gitignore`). Pas de fuite de secret. - ---- - -## 1. BackupVaultWarden/backup-vaultwarden.sh - -### Qualite globale : Bonne - -Le script est bien structuré, utilise `set -euo pipefail`, et gère correctement les erreurs. - -### Problemes - -| Severite | Ligne | Description | -|----------|-------|-------------| -| **CRITIQUE** | 8 | Chemin `.env` en dur (`/home/matt/vaultwarden/scripts/...`) au lieu d'utiliser `$SCRIPT_DIR`. Ce script ne fonctionnera **que sur la machine de matt**. | -| **HAUTE** | 80-83 | **Injection de code** dans le message Discord. La variable `$msg` est injectée directement dans du code Python via un heredoc. Si le contenu du backup contient des guillemets triples `"""` ou du code Python, il sera exécuté. | -| **MOYENNE** | 7 | `SCRIPT_DIR` est calculé mais jamais utilisé (variable morte). | -| **BASSE** | 36 | `WEBHOOK_URL` utilise `:=` (valeur par défaut vide) au lieu de `:-`. Ce n'est pas un bug mais c'est incohérent avec les autres variables qui utilisent `:?`. | - -### Suggestions - -- **Ligne 8** : Remplacer par `ENV_FILE="${SCRIPT_DIR}/.env"` comme dans les autres scripts. -- **Ligne 80-83** : Utiliser `jq` ou `python3 -c` avec passage par argument au lieu d'interpoler dans un heredoc Python : - ```bash - printf '%s' "$msg" | python3 -c 'import sys,json; print(json.dumps({"content": sys.stdin.read()}))' | curl ... - ``` -- Ajouter une rotation des backups distants (pas de purge des anciens backups actuellement). - ---- - -## 2. CheckStorage/check-storage.sh - -### Qualite globale : Faible - -Ce script est le moins mature du dépôt. Pas de `set -euo pipefail`, pas de gestion d'erreurs, et des pratiques fragiles. - -### Problemes - -| Severite | Ligne | Description | -|----------|-------|-------------| -| **HAUTE** | 1 | Pas de `set -euo pipefail`. Le script continue silencieusement en cas d'erreur. | -| **HAUTE** | 10 | Lecture du `.env` avec `grep | cut` au lieu de `source`. Fragile : ne supporte pas les valeurs avec `=`, les espaces, ou les guillemets. | -| **HAUTE** | 39-45 | **Injection JSON** : le message Discord est construit par interpolation directe dans du JSON. Si une variable contient `"` ou `\`, le JSON sera invalide ou pire. | -| **MOYENNE** | 10 | Chemin `.env` relatif sans `cd` vers le répertoire du script. Le script cassera s'il est exécuté depuis un autre répertoire (ex: via cron). | -| **MOYENNE** | 37 | Pas de notification quand tout va bien (aucun message si usage < limite). Impossible de savoir si le cron fonctionne. | -| **BASSE** | - | Pas de shebang `#!/usr/bin/env bash`, utilise `#!/bin/bash` directement (moins portable). | -| **BASSE** | - | Pas de logging dans un fichier, seulement `echo` sur stdout. | - -### Suggestions - -- Aligner sur le pattern des scripts RecetteScripts : `set -euo pipefail`, `source .env`, `SCRIPT_DIR`, gestion d'erreurs. -- Utiliser `jq` ou Python pour construire le JSON Discord de maniere sure. -- Ajouter un chemin absolu vers le `.env` base sur `$SCRIPT_DIR`. -- Ajouter un mode `--verbose` ou un log file. - ---- - -## 3. RecetteScripts/backup-bdd-recette.sh - -### Qualite globale : Tres bonne - -C'est le script le plus mature du dépôt. Bien structure, bonne gestion d'erreurs, verrou d'execution, messages Discord granulaires. - -### Problemes - -| Severite | Ligne | Description | -|----------|-------|-------------| -| **HAUTE** | 92 | `export PGPASSWORD` : le mot de passe PostgreSQL est expose dans l'environnement. Tout process fils peut le lire (visible dans `/proc/*/environ`). Preferer un fichier `.pgpass` avec permissions 600. | -| **HAUTE** | 106-107 | **Injection JSON** dans `discord_send()` : la variable `$msg` est interpolee directement dans le JSON curl. Meme probleme que les autres scripts. | -| **MOYENNE** | 223 | Les noms de dossiers distants (`ferme`, `sirh`, `inventory`, `user`) sont en dur au lieu d'etre derives de `$DBS`. Si on ajoute une base dans `.env`, le dossier distant ne sera pas cree. | -| **MOYENNE** | 237-239 | L'export des "roles" fait en realite un simple `SELECT rolname` : ca ne sauvegarde que les **noms** des roles, pas leurs privileges, mots de passe, ou attributs. Utiliser `pg_dumpall --roles-only` pour un vrai backup des roles. | -| **BASSE** | 336 | `exit 2` en fin de script en cas d'erreur partielle : c'est bien, mais pas documente dans le README. | -| **BASSE** | 85 | Le `TMP_DIR` est sous `/tmp` : sur un systeme multi-utilisateur, un autre user pourrait pre-creer le dossier (race condition / symlink attack). Utiliser `mktemp -d`. | - -### Suggestions - -- Remplacer `export PGPASSWORD` par un fichier `.pgpass`. -- Deriver les dossiers distants de `$DBS_ARRAY` au lieu de les hardcoder. -- Utiliser `pg_dumpall --roles-only` pour un vrai export des roles. -- Utiliser `mktemp -d` pour le repertoire temporaire. - ---- - -## 4. RecetteScripts/check-statut-recette.sh - -### Qualite globale : Bonne - -Script bien ecrit, bonne separation des responsabilites, gestion propre des erreurs curl. - -### Problemes - -| Severite | Ligne | Description | -|----------|-------|-------------| -| **HAUTE** | 92-94 | **Injection JSON** dans Discord (meme pattern que partout). | -| **MOYENNE** | 1 | `set -u` sans `set -e`. Les erreurs non gerees ne stopperont pas le script. C'est voulu (le script doit continuer pour checker tous les sites), mais `set -o pipefail` manque. | -| **MOYENNE** | 52 | Schema HTTP en dur (`http`). Pas de support HTTPS. Si les apps passent en HTTPS, le script retournera des redirections 301/302 au lieu de verifier le vrai endpoint. | -| **BASSE** | 134 | Le `mktemp` pour stderr n'est pas nettoye en cas d'interruption (pas de `trap`). Fuite mineure de fichiers temp. | - -### Suggestions - -- Ajouter le support HTTPS (configurable par URL dans le `.env`, ou suivre les redirections avec `-L`). -- Ajouter `set -o pipefail`. -- Nettoyer le fichier `stderr` temporaire dans un `trap`. - ---- - -## 5. Problemes transversaux - -### 5.1 Injection JSON dans les notifications Discord - -**Tous les scripts** construisent le payload JSON Discord par interpolation de chaines. C'est le probleme le plus repandu. - -**Pattern actuel (dangereux)** : -```bash -curl -d "{\"content\":\"$msg\"}" "$WEBHOOK_URL" -``` - -**Pattern corrige** : -```bash -jq -n --arg msg "$msg" '{content: $msg}' | curl -d @- ... -``` - -Ou si `jq` n'est pas disponible : -```bash -python3 -c "import sys,json; print(json.dumps({'content': sys.argv[1]}))" "$msg" | curl -d @- ... -``` - -### 5.2 Pas de rotation des sauvegardes - -Aucun script ne gere la purge des anciens backups sur le serveur distant. L'espace disque distant finira par se remplir. - -**Suggestion** : ajouter une commande SSH pour supprimer les backups de plus de N jours : -```bash -ssh "$REMOTE" "find '$REMOTE_DIR' -name '*.dump' -mtime +30 -delete" -``` - -### 5.3 Incoherence de style entre les scripts - -| Aspect | check-storage | backup-vaultwarden | backup-bdd-recette | check-statut-recette | -|--------|--------------|--------------------|--------------------|---------------------| -| `set -euo pipefail` | Non | Oui | Oui | Partiel (`set -u`) | -| Chargement .env | `grep\|cut` | `source` (chemin dur) | `source` (SCRIPT_DIR) | `source` (SCRIPT_DIR) | -| Logging | `echo` | `tee` + fichier | `tee` + fichier | `tee` + fichier | -| Gestion erreurs | Aucune | `fail()` | Granulaire | `log_line()` | -| Shebang | `#!/bin/bash` | `#!/usr/bin/env bash` | `#!/usr/bin/env bash` | `#!/usr/bin/env bash` | - -`check-storage.sh` est clairement en retard sur les conventions adoptees dans les autres scripts. - -### 5.4 README du BackupVaultWarden desynchronise - -Le README de BackupVaultWarden decrit l'ancien code (lecture `.env` avec `grep | cut`) alors que le script actuel utilise `source`. La documentation ne correspond plus au code. - ---- - -## 6. .gitignore - -### Problemes - -Le `.gitignore` est **trop complexe** et redondant. Les regles se contredisent : - -```gitignore -.env -.env.* -!.env.example -!.env.exemple -RecetteScripts/.env # redondant avec .env -CheckStorage/.env # redondant avec .env -``` - -Les regles fonctionnent correctement (les fichiers `.env` ne sont pas commites), mais la redondance rend le fichier difficile a maintenir. - -**Suggestion** : simplifier le `.gitignore` : -```gitignore -# Secrets -.env -!.env.exemple -!.env.example -``` - ---- - -## 7. Resume et priorites - -### Actions immediates (a faire maintenant) - -1. Corriger le chemin `.env` en dur dans `backup-vaultwarden.sh` (ligne 8) -2. Corriger l'injection JSON dans **tous** les scripts (utiliser `jq`) - -### Actions a court terme - -3. Remonter `check-storage.sh` au niveau des autres scripts (set -euo, source .env, SCRIPT_DIR, logging) -4. Remplacer `export PGPASSWORD` par `.pgpass` dans `backup-bdd-recette.sh` -5. Utiliser `pg_dumpall --roles-only` au lieu du simple `SELECT rolname` - -### Actions a moyen terme - -8. Ajouter la rotation des backups distants -9. Ajouter le support HTTPS dans `check-statut-recette.sh` -10. Mettre a jour le README de BackupVaultWarden -11. Simplifier le `.gitignore` - ---- - -*Revue generee par Claude (Opus 4.6) - Co-Authored-By: Claude Opus 4.6 * From 89b1229efb98ec9b5378a7405b67da44ddafacf9 Mon Sep 17 00:00:00 2001 From: AkiNoKure Date: Tue, 10 Mar 2026 16:17:11 +0100 Subject: [PATCH 5/5] fix : code review --- CODE_REVIEW.md | 212 ------------------------------------------------- 1 file changed, 212 deletions(-) delete mode 100644 CODE_REVIEW.md diff --git a/CODE_REVIEW.md b/CODE_REVIEW.md deleted file mode 100644 index 33f8e74..0000000 --- a/CODE_REVIEW.md +++ /dev/null @@ -1,212 +0,0 @@ -# Code Review - Scripts Serveur (MALIO) - -**Date** : 2026-03-09 -**Reviewer** : Claude (Opus 4.6) -**Scope** : Revue complète de tout le code du dépôt - ---- - -**Note** : Le fichier `CheckStorage/.env` contient un webhook Discord en local mais n'est **pas commité** dans le dépôt (correctement ignoré par le `.gitignore`). Pas de fuite de secret. - ---- - -## 1. BackupVaultWarden/backup-vaultwarden.sh - -### Qualite globale : Bonne - -Le script est bien structuré, utilise `set -euo pipefail`, et gère correctement les erreurs. - -### Problemes - -| Severite | Ligne | Description | -|----------|-------|-------------| -| **CRITIQUE** | 8 | Chemin `.env` en dur (`/home/matt/vaultwarden/scripts/...`) au lieu d'utiliser `$SCRIPT_DIR`. Ce script ne fonctionnera **que sur la machine de matt**. | -| **HAUTE** | 80-83 | **Injection de code** dans le message Discord. La variable `$msg` est injectée directement dans du code Python via un heredoc. Si le contenu du backup contient des guillemets triples `"""` ou du code Python, il sera exécuté. | -| **MOYENNE** | 7 | `SCRIPT_DIR` est calculé mais jamais utilisé (variable morte). | -| **BASSE** | 36 | `WEBHOOK_URL` utilise `:=` (valeur par défaut vide) au lieu de `:-`. Ce n'est pas un bug mais c'est incohérent avec les autres variables qui utilisent `:?`. | - -### Suggestions - -- **Ligne 8** : Remplacer par `ENV_FILE="${SCRIPT_DIR}/.env"` comme dans les autres scripts. -- **Ligne 80-83** : Utiliser `jq` ou `python3 -c` avec passage par argument au lieu d'interpoler dans un heredoc Python : - ```bash - printf '%s' "$msg" | python3 -c 'import sys,json; print(json.dumps({"content": sys.stdin.read()}))' | curl ... - ``` -- Ajouter une rotation des backups distants (pas de purge des anciens backups actuellement). - ---- - -## 2. CheckStorage/check-storage.sh - -### Qualite globale : Faible - -Ce script est le moins mature du dépôt. Pas de `set -euo pipefail`, pas de gestion d'erreurs, et des pratiques fragiles. - -### Problemes - -| Severite | Ligne | Description | -|----------|-------|-------------| -| **HAUTE** | 1 | Pas de `set -euo pipefail`. Le script continue silencieusement en cas d'erreur. | -| **HAUTE** | 10 | Lecture du `.env` avec `grep | cut` au lieu de `source`. Fragile : ne supporte pas les valeurs avec `=`, les espaces, ou les guillemets. | -| **HAUTE** | 39-45 | **Injection JSON** : le message Discord est construit par interpolation directe dans du JSON. Si une variable contient `"` ou `\`, le JSON sera invalide ou pire. | -| **MOYENNE** | 10 | Chemin `.env` relatif sans `cd` vers le répertoire du script. Le script cassera s'il est exécuté depuis un autre répertoire (ex: via cron). | -| **MOYENNE** | 37 | Pas de notification quand tout va bien (aucun message si usage < limite). Impossible de savoir si le cron fonctionne. | -| **BASSE** | - | Pas de shebang `#!/usr/bin/env bash`, utilise `#!/bin/bash` directement (moins portable). | -| **BASSE** | - | Pas de logging dans un fichier, seulement `echo` sur stdout. | - -### Suggestions - -- Aligner sur le pattern des scripts RecetteScripts : `set -euo pipefail`, `source .env`, `SCRIPT_DIR`, gestion d'erreurs. -- Utiliser `jq` ou Python pour construire le JSON Discord de maniere sure. -- Ajouter un chemin absolu vers le `.env` base sur `$SCRIPT_DIR`. -- Ajouter un mode `--verbose` ou un log file. - ---- - -## 3. RecetteScripts/backup-bdd-recette.sh - -### Qualite globale : Tres bonne - -C'est le script le plus mature du dépôt. Bien structure, bonne gestion d'erreurs, verrou d'execution, messages Discord granulaires. - -### Problemes - -| Severite | Ligne | Description | -|----------|-------|-------------| -| **HAUTE** | 92 | `export PGPASSWORD` : le mot de passe PostgreSQL est expose dans l'environnement. Tout process fils peut le lire (visible dans `/proc/*/environ`). Preferer un fichier `.pgpass` avec permissions 600. | -| **HAUTE** | 106-107 | **Injection JSON** dans `discord_send()` : la variable `$msg` est interpolee directement dans le JSON curl. Meme probleme que les autres scripts. | -| **MOYENNE** | 223 | Les noms de dossiers distants (`ferme`, `sirh`, `inventory`, `user`) sont en dur au lieu d'etre derives de `$DBS`. Si on ajoute une base dans `.env`, le dossier distant ne sera pas cree. | -| **MOYENNE** | 237-239 | L'export des "roles" fait en realite un simple `SELECT rolname` : ca ne sauvegarde que les **noms** des roles, pas leurs privileges, mots de passe, ou attributs. Utiliser `pg_dumpall --roles-only` pour un vrai backup des roles. | -| **BASSE** | 336 | `exit 2` en fin de script en cas d'erreur partielle : c'est bien, mais pas documente dans le README. | -| **BASSE** | 85 | Le `TMP_DIR` est sous `/tmp` : sur un systeme multi-utilisateur, un autre user pourrait pre-creer le dossier (race condition / symlink attack). Utiliser `mktemp -d`. | - -### Suggestions - -- Remplacer `export PGPASSWORD` par un fichier `.pgpass`. -- Deriver les dossiers distants de `$DBS_ARRAY` au lieu de les hardcoder. -- Utiliser `pg_dumpall --roles-only` pour un vrai export des roles. -- Utiliser `mktemp -d` pour le repertoire temporaire. - ---- - -## 4. RecetteScripts/check-statut-recette.sh - -### Qualite globale : Bonne - -Script bien ecrit, bonne separation des responsabilites, gestion propre des erreurs curl. - -### Problemes - -| Severite | Ligne | Description | -|----------|-------|-------------| -| **HAUTE** | 92-94 | **Injection JSON** dans Discord (meme pattern que partout). | -| **MOYENNE** | 1 | `set -u` sans `set -e`. Les erreurs non gerees ne stopperont pas le script. C'est voulu (le script doit continuer pour checker tous les sites), mais `set -o pipefail` manque. | -| **MOYENNE** | 52 | Schema HTTP en dur (`http`). Pas de support HTTPS. Si les apps passent en HTTPS, le script retournera des redirections 301/302 au lieu de verifier le vrai endpoint. | -| **BASSE** | 134 | Le `mktemp` pour stderr n'est pas nettoye en cas d'interruption (pas de `trap`). Fuite mineure de fichiers temp. | - -### Suggestions - -- Ajouter le support HTTPS (configurable par URL dans le `.env`, ou suivre les redirections avec `-L`). -- Ajouter `set -o pipefail`. -- Nettoyer le fichier `stderr` temporaire dans un `trap`. - ---- - -## 5. Problemes transversaux - -### 5.1 Injection JSON dans les notifications Discord - -**Tous les scripts** construisent le payload JSON Discord par interpolation de chaines. C'est le probleme le plus repandu. - -**Pattern actuel (dangereux)** : -```bash -curl -d "{\"content\":\"$msg\"}" "$WEBHOOK_URL" -``` - -**Pattern corrige** : -```bash -jq -n --arg msg "$msg" '{content: $msg}' | curl -d @- ... -``` - -Ou si `jq` n'est pas disponible : -```bash -python3 -c "import sys,json; print(json.dumps({'content': sys.argv[1]}))" "$msg" | curl -d @- ... -``` - -### 5.2 Pas de rotation des sauvegardes - -Aucun script ne gere la purge des anciens backups sur le serveur distant. L'espace disque distant finira par se remplir. - -**Suggestion** : ajouter une commande SSH pour supprimer les backups de plus de N jours : -```bash -ssh "$REMOTE" "find '$REMOTE_DIR' -name '*.dump' -mtime +30 -delete" -``` - -### 5.3 Incoherence de style entre les scripts - -| Aspect | check-storage | backup-vaultwarden | backup-bdd-recette | check-statut-recette | -|--------|--------------|--------------------|--------------------|---------------------| -| `set -euo pipefail` | Non | Oui | Oui | Partiel (`set -u`) | -| Chargement .env | `grep\|cut` | `source` (chemin dur) | `source` (SCRIPT_DIR) | `source` (SCRIPT_DIR) | -| Logging | `echo` | `tee` + fichier | `tee` + fichier | `tee` + fichier | -| Gestion erreurs | Aucune | `fail()` | Granulaire | `log_line()` | -| Shebang | `#!/bin/bash` | `#!/usr/bin/env bash` | `#!/usr/bin/env bash` | `#!/usr/bin/env bash` | - -`check-storage.sh` est clairement en retard sur les conventions adoptees dans les autres scripts. - -### 5.4 README du BackupVaultWarden desynchronise - -Le README de BackupVaultWarden decrit l'ancien code (lecture `.env` avec `grep | cut`) alors que le script actuel utilise `source`. La documentation ne correspond plus au code. - ---- - -## 6. .gitignore - -### Problemes - -Le `.gitignore` est **trop complexe** et redondant. Les regles se contredisent : - -```gitignore -.env -.env.* -!.env.example -!.env.exemple -RecetteScripts/.env # redondant avec .env -CheckStorage/.env # redondant avec .env -``` - -Les regles fonctionnent correctement (les fichiers `.env` ne sont pas commites), mais la redondance rend le fichier difficile a maintenir. - -**Suggestion** : simplifier le `.gitignore` : -```gitignore -# Secrets -.env -!.env.exemple -!.env.example -``` - ---- - -## 7. Resume et priorites - -### Actions immediates (a faire maintenant) - -1. Corriger le chemin `.env` en dur dans `backup-vaultwarden.sh` (ligne 8) -2. Corriger l'injection JSON dans **tous** les scripts (utiliser `jq`) - -### Actions a court terme - -3. Remonter `check-storage.sh` au niveau des autres scripts (set -euo, source .env, SCRIPT_DIR, logging) -4. Remplacer `export PGPASSWORD` par `.pgpass` dans `backup-bdd-recette.sh` -5. Utiliser `pg_dumpall --roles-only` au lieu du simple `SELECT rolname` - -### Actions a moyen terme - -8. Ajouter la rotation des backups distants -9. Ajouter le support HTTPS dans `check-statut-recette.sh` -10. Mettre a jour le README de BackupVaultWarden -11. Simplifier le `.gitignore` - ---- - -*Revue generee par Claude (Opus 4.6) - Co-Authored-By: Claude Opus 4.6 *