Script d'extraction de sauvegardes Unifi
Ce document explique et inclut le script PowerShell utilisé pour extraire les sauvegardes Unifi par SSH avec Putty.
En gros, si vous avez un système de sécurité sans accès WAN, cela permet de sauvegarder les données Unifi vers un serveur LAN.
Aperçu
Le script se connecte à un appareil Unifi via SSH, récupère la liste des fichiers de sauvegarde, les compare avec le répertoire local et télécharge automatiquement ceux qui manquent.
Il utilise les utilitaires PuTTY (plink et pscp) pour la communication SSH et les transferts de fichiers.
Paramètres
| Paramètre | Description |
|---|---|
| unifiUserRoot | Nom d'utilisateur SSH pour l'appareil Unifi (par défaut : root). |
| unifiDevice | Adresse IP de l'appareil Unifi. |
| unifiBackupDir | Chemin du répertoire distant contenant les sauvegardes Unifi. |
| password | Mot de passe SSH pour l'utilisateur Unifi. |
| localDir | Répertoire local où les sauvegardes seront stockées. |
Comment fonctionne le script
Étape 1. Vérifier le répertoire local
Le script s'assure que le répertoire local existe avant de continuer.
Sinon, il se termine pour éviter les erreurs.
if (-not (Test-Path $localDir)) {
Write-Host "Local directory does not exist: $localDir"
exit 1
}
Étape 2. Récupérer l'empreinte SSH
Pour vérifier l'identité de l'appareil Unifi, le script récupère son empreinte SSH et s'assure que la connexion est sécurisée.
$hostKeyScan = & ssh-keyscan -t ed25519 $unifiDevice 2>$null
$hostKeyFingerprint = $hostKeyScan | ssh-keygen -lf - | ForEach-Object {
$_.ToString().Split(" ") | Select-Object -Index 1
}
Cela prévient les attaques de type « man-in-the-middle » en confirmant que la clé SSH correspond à l'appareil attendu.
Étape 3. Récupérer la liste des sauvegardes distantes
Le script se connecte via plink et liste tous les fichiers du répertoire de sauvegarde Unifi.
$unifiBackups = & "$plinkPath" `
-ssh `
-pw $password `
-batch `
-noagent `
-hostkey "$fullHostKey" `
"$unifiUserRoot@$unifiDevice" `
"ls -1 $unifiBackupDir"
Étape 4. Comparer avec les fichiers locaux
Il compare la liste des sauvegardes distantes avec les fichiers locaux pour trouver ceux qui manquent.
$localFiles = Get-ChildItem -Path $localDir -File | Select-Object -ExpandProperty Name
$missingBackups = $unifiBackups | Where-Object { $_ -and ($_ -notin $localFiles) }
S'il n'y a aucun fichier manquant, le script se termine normalement.
Étape 5. Télécharger les sauvegardes manquantes
Pour chaque fichier manquant, le script le télécharge en utilisant pscp via SSH.
foreach ($file in $missingBackups) {
$remoteFullPath = "$unifiUserRoot@$unifiDevice:$unifiBackupDir/$file"
& "$pscpPath" -pw $password -batch -noagent -hostkey $fullHostKey $remoteFullPath $localDir
}
Une fois terminé, il signale que tous les fichiers manquants ont été téléchargés.
Exemple d'utilisation
Pour exécuter le script :
.\BackupUnifi.ps1
Avant l'exécution :
- Assurez-vous que
plink.exeetpscp.exe(de PuTTY) sont installés. - Vérifiez l'adresse IP Unifi et les identifiants SSH.
- Assurez-vous que le répertoire de sauvegarde local existe et a les permissions d'écriture.
Code source complet
# SPDX-License-Identifier: AGPL-3.0-or-later
#
# This file is part of the "Unifi Automatic Backup Script via SSH".
#
# Copyright (C) 2025 Mat Ice
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
#
<#
.SYNOPSIS
Automatically backs up Unifi configuration files over SSH.
.DESCRIPTION
It connects to a Unifi device via SSH, retrieves the list of backup files,
compares them with the local ones, and automatically downloads any that are missing.
.PARAMETER unifiUserRoot
SSH username for connecting to the Unifi device (default: "root").
.PARAMETER unifiDevice
IP address of the Unifi device.
.PARAMETER unifiBackupDir
Remote directory containing Unifi backups.
.PARAMETER password
SSH password for the Unifi user.
.PARAMETER localDir
Local directory where backups will be stored.
.EXAMPLE
.\BackupUnifi.ps1
.NOTES
Author : Mat Ice
#>
$unifiUserRoot = "root"
$unifiDevice = "192.168.2.1"
$unifiBackupDir = "/data/unifi/data/backup/autobackup"
$password = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
$localDir = "G:\unifi"
# Path to PuTTY tools (adjust if needed)
$pscpPath = "C:\Program Files\PuTTY\pscp.exe"
$plinkPath = "C:\Program Files\PuTTY\plink.exe"
# === STEP 0: Verify local directory ===
if (-not (Test-Path $localDir)) {
Write-Host "Local directory does not exist: $localDir"
exit 1
}
# === STEP 1: Retrieve SSH host key fingerprint ===
Write-Host "Retrieving SSH host key fingerprint..."
$hostKeyScan = & ssh-keyscan -t ed25519 $unifiDevice 2>$null
if (-not $hostKeyScan) {
Write-Host "Failed to retrieve SSH key from $unifiDevice"
exit 1
}
# Generate SHA256 fingerprint (requires OpenSSH)
$hostKeyFingerprint = $hostKeyScan | ssh-keygen -lf - | ForEach-Object {
$_.ToString().Split(" ") | Select-Object -Index 1
}
if (-not $hostKeyFingerprint) {
Write-Host "Failed to parse fingerprint."
exit 1
}
$fullHostKey = "ssh-ed25519 255 $hostKeyFingerprint"
Write-Host "Using host key fingerprint: $fullHostKey"
# === STEP 2: Retrieve remote backup list ===
Write-Host "Fetching file list from remote Unifi device..."
try {
$unifiBackups = & "$plinkPath" `
-ssh `
-pw $password `
-batch `
-noagent `
-hostkey "$fullHostKey" `
"$unifiUserRoot@$unifiDevice" `
"ls -1 $unifiBackupDir"
} catch {
Write-Host "Failed to retrieve remote file list: $_"
exit 1
}
if (-not $unifiBackups) {
Write-Host "No backup files found or SSH command failed."
exit 1
}
# === STEP 3: Retrieve local files ===
$localFiles = Get-ChildItem -Path $localDir -File | Select-Object -ExpandProperty Name
# === STEP 4: Compare and download missing backups ===
$missingBackups = $unifiBackups | Where-Object { $_ -and ($_ -notin $localFiles) }
if ($missingBackups.Count -eq 0) {
Write-Host "All backups are already present locally. Nothing to download."
exit 0
}
foreach ($file in $missingBackups) {
$remoteFilePath = "$unifiBackupDir/$file"
$localFilePath = Join-Path $localDir $file
Write-Host "Downloading: $file"
try {
$remoteFullPath = "$unifiUserRoot@$unifiDevice" + ":$remoteFilePath"
$arguments = @(
'-pw', $password,
'-batch',
'-noagent',
'-hostkey', $fullHostKey,
$remoteFullPath,
$localFilePath
)
& "$pscpPath" @arguments
}
catch {
Write-Host "Failed to download $file : $_"
}
}
Write-Host "All missing backup files have been downloaded successfully."
Résumé
Ce script PowerShell automatise les sauvegardes de configuration Unifi via SSH.
Il assure que les sauvegardes de votre appareil Unifi sont mirrorées de manière sécurisée sur un serveur LAN, minimisant le risque de perte de configuration.