feat: add NAS backup, verification, and DR scripts
Some checks failed
Deploy to Production / Build and Deploy (push) Has been cancelled

This commit is contained in:
2026-06-07 11:12:01 +02:00
parent fb6740f333
commit 3f980ad537
7 changed files with 1789 additions and 429 deletions

264
scripts/setup-nas.sh Normal file
View File

@@ -0,0 +1,264 @@
#!/bin/bash
# ==============================================================================
# Wordly.art - NAS Setup via SSH/rsync
# ==============================================================================
# Configure l'accès SSH sans mot de passe au NAS Synology.
# Remplace l'approche CIFS/SMB par rsync sur SSH :
# - Pas de montage à gérer, pas de fstab
# - Path exact /volume1/backups/wordly utilisable directement
# - SSH chiffré, robuste aux redémarrages NAS
#
# Usage:
# sudo bash scripts/setup-nas.sh
#
# Prérequis côté NAS Synology (voir DISASTER_RECOVERY.md section 1) :
# 1. Compte 'wordly-backup' créé dans DSM → Utilisateurs et groupes
# 2. Accès R/W sur le dossier 'backups'
# 3. SSH activé dans DSM → Terminal et SNMP
# 4. Dossier /volume1/backups/wordly créé et chown wordly-backup
# ==============================================================================
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
log() { echo -e "[NAS-Setup] $1"; }
log_success() { echo -e "[NAS-Setup] ${GREEN}$1${NC}"; }
log_warning() { echo -e "[NAS-Setup] ${YELLOW}⚠️ $1${NC}"; }
log_error() { echo -e "[NAS-Setup] ${RED}$1${NC}"; }
log_info() { echo -e "[NAS-Setup] ${BLUE} $1${NC}"; }
# ==============================================================================
# 1. ROOT CHECK
# ==============================================================================
if [ "$EUID" -ne 0 ]; then
log_error "Ce script doit être exécuté en root : sudo bash $0"
exit 1
fi
# ==============================================================================
# 2. CHARGER LE .env
# ==============================================================================
ENV_FILE="${PROJECT_ROOT}/.env"
if [ -f "${ENV_FILE}" ]; then
set -a
source "${ENV_FILE}"
set +a
fi
NAS_HOST="${NAS_HOST:-192.168.1.146}"
NAS_USER="${NAS_USER:-wordly-backup}"
NAS_PATH="${NAS_PATH:-/volume1/backups/wordly}"
NAS_SSH_PORT="${NAS_SSH_PORT:-22}"
NAS_SSH_KEY="${NAS_SSH_KEY:-/root/.ssh/wordly_nas_key}"
# ==============================================================================
# 3. VÉRIFIER QUE SSH EST DISPO SUR LE NAS
# ==============================================================================
check_nas_reachable() {
log "Vérification de la connectivité SSH vers ${NAS_HOST}:${NAS_SSH_PORT}..."
if ! nc -z -w5 "${NAS_HOST}" "${NAS_SSH_PORT}" 2>/dev/null; then
log_error "Impossible de joindre ${NAS_HOST} sur le port ${NAS_SSH_PORT}."
log_error "Vérifiez que SSH est activé dans DSM → Panneau de configuration → Terminal et SNMP."
exit 1
fi
log_success "NAS ${NAS_HOST}:${NAS_SSH_PORT} est joignable"
}
# ==============================================================================
# 4. GÉNÉRER LA CLÉ SSH DÉDIÉE (si elle n'existe pas)
# ==============================================================================
generate_ssh_key() {
if [ -f "${NAS_SSH_KEY}" ]; then
log_info "Clé SSH déjà existante : ${NAS_SSH_KEY}"
log_info "Si vous voulez la regénérer : rm ${NAS_SSH_KEY} ${NAS_SSH_KEY}.pub"
else
log "Génération de la clé SSH dédiée aux backups NAS..."
ssh-keygen -t ed25519 \
-C "wordly-backup@$(hostname)-$(date +%Y%m%d)" \
-f "${NAS_SSH_KEY}" \
-N ""
chmod 600 "${NAS_SSH_KEY}"
log_success "Clé SSH générée : ${NAS_SSH_KEY}"
fi
log_info "Clé publique à autoriser sur le NAS :"
cat "${NAS_SSH_KEY}.pub"
}
# ==============================================================================
# 5. COPIER LA CLÉ PUBLIQUE SUR LE NAS
# ==============================================================================
install_ssh_key() {
log "Copie de la clé publique sur le NAS ${NAS_USER}@${NAS_HOST}..."
log_warning "Le mot de passe du compte '${NAS_USER}' sur le NAS vous sera demandé UNE SEULE FOIS."
echo ""
if ssh-copy-id \
-i "${NAS_SSH_KEY}.pub" \
-p "${NAS_SSH_PORT}" \
-o StrictHostKeyChecking=accept-new \
"${NAS_USER}@${NAS_HOST}"; then
log_success "Clé publique installée sur le NAS — plus de mot de passe requis"
else
log_error "Échec de ssh-copy-id. Avez-vous bien créé le compte '${NAS_USER}' sur le Synology ?"
log_error "Vérifiez aussi que SSH est activé dans DSM."
exit 1
fi
}
# ==============================================================================
# 6. TESTER LA CONNEXION SANS MOT DE PASSE
# ==============================================================================
test_ssh_connection() {
log "Test de la connexion SSH sans mot de passe..."
local result
if result=$(ssh \
-i "${NAS_SSH_KEY}" \
-p "${NAS_SSH_PORT}" \
-o StrictHostKeyChecking=accept-new \
-o ConnectTimeout=10 \
-o BatchMode=yes \
"${NAS_USER}@${NAS_HOST}" \
"echo OK" 2>/dev/null); then
if [ "${result}" = "OK" ]; then
log_success "Connexion SSH sans mot de passe : OK"
else
log_error "Connexion établie mais réponse inattendue : ${result}"
exit 1
fi
else
log_error "Connexion SSH sans mot de passe ÉCHOUÉE."
log_error "Vérifiez que la clé a bien été copiée avec ssh-copy-id."
exit 1
fi
}
# ==============================================================================
# 7. CRÉER LA STRUCTURE DE DOSSIERS SUR LE NAS
# ==============================================================================
create_nas_directories() {
log "Création de la structure de dossiers sur le NAS : ${NAS_PATH}..."
ssh \
-i "${NAS_SSH_KEY}" \
-p "${NAS_SSH_PORT}" \
-o BatchMode=yes \
"${NAS_USER}@${NAS_HOST}" \
"mkdir -p ${NAS_PATH}/snapshots ${NAS_PATH}/scripts && echo OK"
log_success "Structure créée sur le NAS :"
log_success " ${NAS_PATH}/snapshots/ → archives DR"
log_success " ${NAS_PATH}/scripts/ → scripts de restauration"
}
# ==============================================================================
# 8. TESTER L'ÉCRITURE SUR LE NAS
# ==============================================================================
test_nas_write() {
log "Test d'écriture sur le NAS..."
local test_file="${NAS_PATH}/.write_test_$$"
if ssh \
-i "${NAS_SSH_KEY}" \
-p "${NAS_SSH_PORT}" \
-o BatchMode=yes \
"${NAS_USER}@${NAS_HOST}" \
"touch ${test_file} && rm -f ${test_file} && echo OK" | grep -q "OK"; then
log_success "Écriture sur le NAS : OK"
else
log_error "Le NAS est accessible mais pas accessible en écriture !"
log_error "Vérifiez les permissions du dossier '${NAS_PATH}' pour l'utilisateur '${NAS_USER}'."
exit 1
fi
}
# ==============================================================================
# 9. CRÉER LE FICHIER DE CONFIG SSH (~/.ssh/config)
# ==============================================================================
configure_ssh_config() {
local ssh_config="/root/.ssh/config"
local host_entry="
# Wordly.art — NAS Synology Backup
Host wordly-nas
HostName ${NAS_HOST}
User ${NAS_USER}
Port ${NAS_SSH_PORT}
IdentityFile ${NAS_SSH_KEY}
StrictHostKeyChecking accept-new
ConnectTimeout 10
ServerAliveInterval 30
BatchMode yes"
if grep -q "wordly-nas" "${ssh_config}" 2>/dev/null; then
log_warning "Entrée 'wordly-nas' déjà dans ${ssh_config} — ignorée."
else
mkdir -p /root/.ssh
chmod 700 /root/.ssh
echo "${host_entry}" >> "${ssh_config}"
chmod 600 "${ssh_config}"
log_success "Config SSH ajoutée : ${ssh_config}"
log_info "Vous pouvez maintenant utiliser : ssh wordly-nas"
fi
}
# ==============================================================================
# 10. COPIER LES SCRIPTS SUR LE NAS (disponibles depuis n'importe quel serveur)
# ==============================================================================
sync_scripts_to_nas() {
log "Synchronisation des scripts sur le NAS (pour restauration depuis .98)..."
if rsync -az \
-e "ssh -i ${NAS_SSH_KEY} -p ${NAS_SSH_PORT} -o BatchMode=yes" \
--exclude="__pycache__" \
--exclude="*.pyc" \
"${SCRIPT_DIR}/" \
"${NAS_USER}@${NAS_HOST}:${NAS_PATH}/scripts/"; then
log_success "Scripts synchronisés sur le NAS : ${NAS_PATH}/scripts/"
else
log_warning "rsync a échoué — vérifiez que rsync est installé sur le NAS Synology."
log_warning "Essayez : Synology Package Center → installer 'Rsync Server'"
fi
}
# ==============================================================================
# 11. MAIN
# ==============================================================================
main() {
echo ""
echo "================================================================="
echo " Wordly.art — Setup NAS via SSH/rsync"
echo " NAS : ${NAS_USER}@${NAS_HOST}:${NAS_SSH_PORT}"
echo " Path : ${NAS_PATH}"
echo " Clé : ${NAS_SSH_KEY}"
echo "================================================================="
echo ""
check_nas_reachable
generate_ssh_key
install_ssh_key
test_ssh_connection
create_nas_directories
test_nas_write
configure_ssh_config
sync_scripts_to_nas
echo ""
log_success "================================================================="
log_success "Setup NAS COMPLET"
log_success ""
log_success " ✅ Clé SSH : ${NAS_SSH_KEY}"
log_success " ✅ Connexion sans mot de passe : wordly-nas"
log_success " ✅ Dossiers créés sur le NAS"
log_success " ✅ Scripts disponibles pour DR depuis n'importe quel serveur"
log_success ""
log_success " Test rapide : ssh wordly-nas 'ls ${NAS_PATH}/'"
log_success " Étape suivante : bash scripts/backup-to-nas.sh --full"
log_success "================================================================="
echo ""
}
main "$@"