Configuration de l'ODROID HC4 avec Debian 13 en tant que NAS

Introduction

Ce guide détaille la mise en place d'un NAS complet et sécurisé basé sur l'ODROID HC4 avec Debian 13.
La configuration inclut un RAID 1 chiffré avec LUKS et Btrfs, l'accès distant via ZeroTier, les partages SMB sécurisés,
ainsi qu'un système de monitoring complet avec alertes push via Ntfy.sh.


Installation de Debian 13

Installer Debian 13 via petitboot, directement en branchant l'ODROID au réseau, avec un écran et un clavier et ne pas oublier de spécifier les éléments suivants durant l'installation :


Sécurisation du BIOS/UEFI

Ne pas oublier de spéicifier un mot de passe maître pour le BIOS/UEFI pour empêcher l'accès ou le démarrage sur autre chose.


Premier démarrage

Lors du premier boot :


Mise à jour du système

Régler le nameserver sur Cloudflare ou Google

echo "nameserver 1.1.1.1" > /etc/resolv.conf

Mises à jour et outils de base

apt update ; apt upgrade -y ; apt install -y vim curl htop tree man-db ; apt autoremove -y ; reboot

Modification des mots de passe

passwd root
passwd adminastor

Boot silencieux sur Debian 13

Configuration pour un démarrage sans affichage sur écran local (fresh install, en root).

Désactiver le délai GRUB

sed -i 's/^GRUB_TIMEOUT=.*/GRUB_TIMEOUT=0/' /etc/default/grub
sed -i 's/^#\?GRUB_TIMEOUT_STYLE=.*/GRUB_TIMEOUT_STYLE=hidden/' /etc/default/grub

Bloquer l'authentification PAM sur les consoles locales

echo "-:ALL:LOCAL" >> /etc/security/access.conf
sed -i '/@include common-account/i account requisite pam_access.so' /etc/pam.d/login

Désactiver les TTY (supprime le prompt "login:")

for i in {1..6}; do
 systemctl disable getty@tty$i.service
 systemctl stop getty@tty$i.service
done

Masquer les messages kernel et systemd

sed -i 's/^GRUB_CMDLINE_LINUX_DEFAULT=.*/GRUB_CMDLINE_LINUX_DEFAULT="quiet loglevel=0 rd.loglevel=0 vt.global_cursor_default=0"/' /etc/default/grub
update-grub

Masquer le message fsck

sed -i 's|logsave -a -s $FSCK_LOGFILE fsck $spinner $force $fix -V -t "$TYPE" "$DEV"|logsave -a $FSCK_LOGFILE fsck $spinner $force $fix -V -t "$TYPE" "$DEV" >/dev/null 2>\&1|' /usr/share/initramfs-tools/scripts/functions
sed -i 's|logsave -a -s $FSCK_LOGFILE fsck $spinner $force $fix -T -t "$TYPE" "$DEV"|logsave -a $FSCK_LOGFILE fsck $spinner $force $fix -T -t "$TYPE" "$DEV" >/dev/null 2>\&1|' /usr/share/initramfs-tools/scripts/functions
update-initramfs -u

Appliquer les modifications

reboot

À partir de là, il n'est plus possible de s'authentifier avec un écran. Tout par SSH.


Création du RAID 1 chiffré avec LUKS et Btrfs

Identifier les disques pour le RAID

lsblk

Nous prendrons /dev/sdb et /dev/sdc en exemple pour les 2 disques du futur RAID.
Le schéma est simple :

Installer les paquets nécessaires

apt update && apt install -y cryptsetup btrfs-progs

Créer le conteneur LUKS sur les deux disques

PASS="mettre-ici-une-passphrase"
echo -n "$PASS" | cryptsetup luksFormat -q /dev/sdb --key-file -
echo -n "$PASS" | cryptsetup luksFormat -q /dev/sdc --key-file -

Vérifier la bonne création du conteneur

clear ; echo "# /dev/sdb" ; cryptsetup luksDump /dev/sdb | head -5 ; echo ; echo ; echo "# /dev/sdc" ; cryptsetup luksDump /dev/sdc | head -5 ; echo

Ouvrir les 2 conteneurs LUKS créés

echo -n "$PASS" | cryptsetup open /dev/sdb crypt1 --key-file -
echo -n "$PASS" | cryptsetup open /dev/sdc crypt2 --key-file -
clear ; echo "# Vérification" ; echo ; ls /dev/mapper/ | grep crypt ; echo

Initialisation sécurisée (optionnel mais recommandé)

Remplit les conteneurs avec des zéros qui seront chiffrés rendant impossible la distinction entre espace libre et données.

dd if=/dev/zero of=/dev/mapper/crypt1 bs=1M status=progress
dd if=/dev/zero of=/dev/mapper/crypt2 bs=1M status=progress

Créer le système de fichiers Btrfs en RAID1

mkfs.btrfs -m raid1 -d raid1 /dev/mapper/crypt1 /dev/mapper/crypt2

Monter le système de fichiers

mkdir -p /mnt/data
mount /dev/mapper/crypt1 /mnt/data
echo ; echo "# Vérification" ; btrfs filesystem show /mnt/data ; echo

Script de montage manuel

Script pour déchiffrer et remonter le volume lors du redémarrage du serveur :

cat << 'EOF' > /usr/local/sbin/mount-raid
#!/bin/bash
read -s -p "Passphrase LUKS : " PASS
echo
echo -n "$PASS" | cryptsetup open /dev/sdb crypt1 --key-file -
echo -n "$PASS" | cryptsetup open /dev/sdc crypt2 --key-file -
unset PASS
mount /dev/mapper/crypt1 /mnt/data
echo
echo "# Le RAID est monté sur /mnt/data"
echo
EOF
chmod 700 /usr/local/sbin/mount-raid

Lors du redémarrage, il suffit de taper :

mount-raid

Script de démontage

Script pour démonter et chiffrer :

cat << 'EOF' > /usr/local/sbin/umount-raid
#!/bin/bash
umount /mnt/data
cryptsetup close crypt1
cryptsetup close crypt2
echo
echo "Le RAID est démonté et verrouillé"
echo
EOF
chmod 700 /usr/local/sbin/umount-raid

Pour chiffrer et démonter :

umount-raid

Mise en place de ZeroTier

Installer ZeroTier

wget -qO - https://install.zerotier.com | bash

Rejoindre le réseau

NETWORK_ID="copier-ici-lID-du-reseau-à-rejoindre"
zerotier-cli join "$NETWORK_ID"

Autoriser la machine sur my.zerotier.com et noter l'IP de la machine dans ZeroTier (exemple : 10.20.30.10).

Démarrage automatique de ZeroTier

systemctl enable zerotier-one
systemctl status zerotier-one
zerotier-cli listnetworks

Configuration de Samba

Installation

apt install samba -y

Sauvegarder la configuration actuelle

cp /etc/samba/smb.conf /etc/samba/smb.conf.bak

Configuration durcie

Noter les réseaux locaux et ZeroTier puis créer le fichier de configuration durci complet :

NETWORK_LOCAL="192.168.25.0/24"
NETWORK_ZT="10.20.30.10/24"

cat << EOF > /etc/samba/smb.conf
[global]
 # Protocole minimum SMB3
 server min protocol = SMB3
 client min protocol = SMB3
 
 # Chiffrement obligatoire
 server smb encrypt = required
 
 # Désactiver les invités
 map to guest = Never
 restrict anonymous = 2
 
 # Désactiver NetBIOS (obsolète)
 disable netbios = yes
 smb ports = 445
 
 # Restriction d'accès réseau
 hosts allow = ${NETWORK_LOCAL} ${NETWORK_ZT} 127.0.0.1
 hosts deny = all

 # Journalisation
 log file = /var/log/samba/log.%m
 max log size = 1000
 log level = 2
 
 # Permissions strictes
 create mask = 0600
 directory mask = 0700
 
 # Désactiver les fonctionnalités inutiles
 load printers = no
 printing = bsd
 printcap name = /dev/null

 # Performance
 use sendfile = yes
 aio read size = 1
 aio write size = 1
EOF

testparm -s && systemctl restart smbd

Durcissement SSH

Configuration SSH sécurisée avec passage au port 51345.

Sauvegarder le fichier de base

cp /etc/ssh/sshd_config /etc/ssh/sshd_config.BAK

Créer le fichier de configuration personnalisé

cat << 'EOF' > /etc/ssh/sshd_config
# Port personnalisé
Port 51345

# Protocole et algorithmes sécurisés
HostKey /etc/ssh/ssh_host_ed25519_key
KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com
MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com

# Authentification
PermitRootLogin prohibit-password
PasswordAuthentication yes
PermitEmptyPasswords no
PubkeyAuthentication yes
AuthenticationMethods publickey password
MaxAuthTries 3
LoginGraceTime 30

# Désactiver ce qui n'est pas nécessaire
KbdInteractiveAuthentication no
KerberosAuthentication no
GSSAPIAuthentication no
HostbasedAuthentication no
IgnoreRhosts yes
X11Forwarding no
AllowTcpForwarding no
AllowAgentForwarding no
PermitTunnel no
PermitUserEnvironment no

# Pas de SFTP
Subsystem sftp /bin/false

# Aucun message
PrintMotd no
PrintLastLog no
Banner none

# Sécurité réseau
TCPKeepAlive no
ClientAliveInterval 300
ClientAliveCountMax 2
MaxStartups 3:50:10
MaxSessions 2

# Journalisation
SyslogFacility AUTH
LogLevel VERBOSE

# PAM (nécessaire pour les mots de passe)
UsePAM yes
EOF

rm -f /etc/ssh/sshd_config.d/*.conf
sshd -t && systemctl restart sshd

Test de connexion

Ouvrir une session SSH avec le nouveau port depuis un client :

ssh -p51345 adminastor@IP-DU-NAS

Configuration du pare-feu nftables

Configuration avec blocage rate-limit pour protection contre le bruteforce.

apt install -y nftables
systemctl enable nftables

cat << 'EOF' > /etc/nftables.conf
#!/usr/sbin/nft -f

flush ruleset

table inet filter {
 set ssh_bruteforce {
 type ipv4_addr
 flags dynamic,timeout
 timeout 15m
 }
 
 chain input {
 type filter hook input priority 0; policy drop;
 
 # Loopback
 iif lo accept
 
 # Connexions établies
 ct state established,related accept
 
 # Bloquer les IP en bruteforce
 ip saddr @ssh_bruteforce drop
 
 # SSH avec rate-limit (max 3 nouvelles connexions/minute)
 tcp dport 51345 ct state new limit rate 3/minute burst 5 packets accept
 tcp dport 51345 ct state new add @ssh_bruteforce { ip saddr } drop
 
 # SMB
 tcp dport 445 accept
 
 # ZeroTier
 udp dport 9993 accept
 
 # Ping
 icmp type echo-request accept
 }
 
 chain forward {
 type filter hook forward priority 0; policy drop;
 }
 
 chain output {
 type filter hook output priority 0; policy accept;
 }
}
EOF

nft -f /etc/nftables.conf

Ouvrir une connexion SSH pour tester avant de refermer celle en cours.


Entretiens périodiques de Btrfs

Vérification/réparation d'intégrité des données du RAID 1 (scrub) et rééquilibrage.

cat << 'EOF' > /etc/cron.d/btrfs-maintenance
# Scrub mensuel (1er dimanche du mois à 3h)
0 3 1-7 * 0 root /usr/bin/btrfs scrub start /mnt/data

# Balance mensuel (15 du mois à 3h)
0 3 15 * * root /usr/bin/btrfs balance start -dusage=50 -musage=50 /mnt/data
EOF

Mise en place de Ntfy.sh pour les notifications

Configuration du service de notifications push gratuites.

Configuration préalable

Installation sur le serveur

apt install curl -y

Tester l'envoi d'une notification

TOPIC="mynas_AvpiaininzfzZemibn2VzrBIN"
curl -d "Coucou" ntfy.sh/"$TOPIC"

Le message est reçu sur le navigateur web (si les notifications sont autorisées) et sur le smartphone.

Script central pour toutes les alertes

TOPIC="mynas_AvpiaininzfzZemibn2VzrBIN"

cat << EOF > /usr/local/sbin/ntfy-send
#!/bin/bash
TOPIC="$TOPIC"
curl -s -d "\$1" ntfy.sh/\$TOPIC
EOF
chmod +x /usr/local/sbin/ntfy-send

Monitoring et notifications SMART

Installer smartmontools

apt install smartmontools -y

Répondre N (choix par défaut)

Script d'alerte pour les erreurs SMART

TOPIC="mynas_AvpiaininzfzZemibn2VzrBIN"

cat << EOF > /usr/local/sbin/smart-alert
#!/bin/bash
# Alerte SMART via ntfy

MESSAGE="⚠️ Alerte SMART sur $(hostname)
Disque: \$SMARTD_DEVICE
Problème: \$SMARTD_MESSAGE"

# Sans authentification :
curl -s -d "\$MESSAGE" ntfy.sh/"$TOPIC"
EOF

chmod +x /usr/local/sbin/smart-alert
systemctl enable smartd
systemctl restart smartd
systemctl status smartd

Configurer smartd

cat << 'EOF' > /etc/smartd.conf
/dev/sdb -a -o on -S on -W 4,45,50 -m @smart-alert -M exec /usr/local/sbin/smart-alert
/dev/sdc -a -o on -S on -W 4,45,50 -m @smart-alert -M exec /usr/local/sbin/smart-alert
EOF

Tester l'envoi de notification

SMARTD_DEVICE="/dev/sdb" SMARTD_MESSAGE="Test secteurs défectueux" /usr/local/sbin/smart-alert

À partir de maintenant, les erreurs SMART détectées (en continu) seront immédiatement envoyées en tant que notifications push.


Monitoring et notifications usuelles

Alerte espace disque

cat << 'EOF' > /usr/local/sbin/check-disk
#!/bin/bash
WARN=70
CRIT=90
USAGE=$(df /mnt/data 2>/dev/null | awk 'NR==2 {gsub("%",""); print $5}')

if [ -n "$USAGE" ]; then
 if [ "$USAGE" -ge "$CRIT" ]; then
 /usr/local/sbin/ntfy-send "🔴 CRITIQUE - NAS $(hostname) : Espace disque ${USAGE}% sur /mnt/data"
 elif [ "$USAGE" -ge "$WARN" ]; then
 /usr/local/sbin/ntfy-send "🟠 AVERTISSEMENT - NAS $(hostname) : Espace disque ${USAGE}% sur /mnt/data"
 fi
fi
EOF
chmod +x /usr/local/sbin/check-disk

Alerte santé Btrfs (après scrub)

cat << 'EOF' > /usr/local/sbin/check-btrfs
#!/bin/bash
ERRORS=$(btrfs device stats /mnt/data 2>/dev/null | awk '$2 > 0 {count++} END {print count+0}')

if [ "$ERRORS" -gt 0 ]; then
 DETAILS=$(btrfs device stats /mnt/data | grep -v ' 0$')
 /usr/local/sbin/ntfy-send "🔴 CRITIQUE - NAS $(hostname) : Erreurs Btrfs détectées
$DETAILS"
fi
EOF
chmod +x /usr/local/sbin/check-btrfs

Alerte services arrêtés

cat << 'EOF' > /usr/local/sbin/check-services
#!/bin/bash
SERVICES="smbd sshd zerotier-one"

for SERVICE in $SERVICES; do
 if ! systemctl is-active --quiet $SERVICE; then
 /usr/local/sbin/ntfy-send "🔴 CRITIQUE - NAS $(hostname) : Service $SERVICE arrêté !"
 fi
done
EOF
chmod +x /usr/local/sbin/check-services

Alerte redémarrage système

cat << 'EOF' > /usr/local/sbin/notify-reboot
#!/bin/bash
sleep 60
IP=$(hostname -I | awk '{print $1}')
UPTIME=$(uptime -p)
/usr/local/sbin/ntfy-send "🔵 INFO - NAS $(hostname) a redémarré
IP: $IP
$UPTIME"
EOF
chmod +x /usr/local/sbin/notify-reboot

cat << 'EOF' > /etc/systemd/system/notify-reboot.service
[Unit]
Description=Notification de redémarrage
After=network-online.target
Wants=network-online.target

[Service]
Type=oneshot
ExecStart=/usr/local/sbin/notify-reboot

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable notify-reboot

Tentatives SSH échouées

cat << 'EOF' > /usr/local/sbin/check-ssh-failures
#!/bin/bash
WARN=5
CRIT=15
FAILURES=$(journalctl -u sshd --since "1 hour ago" --no-pager 2>/dev/null | grep -c "Failed password\|Invalid user")

if [ "$FAILURES" -ge "$CRIT" ]; then
 DETAILS=$(journalctl -u sshd --since "1 hour ago" --no-pager | grep "Failed password\|Invalid user" | tail -5)
 /usr/local/sbin/ntfy-send "🔴 CRITIQUE - NAS $(hostname) : $FAILURES tentatives SSH échouées
$DETAILS"
elif [ "$FAILURES" -ge "$WARN" ]; then
 /usr/local/sbin/ntfy-send "🟠 AVERTISSEMENT - NAS $(hostname) : $FAILURES tentatives SSH échouées (dernière heure)"
fi
EOF
chmod +x /usr/local/sbin/check-ssh-failures

Charge système (CPU/RAM)

cat << 'EOF' > /usr/local/sbin/check-load
#!/bin/bash
LOAD_WARN=2
LOAD_CRIT=4
RAM_WARN=80
RAM_CRIT=95

LOAD=$(awk '{print int($2)}' /proc/loadavg)
RAM=$(free | awk '/Mem:/ {printf "%.0f", $3/$2 * 100}')

if [ "$LOAD" -ge "$LOAD_CRIT" ]; then
 /usr/local/sbin/ntfy-send "🔴 CRITIQUE - NAS $(hostname) : Charge CPU - Load: $LOAD"
elif [ "$LOAD" -ge "$LOAD_WARN" ]; then
 /usr/local/sbin/ntfy-send "🟠 AVERTISSEMENT - NAS $(hostname) : Charge CPU - Load: $LOAD"
fi

if [ "$RAM" -ge "$RAM_CRIT" ]; then
 /usr/local/sbin/ntfy-send "🔴 CRITIQUE - NAS $(hostname) : RAM ${RAM}% utilisée"
elif [ "$RAM" -ge "$RAM_WARN" ]; then
 /usr/local/sbin/ntfy-send "🟠 AVERTISSEMENT - NAS $(hostname) : RAM ${RAM}% utilisée"
fi
EOF
chmod +x /usr/local/sbin/check-load

Connectivité ZeroTier

cat << 'EOF' > /usr/local/sbin/check-zerotier
#!/bin/bash
STATUS=$(zerotier-cli status 2>/dev/null | awk '{print $5}')

if [ "$STATUS" != "ONLINE" ]; then
 /usr/local/sbin/ntfy-send "🔴 CRITIQUE - NAS $(hostname) : ZeroTier hors ligne - Status: $STATUS"
fi
EOF
chmod +x /usr/local/sbin/check-zerotier

Mises à jour de sécurité en attente

cat << 'EOF' > /usr/local/sbin/check-updates
#!/bin/bash
WARN=1
CRIT=10
apt update -qq 2>/dev/null
UPDATES=$(apt list --upgradable 2>/dev/null | grep -c security)

if [ "$UPDATES" -ge "$CRIT" ]; then
 /usr/local/sbin/ntfy-send "🔴 CRITIQUE - NAS $(hostname) : $UPDATES mises à jour de sécurité en attente"
elif [ "$UPDATES" -ge "$WARN" ]; then
 /usr/local/sbin/ntfy-send "🟠 AVERTISSEMENT - NAS $(hostname) : $UPDATES mises à jour de sécurité en attente"
fi
EOF
chmod +x /usr/local/sbin/check-updates

RAID Btrfs dégradé

cat << 'EOF' > /usr/local/sbin/check-raid
#!/bin/bash
# Vérifie que les deux disques du RAID1 sont présents

DEVICES=$(btrfs filesystem show /mnt/data 2>/dev/null | grep -c "devid")
MISSING=$(btrfs filesystem show /mnt/data 2>/dev/null | grep -c "missing")

if [ "$MISSING" -gt 0 ]; then
 /usr/local/sbin/ntfy-send "🔴 CRITIQUE - NAS $(hostname) : RAID dégradé - Disque manquant !"
elif [ "$DEVICES" -lt 2 ]; then
 /usr/local/sbin/ntfy-send "🔴 CRITIQUE - NAS $(hostname) : RAID dégradé - Seulement $DEVICES disque(s) détecté(s)"
fi
EOF
chmod +x /usr/local/sbin/check-raid

Température CPU (adapté pour l'ODROID HC4)

cat << 'EOF' > /usr/local/sbin/check-temp
#!/bin/bash
WARN=60
CRIT=75

# ODROID HC4 / Amlogic
if [ -f /sys/class/thermal/thermal_zone0/temp ]; then
 TEMP=$(($(cat /sys/class/thermal/thermal_zone0/temp) / 1000))
# Fallback autres SBC
elif [ -f /sys/class/hwmon/hwmon0/temp1_input ]; then
 TEMP=$(($(cat /sys/class/hwmon/hwmon0/temp1_input) / 1000))
else
 exit 0
fi

if [ "$TEMP" -ge "$CRIT" ]; then
 /usr/local/sbin/ntfy-send "🔴 CRITIQUE - NAS $(hostname) : Température CPU ${TEMP}°C"
elif [ "$TEMP" -ge "$WARN" ]; then
 /usr/local/sbin/ntfy-send "🟠 AVERTISSEMENT - NAS $(hostname) : Température CPU ${TEMP}°C"
fi
EOF
chmod +x /usr/local/sbin/check-temp

Surveillance d'intégrité des fichiers système

Installation d'inotify-tools

apt install -y inotify-tools

Script de surveillance en temps réel

cat << 'EOF' > /usr/local/sbin/watch-integrity
#!/bin/bash

FILES="
/etc/samba/smb.conf
/etc/ssh/sshd_config
/etc/nftables.conf
/etc/smartd.conf
/etc/passwd
/etc/shadow
/etc/group
/etc/sudoers
/etc/hosts
/etc/fstab
/etc/apt/sources.list
/root/.ssh/authorized_keys
"

DIRS="
/etc/cron.d
/etc/sudoers.d
/etc/apt/sources.list.d
/usr/local/sbin
"

# Construire la liste de surveillance
WATCH_LIST=""
for f in $FILES; do
 [ -f "$f" ] && WATCH_LIST="$WATCH_LIST $f"
done
for d in $DIRS; do
 [ -d "$d" ] && WATCH_LIST="$WATCH_LIST $d"
done

inotifywait -m -e modify,create,delete,move $WATCH_LIST 2>/dev/null | while read path action file; do
 /usr/local/sbin/ntfy-send "🔴 CRITIQUE - NAS $(hostname) : Modification détectée
Action: $action
Fichier: ${path}${file}"
done
EOF
chmod +x /usr/local/sbin/watch-integrity

Service systemd pour le démarrage automatique

cat << 'EOF' > /etc/systemd/system/watch-integrity.service
[Unit]
Description=Surveillance intégrité fichiers en temps réel
After=network.target

[Service]
Type=simple
ExecStart=/usr/local/sbin/watch-integrity
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable watch-integrity
systemctl start watch-integrity

Tâches cron pour les vérifications régulières

cat << 'EOF' > /etc/cron.d/nas-alerts
# Espace disque (toutes les 6h)
0 */6 * * * root /usr/local/sbin/check-disk

# Santé Btrfs (quotidienne à 4h)
0 4 * * * root /usr/local/sbin/check-btrfs

# RAID dégradé (toutes les 15 min)
*/15 * * * * root /usr/local/sbin/check-raid

# Services (toutes les 15 min)
*/15 * * * * root /usr/local/sbin/check-services

# SSH échoués (toutes les heures)
0 * * * * root /usr/local/sbin/check-ssh-failures

# Charge système (toutes les 10 min)
*/10 * * * * root /usr/local/sbin/check-load

# Température CPU (toutes les 10 min)
*/10 * * * * root /usr/local/sbin/check-temp

# ZeroTier (toutes les 15 min)
*/15 * * * * root /usr/local/sbin/check-zerotier

# Mises à jour (quotidienne à 8h)
0 8 * * * root /usr/local/sbin/check-updates
EOF

Installation de btop pour le monitoring d'appoint

apt install btop -y

Mises à jour de sécurité automatiques

Installation

apt install -y unattended-upgrades apt-listchanges

cat << 'EOF' > /etc/apt/apt.conf.d/20auto-upgrades
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";
APT::Periodic::AutocleanInterval "7";
EOF

Notification après mise à jour

cat << 'EOF' > /usr/local/sbin/notify-upgrades
#!/bin/bash
LOG="/var/log/unattended-upgrades/unattended-upgrades.log"
DPKG_LOG="/var/log/dpkg.log"

# Paquets mis à jour dans les 5 dernières minutes
PACKAGES=$(awk -v d="$(date -d '5 minutes ago' '+%Y-%m-%d %H:%M')" '$0 > d && /upgrade|install/ {print $4}' "$DPKG_LOG" 2>/dev/null | sort -u | tr '\n' ' ')

if [ -n "$PACKAGES" ]; then
 /usr/local/sbin/ntfy-send "🟢 INFO - NAS $(hostname) : Mises à jour installées
$PACKAGES"
fi
EOF
chmod +x /usr/local/sbin/notify-upgrades

Hook pour unattended-upgrades

cat << 'EOF' >> /etc/apt/apt.conf.d/50unattended-upgrades

// Notification après mise à jour
Unattended-Upgrade::Post-Invoke {
 "/usr/local/sbin/notify-upgrades";
};

// Redémarrage auto si nécessaire
Unattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-Time "04:00";
EOF

Réplication vers un second NAS

Ne pas oublier de mettre en place une réplication vers un second NAS.
Utiliser rsync, car les snapshots Btrfs imposeront une structure différente sur le NAS No.2.

Prérequis

Mettre en place une connexion SSH par clef entre le NAS No.1 et le NAS No.2 avec l'utilisateur root.
(Depuis le NAS No.1 en root, il faut pouvoir se connecter au NAS No.2 en root sans mot de passe)

Script de réplication

(Adapter les variables avant de copier/coller !)

cat << 'EOF' > /usr/local/sbin/replicate-to-nas2
#!/bin/bash
SRC="/mnt/data/"
DEST_HOST="root@IP-ZEROTIER-NAS2"
DEST_PORT="51345"
DEST_PATH="/mnt/data/"

rsync -az --delete -e "ssh -p $DEST_PORT" --exclude=".snapshots" "$SRC" "$DEST_HOST:$DEST_PATH"

if [ $? -eq 0 ]; then
 /usr/local/sbin/ntfy-send "🟢 INFO - $(hostname) : Réplication vers NAS2 réussie"
else
 /usr/local/sbin/ntfy-send "🔴 ERREUR - $(hostname) : Échec réplication vers NAS2"
fi
EOF
chmod 700 /usr/local/sbin/replicate-to-nas2

Tâche cron pour la réplication

cat << 'EOF' >> /etc/cron.d/nas-alerts
# Réplication vers NAS2 (quotidienne à 1h)
0 1 * * * root /usr/local/sbin/replicate-to-nas2
EOF

Création d'un utilisateur et partage SMB

Créer l'utilisateur et son dossier sur le RAID

(USER1 est l'utilisateur exemple ici. À adapter)

USERID="USER1"
useradd -M -s /usr/sbin/nologin $USERID
mkdir -p /mnt/data/$USERID
chown $USERID:$USERID /mnt/data/$USERID
smbpasswd -a $USERID

cat << EOF >> /etc/samba/smb.conf

[$USERID]
 path = /mnt/data/$USERID
 browseable = yes
 read only = no
 valid users = $USERID

EOF

testparm -s && systemctl restart smbd

Montage du partage SMB sur macOS

Pour ZeroTier, il faudra rejoindre le réseau et contacter le partage via l'IP ZeroTier du serveur Debian.


Conclusion

La configuration est terminée. Le NAS est maintenant opérationnel avec :



↑ Haut de page