Publier le NAS sur Internet (accès externe)
17 min · 8 rubriques
Ce guide fait de ton NAS ton cloud : un nom à toi (micasa.duckdns.org), un certificat valide et un accès depuis n’importe où sans avertissement du navigateur. Effet secondaire : l’interface peut s’installer comme application (PWA) ; avec un certificat autosigné, le navigateur limite le service worker, avec un certificat valide, non.
Le chemin compte quatre étapes, dans cet ordre :
- Ouvrir 80 et 443 sur le routeur (et seulement ceux-là).
- Un nom de domaine qui suit ton IP (DDNS).
- Obtenir le certificat Let's Encrypt.
- Publier le panneau et les apps avec le proxy inverse.
Publier le NAS est le changement qui ajoute le plus de surface d’attaque de toute sa vie. La section Sécurité n’est pas une annexe : lis-la avant d’ouvrir le premier port.
Si tu ne l’utilises qu’à la maison, il y a un chemin plus court
Si tu n’as pas besoin d’entrer depuis l’extérieur et que la seule chose qui te gêne est l’avertissement du navigateur —et de ne pas pouvoir installer le panneau comme application sur le téléphone—, rien de tout ça n’est nécessaire.
Ton NAS a son propre certificat. Dans Panneau de configuration → Accès externe → Certificat, il y a un bouton pour le télécharger, avec les étapes d’installation pour le dispositif depuis lequel tu regardes (iPhone, Android, Windows, Mac ou Linux). Installe-le sur chaque téléphone ou ordinateur depuis lequel tu entres et l’avertissement disparaît sur celui-ci ; ensuite, le panneau peut s’installer comme application.
Il faut le faire dispositif par dispositif —la confiance est propre à chacun— mais une seule fois : ça reste valable même si le NAS change d’adresse. Et garde en tête ce que tu dis en l’installant : ce dispositif fera confiance à tout site que ton NAS lui présentera. Sur un réseau domestique, c’est normal, mais ne l’installe que sur tes propres dispositifs.
Comment c’est monté
Internet ──► routeur ──► NAS · Apache ──┬──► 127.0.0.1:5001 panneau LGM-OS
80 et 443 :443 TLS ├──► 127.0.0.1:8096 Jellyfin
:80 redirige └──► 127.0.0.1:8080 Nextcloud
Apache est le seul qui écoute depuis l’extérieur : il termine le TLS avec le certificat Let’s Encrypt et transmet à chaque service par 127.0.0.1. Ni les ports du panneau (5001 et 5000) ni ceux des apps ne sortent du NAS.
1. Avant de commencer
- Une IP fixe pour le NAS sur ton réseau : réservation DHCP sur le routeur ou IP statique dans Panneau de configuration → Réseau. Si le NAS change d’IP, la redirection de ports ne pointe plus vers lui.
- Une vraie IP publique (sans CGNAT). Vérifie-le ainsi :
curl -s https://api.ipify.org; echo # IP sous laquelle Internet te voit
Compare cette valeur avec l’IP WAN qu’affiche ton routeur. Si elles ne correspondent pas, ou si celle du routeur est dans la plage 100.64.0.0 – 100.127.255.255, tu es derrière un CGNAT : la redirection de ports ne fonctionnera pas, quoi que tu fasses. Demande une IP publique à ton opérateur (c’est souvent gratuit, il suffit de la demander) ou passe par Tailscale ou NetBird, qui n’ont pas besoin d’ouvrir de ports (Services réseau).
- Un nom de domaine : le tien, ou un gratuit avec DDNS (étape 3).
2. Ports du routeur : 80 et 443, rien de plus
| Port externe | Protocole | Destination | À quoi ça sert |
|---|---|---|---|
| 80 | TCP | IP-del-NAS:80 | Validation du certificat (HTTP-01) et redirection vers https |
| 443 | TCP | IP-del-NAS:443 | Tout le trafic réel, déjà chiffré |
Le 80 n’est pas optionnel, même si tu ne veux rien servir en clair : Let's Encrypt vérifie que le domaine est à toi en demandant un fichier par le port 80, et sans cette vérification il n’y a pas de certificat. Ce qui est conseillé, en revanche, c’est que le 80 ne fasse que rediriger vers le 443.
Pourquoi on N’ouvre NI le 5001 NI le 5000
Ce sont les ports du panneau : le 5001 chiffré et le 5000 en clair, qui ne fait que rediriger vers le 5001. Les publier est une erreur, même si ça ressemble à un raccourci :
- Le 5000 n’est pas chiffré. Ce qui y passe depuis Internet peut être lu par n’importe qui en chemin, à commencer par l’adresse vers laquelle tu es redirigé.
- Le 5001 sert le certificat autosigné, donc le navigateur affichera toujours un avertissement et tu finiras par prendre l’habitude d’ignorer les avertissements de certificat — ce qui est exactement ce qui rend possible une attaque de l’homme du milieu contre toi.
- Il expose directement l’API d’administration complète, sans les en-têtes, la redirection ni le filtrage qu’applique le proxy placé devant.
- Avec un certificat non valide, la PWA est bancale et certaines fonctions du navigateur sont désactivées.
Avec le proxy inverse, tu entres dans le panneau par https://micasa.duckdns.org (port 443, avec un certificat valide) et le 5001 et le 5000 continuent d’écouter seulement à la maison, là où ils doivent être.
N’ouvre pas non plus le 445 (SMB), le 2049 (NFS), le 3389 ni, sauf si tu sais très bien ce que tu fais, le 22 (SSH). Ce sont des protocoles pensés pour le réseau local ; SMB exposé sur Internet est la porte par laquelle entrent la plupart des rançongiciels domestiques.
Le pare-feu du NAS compte aussi
Si tu as activé le pare-feu (Panneau de configuration → Sécurité → Pare-feu), par défaut il ne laisse passer que le panneau et SSH : même si le routeur redirige, Apache ne recevra rien. Ajoute deux règles et ne touche pas à l’origine (il faut pouvoir entrer depuis n’importe quelle IP) :
| Action | Protocole | Port | Description |
|---|---|---|---|
| Autoriser | tcp | 80 | Let's Encrypt et redirection |
| Autoriser | tcp | 443 | Accès externe https |
3. DDNS avec DuckDNS, pas à pas
Presque aucun opérateur grand public ne donne d’IP fixe : elle change tous les quelques jours ou à chaque redémarrage du routeur. Un service de DNS dynamique fait pointer le nom vers l’IP actuelle. DuckDNS est gratuit, ne demande pas de carte bancaire et fonctionne bien.
- Va sur
https://www.duckdns.orget clique sur l’un des boutons sign in with (Google, GitHub, Reddit…). Ne crée pas de nouveau mot de passe : utilise le compte que tu as déjà. - Dans le cadre add domain, tape le nom que tu veux (par exemple
micasa) et clique sur add domain. Ton domaine estmicasa.duckdns.org. - En haut de la page, tu verras token : xxxxxxxx-xxxx-…. Copie-le. Ce jeton est le mot de passe de ton domaine : ne le partage pas et ne le laisse pas visible sur des captures d’écran.
- Sur le NAS : Panneau de configuration → Accès externe → *Domaine dynamique (DDNS)*. Choisis le fournisseur DuckDNS, tape le domaine complet (
micasa.duckdns.org), colle le jeton et laisse la fréquence par défaut (de 5 à 1440 minutes ; en dessous de 5, les fournisseurs commencent à refuser les requêtes). Active l’interrupteur et enregistre ; avec « Mettre à jour maintenant », tu vérifies tout de suite que le jeton est valide. Le panneau affiche la dernière IP publiée et l’erreur de la dernière mise à jour s’il y en a eu une. Les autres fournisseurs pris en charge sont Cloudflare (jeton d’API avec l’autorisation Zone · DNS · Edit) et No-IP (clé de la section Dynamic DNS). - Vérifie que le nom est résolu (depuis le NAS, ou avec
nslookupdepuis Windows) :
getent hosts micasa.duckdns.org # doit renvoyer ton IP publique
curl -s https://api.ipify.org; echo # ...la même que celle-ci
Si tu préfères ne pas dépendre du NAS pour ça, regarde si ton routeur intègre un client DDNS compatible DuckDNS : elle met l’IP à jour même quand le NAS est éteint, ce qui est plus robuste. L’appel, au cas où tu en aurais besoin dans un script ou pour forcer une mise à jour manuelle, est :
curl -s "https://www.duckdns.org/update?domains=micasa&token=TON-JETON&ip="
# répond OK (mis à jour) ou KO (domaine ou jeton incorrects)
Le paramètre ip vide signifie « utilise l’IP depuis laquelle je t’appelle ».
Deux détails utiles sur DuckDNS : les changements mettent quelques minutes à se propager, et n’importe quel sous-domaine (pelis.micasa.duckdns.org) est résolu vers la même IP sans rien configurer — c’est ce qui permet de publier plusieurs apps par nom (étape 5).
Avec ton propre domaine, l’étape 3 est équivalente : fais pointer un enregistrement A vers ton IP publique (ou utilise le DDNS de ton fournisseur DNS) et continue pareil à partir de l’étape 4.
4. Obtenir le certificat
Conditions, les trois en même temps : le domaine est résolu vers ton IP publique, le port 80 arrive jusqu’au NAS et Apache tourne. Avant de demander quoi que ce soit, vérifie depuis l’extérieur de ton réseau (données mobiles du téléphone, pas le wifi de la maison) que http://micasa.duckdns.org répond quelque chose —même si c’est la page par défaut d’Apache—. Si ça ne marche pas, le certificat ne marchera pas non plus.
Depuis l’interface : Panneau de configuration → Accès externe → Certificat. Tape le domaine, une adresse e-mail de contact (Let's Encrypt ne l’utilise que pour te prévenir si un certificat va expirer sans avoir été renouvelé), accepte les conditions et clique sur Émettre le certificat. Une fois émis, Utiliser dans le panneau fait que l’interface elle-même le sert : elle redémarre quelques secondes et revient en https avec ton domaine, sans avertissement.
L’équivalent en console, si tu préfères voir ce qui se passe dessous :
sudo certbot --apache -d micasa.duckdns.org -m toi@email --agree-tos --no-eff-email
Si tu gères déjà le proxy inverse depuis le panneau, utilise plutôt certbot certonly --apache … : --apache seul réécrit les vhosts pour ajouter le TLS et écraserait ceux que génère le panneau. Avec certonly, seul le certificat est émis et c’est toujours le panneau qui gère la configuration.
Ce qu’il faut savoir ensuite :
- Les fichiers se trouvent dans
/etc/letsencrypt/live/micasa.duckdns.org/(fullchain.pemetprivkey.pem). Ne les déplace pas : certbot les remplace lors du renouvellement. - Ils expirent au bout de 90 jours et se renouvellent tout seuls. Le paquet installe un minuteur ; vérifie-le avec
systemctl list-timers certbot.timeret fais un essai avecsudo certbot renew --dry-run. - Let's Encrypt limite les tentatives échouées (5 par heure et par domaine). En cas d’échec, corrige la cause avant de réessayer ; insister en boucle t’empêchera d’obtenir un certificat pendant un moment. Pour les tests, utilise
--dry-run.
Si tu as obtenu le certificat à la main avec certbot, le panneau ne le sait pas : il gardera l’autosigné sur le 5001 et la copie que tu feras sera périmée dès que certbot renouvellera. Ce crochet de déploiement le tient à jour (certbot l’exécute à chaque renouvellement effectif) :
sudo tee /etc/letsencrypt/renewal-hooks/deploy/10-lgm-os.sh >/dev/null <<'EOF'
#!/bin/sh
# certbot ejecuta este script en cada renovación efectiva.
D=micasa.duckdns.org
cp "/etc/letsencrypt/live/$D/fullchain.pem" /etc/nas/tls/cert.pem
cp "/etc/letsencrypt/live/$D/privkey.pem" /etc/nas/tls/key.pem
chgrp nas /etc/nas/tls/key.pem && chmod 640 /etc/nas/tls/key.pem
systemctl restart nas-backend
EOF
sudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/10-lgm-os.sh
5. Publier des apps par sous-domaine (proxy inverse)
L’idée : un nom pour chaque service, tous entrant par le 443 et répartis par Apache selon le nom que demande le navigateur.
| Nom | Va vers | Ce que c’est |
|---|---|---|
micasa.duckdns.org | 127.0.0.1:5001 | Le panneau LGM-OS |
pelis.micasa.duckdns.org | 127.0.0.1:8096 | Jellyfin |
nube.micasa.duckdns.org | 127.0.0.1:8080 | Nextcloud |
Dans Panneau de configuration → Accès externe → Proxy inverse → Nouvelle règle, avec un service par règle :
- Domaine public : le nom complet (
pelis.micasa.duckdns.org). - Hôte et port de destination : normalement
127.0.0.1et le port de l’app. La liste déroulante des conteneurs en cours d’exécution les remplit pour toi ; si l’app ne publie pas de port, saisis-les à la main. - Rediriger HTTP vers HTTPS : laisse-le activé. Qui tape le nom sans
https://arrivera quand même sur la connexion chiffrée. - Utiliser le certificat géré : activé si ce nom est couvert par le certificat obtenu à l’étape 4.
- Règle active : tu peux la laisser désactivée et la publier plus tard sans la supprimer.
À l’enregistrement, le panneau écrit le vhost et recharge Apache. Les WebSockets fonctionnent sans rien toucher (l’installateur laisse proxy_wstunnel activé) ; c’est ce dont ont besoin les terminaux web, les journaux en direct, Home Assistant ou code-server pour ne pas rester « en cours de connexion » indéfiniment. Deux conditions pour chaque nom :
- Qu’il soit résolu : avec DuckDNS, les sous-domaines fonctionnent tout seuls ; avec ton propre domaine, crée un enregistrement
CNAME(ouA) pour chacun. - Qu’il ait un certificat : la validation HTTP-01 émet par nom précis, donc obtiens aussi le certificat du sous-domaine (ou ajoute-le à l’existant avec un autre
-d). Un certificat générique*.midominioexige une validation DNS-01, que ce guide ne couvre pas.
Et une règle qu’il vaut la peine de répéter : les ports des apps ne s’ouvrent pas sur le routeur. Le proxy les atteint par 127.0.0.1. Publier par le proxy et en plus ouvrir le port direct, c’est laisser la porte de derrière ouverte à côté de la bonne.
6. Sécurité (lis-le avant de toucher au routeur)
Tant que le NAS n’était que sur ton réseau, une erreur de configuration, c’était ta famille qui la voyait. Dès que tu le publies, c’est un scanner automatique qui la voit en quelques heures : ce n’est pas une exagération, les robots testent /login sur n’importe quelle IP qui a le 443 ouvert. Voici le minimum :
- Active la validation en deux étapes tout de suite : Panneau de configuration → Ton compte. Sans second facteur, la seule chose entre Internet et toutes tes données est un mot de passe.
- Passe le Conseiller de sécurité (Panneau de configuration → Sécurité) et règle ses alertes. C’est le résumé honnête de l’état du dispositif ; ne publie pas avec des alertes critiques en suspens.
- Blocage d’IP activé (Sécurité → Blocage d’IP). Le panneau limite déjà à 10 tentatives par minute et bloque le compte après 5 échecs, mais c’est le blocage par IP qui coupe le scan à la racine.
- Pare-feu activé avec seulement 80 et 443 ouverts vers l’extérieur.
- Des mots de passe longs et uniques, en particulier celui de l’administrateur. Pour qui ne fait que consulter, crée des utilisateurs avec le rôle
viewer. - Mets à jour : Panneau de configuration → Mettre à jour LGM-OS (apt) et la mise à jour du panneau. Un NAS publié et pas à jour, c’est une question de temps, pas de chance.
- Des sauvegardes, dont au moins une hors ligne. Publier multiplie le risque de rançongiciel, et une sauvegarde connectée est chiffrée avec le reste. Voir disaster-recovery.md.
- Regarde l’Audit et les Utilisateurs connectés de temps en temps : tu y verras les tentatives d’accès et depuis quelle IP.
- Publie le strict nécessaire. Si ce que tu veux, c’est regarder tes films hors de chez toi, publie Jellyfin et administre le panneau depuis la maison. Chaque nom publié est une porte de plus.
Et la comparaison honnête : le plus sûr reste de ne rien publier. Un VPN (WireGuard) te donne accès à tout le NAS sans exposer un seul service sur Internet, en échange de devoir connecter le VPN sur chaque dispositif. LGM-OS intègre son propre serveur WireGuard (Panneau de configuration → VPN, avec un code QR pour le téléphone), et dans « Ta connexion » il peut demander au routeur d’ouvrir son port toute seule (UPnP). Pour un usage personnel, c’est la meilleure option. Si tu ne peux pas ouvrir ce port —CGNAT, ou un routeur qui n’est pas le tien—, le même écran propose Tailscale et NetBird : le NAS rejoint ton réseau de ce service et tu l’atteins sans rien ouvrir. Publier avec proxy et certificat est la bonne option quand tu as besoin de partager avec des gens qui ne vont pas installer de VPN.
7. Si quelque chose ne fonctionne pas
| Symptôme | Cause habituelle | Que vérifier | |
|---|---|---|---|
| Le domaine n’est pas résolu | Le DDNS n’a pas mis à jour | getent hosts micasa.duckdns.org ; jeton correct ; attends quelques minutes | |
| Il est résolu, mais ça ne se connecte pas depuis l’extérieur (depuis la maison, si) | Ports non redirigés, ou CGNAT | Essaie avec les données mobiles ; vérifie la redirection 80/443 ; compare l’IP du routeur avec api.ipify.org | |
| certbot : Timeout during connect ou challenge failed | Le port 80 n’arrive pas jusqu’au NAS | Redirection du 80, règle du pare-feu, et vérifie si ton opérateur bloque le 80 (certains le font) | |
| 502 / 503 en ouvrant un sous-domaine | L’app n’est pas démarrée ou le port de destination est un autre | docker ps, Centre de paquets, sudo tail -f /var/log/apache2/error.log | |
| L’app se charge mais reste « en cours de connexion » | Il manque les WebSockets | `apache2ctl -M \ | grep wstunnel ; s’il n’apparaît pas : sudo a2enmod proxy_wstunnel && sudo systemctl reload apache2` |
| Le navigateur affiche un avertissement de certificat | Tu entres par le 5001, ou ce nom n’a pas de certificat | Entre par https://micasa.duckdns.org (443) ; sudo certbot certificates | |
| Par le VPN, tu atteins tout sauf le panneau | La taille de paquet du tunnel (MTU) ne passe pas par le réseau mobile | Dans l’app WireGuard du client, dans [Interface], mets MTU = 1280 (les clients créés avec LGM-OS l’ont déjà) |
Par le VPN, on voit tout sauf le panneau
C’est déroutant, parce qu’on dirait que le NAS se protège de toi : le téléphone dit « connecté », le ping passe, tu accèdes aux autres dispositifs de la maison… et le panneau affiche impossible d’accéder à ce site.
Ce n’est ni le pare-feu ni la licence : c’est le MTU. Un tunnel WireGuard sans MTU déclaré utilise 1420 octets, ce qui suffit largement par la fibre mais ne passe pas en 4G/5G (le réseau mobile et le CGNAT gardent une partie du paquet). Les petits paquets passent —d’où le fait que le ping et presque tout fonctionnent— et les paquets pleins se perdent en silence. Le panneau est justement ce qui voyage dans des paquets pleins : la négociation TLS avec son certificat, puis toute l’interface.
Les clients que crée LGM-OS ont déjà MTU = 1280, le minimum que garantit Internet. Si ton client date d’avant cette version, pas besoin de le refaire : modifie la connexion dans l’app WireGuard et ajoute cette ligne dans [Interface].
Commandes de diagnostic :
sudo apachectl configtest # la configuration d’Apache est-elle valide ?
sudo systemctl status apache2
sudo journalctl -u apache2 -n 50
sudo tail -f /var/log/apache2/error.log
sudo certbot certificates # certificats émis et leur expiration
Les modules Apache dont le proxy a besoin (proxy, proxy_http, proxy_wstunnel, headers, ssl, rewrite) sont activés par deploy/install.sh et deploy/update.sh. Pour les vérifier :
apache2ctl -M | grep -E 'proxy|headers|ssl|rewrite'