Pour LiNotes, LiChat, LiDio et tout serveur perso

Ton serveur.
Ta forteresse.

Avoir son propre serveur, c’est décider soi-même de ses données.
Voici comment le protéger contre les accès étrangers, couche par couche.

Une défense en couches

Aucune protection ne bloque tout à elle seule. C’est pourquoi les spécialistes de la sécurité construisent leurs systèmes en couches : matériel, réseau, système d’exploitation, services, données. Si une couche tombe, la suivante tient. Nous appliquons ce principe au serveur de la maison.

Ce guide s’inspire de normes publiques : MIL-STD-882E (évaluer les risques), les DISA STIGs du ministère américain de la Défense (règles de durcissement, catégories CAT I à III), NIST SP 800-53, les CIS Benchmarks et le compendium IT-Grundschutz du BSI (Office fédéral allemand de la sécurité de l’information). Il ne remplace pas un audit et n’est pas une certification.

1 · Évaluer le risque

Par quoi commencer

MIL-STD-882E évalue chaque danger avec deux questions. Quelle serait la gravité ? Quelle est la probabilité ? Ce qui est rouge passe en premier.

1 · Catas­trophique
2 · Critique
3 · Marginal
4 · Négli­geable
A · Fréquent
Élevé
Élevé
Sérieux
Moyen
B · Probable
Élevé
Élevé
Sérieux
Moyen
C · Occa­sionnel
Élevé
Sérieux
Moyen
Faible
D · Rare
Sérieux
Moyen
Moyen
Faible
E · Impro­bable
Moyen
Moyen
Moyen
Faible

Élevé : accès ouvert

Connexion par mot de passe depuis Internet, root autorisé à se connecter, pas de mises à jour. Catastrophique et tenté sans arrêt. À fermer en premier.

Sérieux : trop de choses visibles

Base de données ou page d’administration ouverte sur le réseau, numéros de version dans chaque réponse. Qui cherche trouve.

Moyen : vol

Rare, mais critique quand ça arrive : la machine disparaît avec son disque. Le chiffrement et le gardien 3 sont là pour ça.

2 · La solution en un bouton

Un script pour tout

Pour Debian, Ubuntu et Raspberry Pi OS. Il montre d’abord ce qui manque, puis te demande ton accord et sauvegarde chaque fichier avant de le modifier. Il ne te bloque pas dehors : les mots de passe restent autorisés tant qu’aucune clé SSH n’est enregistrée.

Somme de contrôle (SHA-256) de haerten.sh 1.1 :
feb071563810198c9d7f30d8e7360a96742ad0791d03d7e5b405b150e17da724
La commande télécharge le script, vérifie la somme de contrôle et l’ouvre pour que tu le lises. Si elle n’affiche pas « OK », arrête tout. Ensuite, lance-le toi-même avec sudo bash haerten.sh.

Terminal
$ sudo bash haerten.shÉtat des lieux (Debian GNU/Linux 12)  ✘ mises à jour de sécurité auto désactivées  ✘ aucun pare-feu actif (ufw)  ✘ SSH : connexion par mot de passe autorisée  ✔ clé SSH enregistrée pour utilisateurContinuer ? [j/N] j1 · Mises à jour de sécurité auto  ✔2 · Pare-feu : SSH (limité), 80, 443  ✔3 · SSH : clé seulement, pas de root  ✔4 · fail2ban  ✔5 · Noyau  ✔6 · nginx : version masquée  ✔! Ouvre un second terminal et reconnecte-toi.

Ce qu’il fait

  • Mises à jour : les correctifs de sécurité s’installent tout seuls. STIG CAT II
  • Pare-feu : tout est fermé en entrée, sauf SSH (limité), 80 et 443. NIST SC-7
  • SSH : pas de root, clé seulement, moins de tentatives. STIG CAT I
  • fail2ban : qui se trompe trop souvent reste dehors une heure, les récidivistes une semaine. NIST AC-7
  • Noyau : pas de redirections, pas de fuites d’adresses, liens protégés. CIS 3.x
  • nginx : pas de numéro de version, une base pour les en-têtes de sécurité. OWASP

Juste regarder, sans rien changer : sudo bash haerten.sh --pruefen. Sauter une étape : --ohne firewall. Ports supplémentaires : --port 8448. Le script lui-même affiche ses messages en allemand. Les lignes du terminal ci-contre sont traduites.

D’abord lire, ensuite exécuter. Lancer avec sudo un script venu d’Internet, c’est une question de confiance. C’est pourquoi même le bouton ci-dessus n’exécute rien : il télécharge le script, vérifie la somme de contrôle et te le montre. C’est toi qui le lances. Il est court et commenté. Le code source est aussi sur cette page.

3 · Étape par étape

Tu préfères le terminal ?

Les mêmes étapes, à la main. Comme ça, tu sais ce que fait chaque ligne.

Mises à jour de sécurité automatiques STIG CAT II

La plupart des intrusions exploitent des failles corrigées depuis longtemps par une mise à jour.

Terminal
$ sudo apt update && sudo apt install -y unattended-upgrades
$ sudo dpkg-reconfigure -plow unattended-upgrades

Une clé SSH plutôt qu’un mot de passe STIG CAT I

Crée une clé sur ton propre ordinateur et copie-la sur le serveur. Ensuite, vérifie dans une deuxième fenêtre que la connexion marche sans mot de passe.

Terminal (ton ordinateur)
$ ssh-keygen -t ed25519
$ ssh-copy-id benutzer@dein-server

Verrouiller SSH STIG CAT I

Seulement une fois que la connexion par clé marche : bloquer root, désactiver les mots de passe, limiter les tentatives.

Terminal
$ printf 'PermitRootLogin no\nPasswordAuthentication no\n…' \
    | sudo tee /etc/ssh/sshd_config.d/10-haerten.conf
$ sudo sshd -t && sudo systemctl reload ssh

Pare-feu : seulement le nécessaire NIST SC-7

Tout fermer, puis ouvrir au cas par cas. Vérifie d’abord ton port SSH : sudo sshd -T | grep ^port. Si ce n’est pas 22, remplace le nombre ci-dessous, sinon tu te bloques dehors. Attention avec Docker : les ports publiés des conteneurs contournent ufw. Lie donc tes conteneurs à 127.0.0.1 et ne laisse que nginx exposé à l’extérieur.

Terminal
$ sudo apt install -y ufw
$ sudo ufw default deny incoming
$ sudo ufw limit 22/tcp && sudo ufw allow 80,443/tcp
$ sudo ufw enable

Bloquer les tentatives ratées NIST AC-7

Terminal
$ sudo apt install -y fail2ban
$ printf '[sshd]\nenabled = true\nbackend = systemd\n…' \
    | sudo tee /etc/fail2ban/jail.d/haerten.local
$ sudo systemctl restart fail2ban

Chiffrer le disque NIST SC-28

Le mieux, c’est dès l’installation : choisis « LVM chiffré » (LUKS). Sans la clé, un voleur ne peut alors pas lire tes données. Pour un serveur sans écran, tu peux le déverrouiller par SSH au démarrage (paquet dropbear-initramfs).

Serveur web : en-têtes et pas de numéro de version OWASP ASVS

Terminal
$ echo 'server_tokens off;' | sudo tee /etc/nginx/conf.d/server-tokens.conf
$ sudo nginx -t && sudo systemctl reload nginx

Ajoute aussi dans chaque bloc HTTPS : Strict-Transport-Security, Content-Security-Policy, X-Content-Type-Options nosniff, Referrer-Policy no-referrer, Permissions-Policy. Prudence : une Content-Security-Policy stricte bloque les scripts en ligne et les sources externes, teste-la d’abord. N’ajoute includeSubDomains à HSTS que si chaque sous-domaine a HTTPS. Et un add_header dans un bloc location y annule tous les en-têtes hérités.

Sauvegarde, rangée à part NIST CP-9

3-2-1 : trois copies, deux supports, une hors de la maison, chiffrée (par exemple avec restic ou borg). Et une fois par trimestre, entraîne-toi à restaurer. Seul un essai de restauration montre si la sauvegarde est complète.

4 · Les trois gardiens

Qui veille quand tu dors ?

Sécuriser, c’est le début. Les gardiens remarquent quand quelque chose arrive malgré tout, et ils agissent. Du logiciel au matériel, jusqu’à l’alarme sur la baie du serveur.

👁

Gardien 1 · Logiciel

Un petit script sur le serveur, lancé toutes les deux minutes par un timer systemd :

  • Les services et conteneurs tournent, sinon il les redémarre
  • Le site répond
  • Le certificat est encore valable 14 jours
  • Disque sous 90 %, température sous 80 °C
  • Alerte vers ton propre serveur ntfy ou par mail, une fois par heure au plus

waechter.sh · .service · .timer · Réglages · alarm-ntfy.sh

⏱

Gardien 2 · Matériel et gardien distant

Et si le serveur lui-même se fige ? Le watchdog matériel intégré à la puce le redémarre quand le système ne répond plus pendant 15 secondes.

Et s’il tombe complètement en panne, seul un gardien distant sur un deuxième appareil s’en aperçoit. Il vérifie depuis l’extérieur l’accessibilité, le DNS et les ports ouverts, et signale tout ce qui sort de l’ordinaire.

watchdog.conf · fernwaechter.sh

🚨

Gardien 3 · Anti-intrusion

Une centrale d’alarme avec ESP32-C6 et Zigbee : contact de porte, capteur de vibration et capteur anti-sabotage sur la baie du serveur.

En cas d’alarme, elle coupe le courant du serveur pour que le disque chiffré devienne inutilisable. Elle redirige ta page d’accueil vers une copie sur GitHub, pour que ton site reste accessible, et donne l’alarme sur ton téléphone.

Partie A (ESP32-C6) · Partie B (Wi-Fi)

Gardien 3 : le déroulé en cas d’intrusion

🚪
T + 0 sPorte, vibration ou sabotage
⏳
jusqu’à 30 sPréalarme : désarmer avec la clé
📣
AlarmeSirène, message à la partie B
🌐
+ quelques sDNS : la page d’accueil pointe vers GitHub Pages
⚡
+ 20 sZigbee : courant du serveur coupé
Contact de porteGPIO 4 · reed, NF VibrationGPIO 5 · SW-420 Sabotage (boîtier)GPIO 6 Interrupteur à cléGPIO 7 · armé/désarmé Sirène 12 VGPIO 10 → MOSFET ESP32-C6Partie A · centraleCoordinateur Zigbee onduleur / batterieboîtier verrouillé Zigbee : on/off Prise Zigbeecertifiée, 230 Vou relais en 5/12 V CC ServeurDisque LUKSCourant coupé= données sûres UART « ALARM » ESP32 avec Wi-FiPartie B · redirectionJeton limité à 1 entréeTLS + certificat racine DNS : www → GitHub PagesTTL courte (60–300 s)

Pourquoi deux ESP32 ?

L’ESP32-C6 parle Zigbee et surveille les capteurs. Un deuxième ESP32 avec Wi-Fi modifie l’entrée DNS en cas d’alarme. Ainsi, le Wi-Fi ne perturbe jamais la liaison radio vers la prise, et si une partie tombe en panne, l’autre continue de fonctionner.

Construire sans danger

  • Pas de bricolage sur le 230 V : prends une prise Zigbee certifiée, ou un relais placé uniquement sur le circuit basse tension (5/12 V).
  • Une alimentation à part pour la centrale (onduleur ou batterie), pour que le cambrioleur ne puisse pas simplement la débrancher.
  • Un jeton aux droits minimaux : il ne peut modifier que cette seule entrée DNS. Active le chiffrement de la flash sur l’ESP32.
  • Chiffrer le disque (LUKS) : c’est seulement grâce à ça que « courant coupé » rend les données inutiles pour le voleur.
  • Prévoir les fausses alertes : pour le serveur, « courant coupé » est une panne de courant. Un système de fichiers journalisé (ext4), des bases de données avec journal de transactions et une sauvegarde quotidienne y répondent.
  • Préparer un plan B : une copie de la page d’accueil sur GitHub Pages dans un dépôt public, et un TTL DNS court.

Pour être honnêtes : les programmes du gardien 3 compilent sans erreur (arduino-esp32 3.3.12), mais nous ne les avons pas testés en continu sur du vrai matériel. Teste le montage avant de compter dessus. Un brouillage de la liaison Zigbee peut empêcher la coupure. Retiens donc ceci : la vraie protection, c’est le chiffrement du disque. Le gardien n’est que la deuxième couche.

L’alarme sur ton téléphone

Forte, insistante et même en mode « Ne pas déranger », un peu comme une alerte officielle. ntfy y arrive avec sa priorité la plus haute. Le gardien 3 envoie l’alarme directement depuis l’ESP32, car le serveur n’a alors plus de courant. Les gardiens 1 et 2 utilisent le script.

Terminal
$ curl -fsSLo alarm-ntfy \
    https://lisoftware.de/sicherheit/waechter/alarm-ntfy.sh
$ echo '3aa63d7fe351ea39795a9d21a7bad644a5e94ab8ae9c9843ad076e99cedfae3d  alarm-ntfy' | sha256sum -c
$ sudo install -m 755 alarm-ntfy /usr/local/bin/
$ sudoedit /etc/default/alarm-ntfy   # NTFY_URL, NTFY_TOKEN
$ sudo alarm-ntfy --test
$ sudo alarm-ntfy "Porte de la baie serveur ouverte"

Régler le téléphone

  • Appli ntfy : installe-la (F-Droid, Google Play ou App Store), ajoute ton serveur ntfy et abonne-toi au topic. Sous Android, active « Livraison instantanée » pour l’abonnement.
  • Ton propre serveur avec un jeton : sur le service public ntfy.sh, toute personne qui connaît le nom du topic peut lire et envoyer de fausses alertes. Utilise donc ton propre serveur ntfy avec un jeton d’accès et un topic long et aléatoire.
  • Android : Paramètres → Notifications → ntfy → le canal de priorité maximale : autorise-le à passer outre « Ne pas déranger ». Dans l’appli, active le réglage qui fait sonner en continu pour la priorité maximale.
  • iPhone : ajoute ntfy aux applis autorisées sous Concentration → « Ne pas déranger ». Pour être honnêtes : avec ton propre serveur, les notifications instantanées n’arrivent que s’il envoie un signal de réveil via ntfy.sh et Apple grâce à upstream-base-url. Ce signal ne contient aucun texte, mais une empreinte du topic. À toi de décider si tu utilises ce service.
  • Alarme d’essai avec sudo alarm-ntfy --test, puis une fois par mois.

Aucune appli ne peut déclencher une vraie alerte officielle (cell broadcast). Une alarme ntfy de priorité maximale s’en approche le plus.

5 · Faire vérifier

Tester ton propre serveur

Les outils et sites les plus connus pour tester ton serveur face aux normes. Les tests en ligne voient ton adresse. Si tu ne le veux pas, utilise les outils qui tournent sur ta propre machine.

NormeDe quoi il s’agitVérifier avec
DISA STIGRègles de durcissement du ministère américain de la Défense, de CAT I (critique) à CAT IIISTIGs et STIG Viewer · OpenSCAP avec profil STIG · NIST National Checklist Program
CIS BenchmarksDurcissement consensuel pour Linux, Docker, nginxLynis (libre, en local) · CIS-CAT
NIST SP 800-53Catalogue des mesures de sécurité (AC, SC, CP …)Catalogue · OpenSCAP · NVD pour les failles connues
TLS : BSI TR-02102-2 · NIST SP 800-52r2Chiffrement de la connexion, certificat, protocolestestssl.sh (en local) · SSL Labs (coche « Do not show the results ») · internet.nl
OWASP Secure Headers · ASVSEn-têtes de sécurité et application webMozilla HTTP Observatory · securityheaders.com · OWASP ZAP
BSI IT-GrundschutzNorme allemande de sécurité de l’informationCompendium et listes de contrôle · internet.nl (web et mail)
CVE / failles connuesMes paquets ont-ils des vulnérabilités connues ?Debian Security Tracker · Ubuntu Security Notices · CVE.org
Surface d’attaque externeQue voit Internet de mon serveur ?Shodan · Censys · nmap depuis un autre réseau
DNSDNSSEC et enregistrementsDNSViz
MIL-STD-882ELa sécurité comme système : trouver les dangers, les évaluer, les réduirePas de scanner. Utilise la matrice des risques plus haut, avec tous les résultats des autres outils.