improve scripts security

This commit is contained in:
BeauTroll
2025-12-15 11:14:16 +01:00
parent dc15b4665d
commit 517e337a25
4 changed files with 272 additions and 49 deletions

View File

@@ -1,14 +1,51 @@
#!/bin/bash #!/bin/bash
# scripts/backup.sh - Backup complet Nextcloud # scripts/backup.sh - Backup complet Nextcloud
set -e set -euo pipefail
# Charger les variables d'environnement
if [ ! -f .env ]; then
echo "❌ Erreur: Fichier .env introuvable"
exit 1
fi
# shellcheck disable=SC1091
source .env source .env
# Vérifier les variables requises
: "${MYSQL_USER:?Variable MYSQL_USER non définie}"
: "${MYSQL_PASSWORD:?Variable MYSQL_PASSWORD non définie}"
: "${MYSQL_DATABASE:?Variable MYSQL_DATABASE non définie}"
BACKUP_DIR="${BACKUP_DESTINATION:-./backups}" BACKUP_DIR="${BACKUP_DESTINATION:-./backups}"
DATE=$(date +%Y%m%d_%H%M%S) DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_NAME="nextcloud_backup_$DATE" BACKUP_NAME="nextcloud_backup_$DATE"
BACKUP_PATH="$BACKUP_DIR/$BACKUP_NAME" BACKUP_PATH="$BACKUP_DIR/$BACKUP_NAME"
MAINTENANCE_ENABLED=false
# Fonction de nettoyage en cas d'erreur
cleanup() {
local exit_code=$?
if [ "$exit_code" -ne 0 ]; then
echo "❌ Erreur détectée (code: $exit_code), nettoyage..."
fi
# Désactiver le mode maintenance si activé
if [ "$MAINTENANCE_ENABLED" = true ]; then
echo "▶️ Désactivation du mode maintenance..."
docker-compose exec -T -u www-data nextcloud php occ maintenance:mode --off || true
fi
# Nettoyer le backup partiel
if [ -d "$BACKUP_PATH" ]; then
echo "🧹 Nettoyage du backup partiel..."
rm -rf "${BACKUP_PATH:?}"
fi
exit "$exit_code"
}
trap cleanup EXIT INT TERM
echo "🔧 Démarrage du backup: $BACKUP_NAME" echo "🔧 Démarrage du backup: $BACKUP_NAME"
@@ -17,18 +54,25 @@ mkdir -p "$BACKUP_PATH"
# 1. Activer le mode maintenance # 1. Activer le mode maintenance
echo "⏸️ Activation du mode maintenance..." echo "⏸️ Activation du mode maintenance..."
docker-compose exec -T -u www-data nextcloud php occ maintenance:mode --on if docker-compose exec -T -u www-data nextcloud php occ maintenance:mode --on; then
MAINTENANCE_ENABLED=true
else
echo "❌ Impossible d'activer le mode maintenance"
exit 1
fi
# 2. Backup de la base de données # 2. Backup de la base de données
echo "💾 Backup de la base de données..." echo "💾 Backup de la base de données..."
docker-compose exec -T db mysqldump \ # Utiliser des variables d'environnement pour éviter le mot de passe dans la ligne de commande
-u"$MYSQL_USER" \ if ! docker-compose exec -T db sh -c "MYSQL_PWD=\"\$MYSQL_PASSWORD\" mysqldump \
-p"$MYSQL_PASSWORD" \ -u\"\$MYSQL_USER\" \
"$MYSQL_DATABASE" \ \"\$MYSQL_DATABASE\" \
--single-transaction \ --single-transaction \
--quick \ --quick \
--lock-tables=false \ --lock-tables=false" > "$BACKUP_PATH/database.sql"; then
> "$BACKUP_PATH/database.sql" echo "❌ Erreur lors du backup de la base de données"
exit 1
fi
# 3. Backup des fichiers de config # 3. Backup des fichiers de config
echo "⚙️ Backup de la configuration..." echo "⚙️ Backup de la configuration..."
@@ -59,17 +103,26 @@ fi
# 6. Désactiver le mode maintenance # 6. Désactiver le mode maintenance
echo "▶️ Désactivation du mode maintenance..." echo "▶️ Désactivation du mode maintenance..."
docker-compose exec -T -u www-data nextcloud php occ maintenance:mode --off if docker-compose exec -T -u www-data nextcloud php occ maintenance:mode --off; then
MAINTENANCE_ENABLED=false
else
echo "⚠️ Attention: Impossible de désactiver le mode maintenance"
fi
# 7. Créer une archive complète # 7. Créer une archive complète
echo "🗜️ Compression finale..." echo "🗜️ Compression finale..."
cd "$BACKUP_DIR" if ! tar -czf "$BACKUP_DIR/$BACKUP_NAME.tar.gz" -C "$BACKUP_DIR" "$BACKUP_NAME/"; then
tar -czf "$BACKUP_NAME.tar.gz" "$BACKUP_NAME/" echo "❌ Erreur lors de la compression"
rm -rf "$BACKUP_NAME" exit 1
fi
# Supprimer le dossier temporaire après compression réussie
rm -rf "${BACKUP_PATH:?}"
# 8. Nettoyer les vieux backups # 8. Nettoyer les vieux backups
echo "🧹 Nettoyage des backups > ${BACKUP_RETENTION_DAYS:-30} jours..." RETENTION_DAYS="${BACKUP_RETENTION_DAYS:-30}"
find "$BACKUP_DIR" -name "nextcloud_backup_*.tar.gz" -mtime +${BACKUP_RETENTION_DAYS:-30} -delete echo "🧹 Nettoyage des backups > $RETENTION_DAYS jours..."
find "$BACKUP_DIR" -name "nextcloud_backup_*.tar.gz" -type f -mtime +"$RETENTION_DAYS" -delete
echo "✅ Backup terminé: $BACKUP_DIR/$BACKUP_NAME.tar.gz" echo "✅ Backup terminé: $BACKUP_DIR/$BACKUP_NAME.tar.gz"
du -h "$BACKUP_DIR/$BACKUP_NAME.tar.gz" du -h "$BACKUP_DIR/$BACKUP_NAME.tar.gz"

View File

@@ -1,6 +1,21 @@
#!/bin/bash #!/bin/bash
# scripts/occ.sh - Wrapper pour commandes OCC # scripts/occ.sh - Wrapper pour commandes OCC
set -e set -euo pipefail
# Vérifier que docker-compose est disponible
if ! command -v docker-compose >/dev/null 2>&1; then
echo "❌ Erreur: docker-compose n'est pas installé"
exit 1
fi
# Vérifier que le container nextcloud est actif
if ! docker-compose ps nextcloud | grep -q "Up"; then
echo "❌ Erreur: Le container nextcloud n'est pas actif"
echo " Démarrez-le avec: make up"
exit 1
fi
# Exécuter la commande OCC
# Le "$@" est sûr ici car il est passé directement à PHP OCC qui gère la validation
docker-compose exec -u www-data nextcloud php occ "$@" docker-compose exec -u www-data nextcloud php occ "$@"

View File

@@ -1,22 +1,48 @@
#!/bin/bash #!/bin/bash
# scripts/restore.sh - Restauration d'un backup # scripts/restore.sh - Restauration d'un backup
set -e set -euo pipefail
if [ -z "$1" ]; then # Charger les variables d'environnement
if [ ! -f .env ]; then
echo "❌ Erreur: Fichier .env introuvable"
exit 1
fi
# shellcheck disable=SC1091
source .env
# Vérifier les variables requises
: "${MYSQL_USER:?Variable MYSQL_USER non définie}"
: "${MYSQL_PASSWORD:?Variable MYSQL_PASSWORD non définie}"
: "${MYSQL_DATABASE:?Variable MYSQL_DATABASE non définie}"
if [ -z "${1:-}" ]; then
echo "Usage: $0 <backup_file.tar.gz>" echo "Usage: $0 <backup_file.tar.gz>"
exit 1 exit 1
fi fi
BACKUP_FILE="$1" BACKUP_FILE="$1"
# Valider le chemin du fichier (éviter path traversal)
if [[ "$BACKUP_FILE" =~ \.\./\.\. ]]; then
echo "❌ Chemin de fichier invalide"
exit 1
fi
if [ ! -f "$BACKUP_FILE" ]; then if [ ! -f "$BACKUP_FILE" ]; then
echo "❌ Fichier introuvable: $BACKUP_FILE" echo "❌ Fichier introuvable: $BACKUP_FILE"
exit 1 exit 1
fi fi
# Vérifier que c'est bien un fichier tar.gz
if ! file "$BACKUP_FILE" | grep -q "gzip compressed"; then
echo "❌ Le fichier n'est pas une archive gzip valide"
exit 1
fi
echo "⚠️ ATTENTION: Cette opération va écraser les données actuelles !" echo "⚠️ ATTENTION: Cette opération va écraser les données actuelles !"
read -p "Continuer? (yes/no): " confirm read -r -p "Continuer? (yes/no): " confirm
if [ "$confirm" != "yes" ]; then if [ "$confirm" != "yes" ]; then
echo "Annulé." echo "Annulé."
@@ -25,32 +51,100 @@ fi
# Extraire le backup # Extraire le backup
TEMP_DIR=$(mktemp -d) TEMP_DIR=$(mktemp -d)
echo "📂 Extraction vers $TEMP_DIR..."
tar -xzf "$BACKUP_FILE" -C "$TEMP_DIR"
BACKUP_DIR=$(ls -1 "$TEMP_DIR" | head -n1) # Fonction de nettoyage
cleanup() {
local exit_code=$?
if [ -d "$TEMP_DIR" ]; then
echo "🧹 Nettoyage du répertoire temporaire..."
rm -rf "${TEMP_DIR:?}"
fi
exit "$exit_code"
}
trap cleanup EXIT INT TERM
echo "📂 Extraction vers $TEMP_DIR..."
if ! tar -xzf "$BACKUP_FILE" -C "$TEMP_DIR"; then
echo "❌ Erreur lors de l'extraction"
exit 1
fi
# Trouver le répertoire de backup de manière sécurisée
BACKUP_DIR=$(find "$TEMP_DIR" -mindepth 1 -maxdepth 1 -type d | head -n1)
if [ -z "$BACKUP_DIR" ]; then
echo "❌ Aucun répertoire trouvé dans l'archive"
exit 1
fi
BACKUP_DIR=$(basename "$BACKUP_DIR")
# Arrêter les services # Arrêter les services
echo "⏹️ Arrêt des services..." echo "⏹️ Arrêt des services..."
docker-compose down docker-compose down
# Vérifier que les fichiers requis existent
if [ ! -f "$TEMP_DIR/$BACKUP_DIR/database.sql" ]; then
echo "❌ Fichier database.sql manquant dans l'archive"
exit 1
fi
if [ ! -f "$TEMP_DIR/$BACKUP_DIR/config.tar.gz" ]; then
echo "❌ Fichier config.tar.gz manquant dans l'archive"
exit 1
fi
# Restaurer la base de données # Restaurer la base de données
echo "💾 Restauration de la base de données..." echo "💾 Restauration de la base de données..."
docker-compose up -d db docker-compose up -d db
sleep 10
docker-compose exec -T db mysql \ # Attendre que la base de données soit prête
-u"$MYSQL_USER" \ echo "⏳ Attente de la base de données..."
-p"$MYSQL_PASSWORD" \ for i in {1..30}; do
"$MYSQL_DATABASE" \ if docker-compose exec -T db mysqladmin ping -h localhost --silent 2>/dev/null; then
< "$TEMP_DIR/$BACKUP_DIR/database.sql" echo "✅ Base de données prête"
break
fi
if [ "$i" -eq 30 ]; then
echo "❌ Timeout: La base de données n'est pas prête"
exit 1
fi
sleep 1
done
# Restaurer avec MYSQL_PWD pour éviter le mot de passe dans la commande
if ! docker-compose exec -T db sh -c "MYSQL_PWD=\"\$MYSQL_PASSWORD\" mysql \
-u\"\$MYSQL_USER\" \
\"\$MYSQL_DATABASE\"" < "$TEMP_DIR/$BACKUP_DIR/database.sql"; then
echo "❌ Erreur lors de la restauration de la base de données"
exit 1
fi
# Restaurer les fichiers # Restaurer les fichiers
echo "📁 Restauration des fichiers..." echo "📁 Restauration des fichiers..."
tar -xzf "$TEMP_DIR/$BACKUP_DIR/config.tar.gz" -C ./data/config
tar -xzf "$TEMP_DIR/$BACKUP_DIR/data.tar.gz" -C ./data/data
# Vérifier et créer les répertoires si nécessaire
mkdir -p ./data/config ./data/data
if ! tar -xzf "$TEMP_DIR/$BACKUP_DIR/config.tar.gz" -C ./data/config; then
echo "❌ Erreur lors de la restauration de la configuration"
exit 1
fi
# Restaurer les données si elles existent dans l'archive
if [ -f "$TEMP_DIR/$BACKUP_DIR/data.tar.gz" ]; then
if ! tar -xzf "$TEMP_DIR/$BACKUP_DIR/data.tar.gz" -C ./data/data; then
echo "❌ Erreur lors de la restauration des données"
exit 1
fi
elif [ -d "$TEMP_DIR/$BACKUP_DIR/data" ]; then
# Si les données sont dans un dossier (backup rsync)
rsync -a "$TEMP_DIR/$BACKUP_DIR/data/" ./data/data/
fi
# Restaurer les apps personnalisées si présentes
if [ -f "$TEMP_DIR/$BACKUP_DIR/apps.tar.gz" ]; then if [ -f "$TEMP_DIR/$BACKUP_DIR/apps.tar.gz" ]; then
mkdir -p ./data/custom_apps
tar -xzf "$TEMP_DIR/$BACKUP_DIR/apps.tar.gz" -C ./data/custom_apps tar -xzf "$TEMP_DIR/$BACKUP_DIR/apps.tar.gz" -C ./data/custom_apps
fi fi
@@ -58,13 +152,23 @@ fi
echo "▶️ Redémarrage des services..." echo "▶️ Redémarrage des services..."
docker-compose up -d docker-compose up -d
# Attendre que Nextcloud soit prêt
echo "⏳ Attente du démarrage de Nextcloud..."
for i in {1..60}; do
if docker-compose exec -T nextcloud curl -f http://localhost/status.php >/dev/null 2>&1; then
echo "✅ Nextcloud prêt"
break
fi
if [ "$i" -eq 60 ]; then
echo "⚠️ Warning: Nextcloud met du temps à démarrer, on continue..."
break
fi
sleep 1
done
# Réparer et scanner # Réparer et scanner
echo "🔧 Réparation..." echo "🔧 Réparation..."
sleep 30 docker-compose exec -u www-data nextcloud php occ maintenance:repair || echo "⚠️ Erreur lors de la réparation"
docker-compose exec -u www-data nextcloud php occ maintenance:repair docker-compose exec -u www-data nextcloud php occ files:scan --all || echo "⚠️ Erreur lors du scan"
docker-compose exec -u www-data nextcloud php occ files:scan --all
# Nettoyer
rm -rf "$TEMP_DIR"
echo "✅ Restauration terminée !" echo "✅ Restauration terminée !"

View File

@@ -1,47 +1,98 @@
#!/bin/bash #!/bin/bash
# scripts/update.sh - Mise à jour Nextcloud # scripts/update.sh - Mise à jour Nextcloud
set -e set -euo pipefail
MAINTENANCE_ENABLED=false
# Fonction de nettoyage en cas d'erreur
cleanup() {
local exit_code=$?
if [ "$exit_code" -ne 0 ]; then
echo "❌ Erreur détectée lors de la mise à jour (code: $exit_code)"
echo "⚠️ IMPORTANT: Vérifiez les logs et considérez une restauration si nécessaire"
fi
# Désactiver le mode maintenance si activé
if [ "$MAINTENANCE_ENABLED" = true ]; then
echo "▶️ Tentative de désactivation du mode maintenance..."
docker-compose exec -T -u www-data nextcloud php occ maintenance:mode --off 2>/dev/null || true
fi
exit "$exit_code"
}
trap cleanup EXIT INT TERM
echo "🔄 Mise à jour de Nextcloud" echo "🔄 Mise à jour de Nextcloud"
# Backup avant update # Backup avant update
echo "💾 Backup de sécurité..." echo "💾 Backup de sécurité..."
bash scripts/backup.sh if ! bash scripts/backup.sh; then
echo "❌ Erreur lors du backup, abandon de la mise à jour"
exit 1
fi
# Mode maintenance # Mode maintenance
echo "⏸️ Mode maintenance activé" echo "⏸️ Mode maintenance activé"
docker-compose exec -u www-data nextcloud php occ maintenance:mode --on if docker-compose exec -T -u www-data nextcloud php occ maintenance:mode --on; then
MAINTENANCE_ENABLED=true
else
echo "❌ Impossible d'activer le mode maintenance"
exit 1
fi
# Pull nouvelle image # Pull nouvelle image
echo "📥 Téléchargement de la nouvelle version..." echo "📥 Téléchargement de la nouvelle version..."
docker-compose pull nextcloud if ! docker-compose pull nextcloud; then
echo "❌ Erreur lors du téléchargement de l'image"
exit 1
fi
# Restart # Restart
echo "🔄 Redémarrage..." echo "🔄 Redémarrage..."
docker-compose up -d --force-recreate nextcloud cron docker-compose up -d --force-recreate nextcloud cron
# Attendre que Nextcloud soit prêt # Attendre que Nextcloud soit prêt
echo "⏳ Attente du démarrage..." echo "⏳ Attente du démarrage de Nextcloud..."
sleep 30 for i in {1..60}; do
if docker-compose exec -T nextcloud curl -f http://localhost/status.php >/dev/null 2>&1; then
echo "✅ Nextcloud prêt"
break
fi
if [ "$i" -eq 60 ]; then
echo "❌ Timeout: Nextcloud n'est pas prêt"
exit 1
fi
sleep 1
done
# Upgrade via OCC # Upgrade via OCC
echo "⬆️ Lancement de l'upgrade..." echo "⬆️ Lancement de l'upgrade..."
docker-compose exec -u www-data nextcloud php occ upgrade if ! docker-compose exec -T -u www-data nextcloud php occ upgrade; then
echo "❌ Erreur lors de l'upgrade"
exit 1
fi
# Scan et indices # Scan et indices (non bloquant)
echo "🔍 Scan des fichiers..." echo "🔍 Scan des fichiers..."
docker-compose exec -u www-data nextcloud php occ files:scan --all docker-compose exec -T -u www-data nextcloud php occ files:scan --all || echo "⚠️ Avertissement: Erreur lors du scan"
echo "📊 Ajout des indices manquants..." echo "📊 Ajout des indices manquants..."
docker-compose exec -u www-data nextcloud php occ db:add-missing-indices docker-compose exec -T -u www-data nextcloud php occ db:add-missing-indices || echo "⚠️ Avertissement: Erreur lors de l'ajout des indices"
echo "🔧 Conversion des colonnes..." echo "🔧 Conversion des colonnes..."
docker-compose exec -u www-data nextcloud php occ db:convert-filecache-bigint --no-interaction docker-compose exec -T -u www-data nextcloud php occ db:convert-filecache-bigint --no-interaction || echo "⚠️ Avertissement: Erreur lors de la conversion"
# Désactiver maintenance # Désactiver maintenance
echo "▶️ Désactivation du mode maintenance" echo "▶️ Désactivation du mode maintenance"
docker-compose exec -u www-data nextcloud php occ maintenance:mode --off if docker-compose exec -T -u www-data nextcloud php occ maintenance:mode --off; then
MAINTENANCE_ENABLED=false
echo "✅ Mise à jour terminée !" echo "✅ Mise à jour terminée !"
docker-compose exec -u www-data nextcloud php occ status else
echo "⚠️ Attention: Impossible de désactiver le mode maintenance"
echo " Exécutez manuellement: make occ maintenance:mode --off"
fi
docker-compose exec -T -u www-data nextcloud php occ status