Skip to content
selfhostr

guide · 6 min read

Mettre en place un reverse proxy

Des noms lisibles et du HTTPS au lieu de six ports à retenir : Nginx Proxy Manager, Let's Encrypt, et l'erreur « Internal Error » qui attend tout le monde.

Au troisième service, vous allez avoir un problème que personne n'annonce.

Jellyfin écoute sur 8096, Immich sur 2283, Vaultwarden sur 8080. Vous les retenez au début. Puis vous en ajoutez un quatrième, vous vous trompez de port, vous cherchez dans le docker-compose.yml pour retrouver lequel c'était. Et quand quelqu'un d'autre dans la maison vous demande l'adresse des photos, vous dictez 192.168.1.42:2283 — deux fois, parce que la première n'a pas marché.

Il y a pire : tout ça passe en clair. Un gestionnaire de mots de passe consulté en HTTP sur son propre réseau reste un gestionnaire de mots de passe qui transmet sa session sans chiffrement.

Un reverse proxy règle les deux d'un coup. Un seul point d'entrée, des noms lisibles, et du HTTPS partout :

photos.exemple.fr    →  192.168.1.42:2283
films.exemple.fr     →  192.168.1.42:8096
motsdepasse.exemple.fr →  192.168.1.42:8080

Ce guide utilise Nginx Proxy Manager : c'est nginx, avec une interface web par-dessus. Les certificats Let's Encrypt se demandent en trois clics et se renouvellent seuls. Comptez trente minutes la première fois.

Ce qu'il vous faut

  • Ubuntu Server avec Docker — voir Installer Docker.
  • Un nom de domaine. C'est la seule dépense obligatoire de ce guide : comptez une dizaine d'euros par an. Sans domaine, pas de certificat Let's Encrypt, donc pas de HTTPS.
  • Une façon de joindre votre serveur depuis l'extérieur, si c'est ce que vous voulez : un tunnel Cloudflare ou une redirection de port.

Et si vous ne voulez rien exposer du tout, ce guide reste utile : des noms lisibles et du HTTPS sur votre seul réseau local, c'est déjà l'essentiel du confort.

Étape 1 — Libérer les ports 80 et 443

Le proxy doit être seul à les écouter. Si un service les occupe déjà, il faut le déplacer d'abord :

sudo ss -tlnp | grep -E ':(80|443)\s'

Pas de sortie, rien ne les écoute, vous pouvez continuer. Une ligne apache2 ou nginx : un serveur web s'est installé avec autre chose, et il faut l'arrêter (sudo systemctl disable --now apache2).

Étape 2 — Lancer le proxy

Dans un dossier à lui, un docker-compose.yml :

services:
  npm:
    image: jc21/nginx-proxy-manager:2.15.1
    restart: unless-stopped
    ports:
      - '80:80'    # HTTP public
      - '443:443'  # HTTPS public
      - '81:81'    # interface d'administration
    volumes:
      - ./data:/data
      - ./letsencrypt:/etc/letsencrypt
docker compose up -d

La version est épinglée, et ce n'est pas un détail : latest sur le composant qui porte tout votre trafic veut dire qu'une mise à jour surprise peut couper l'accès à tous vos services d'un coup. Le guide Mettre à jour ses conteneurs explique quand et comment monter de version.

Étape 3 — La première connexion

Rendez-vous sur http://192.168.1.42:8181, pas 80. Le port 80 sert le trafic public ; l'interface d'administration vit à côté.

Le premier compte est écrit dans la documentation, donc connu de tout le monde :

[email protected]
changeme

L'interface vous demande de le remplacer immédiatement. Faites-le vraiment — cette page d'administration peut créer un certificat pour n'importe quel sous-domaine et rediriger n'importe quel service.

Étape 4 — Faire pointer votre domaine

Chez votre registrar (ou dans Cloudflare, si vous y avez délégué le domaine), créez un enregistrement par service :

Type Nom Valeur
A photos votre IP publique
A films votre IP publique

Ou, plus simple, un joker : un enregistrement * qui envoie tous les sous-domaines vers la même adresse. Vous n'aurez plus jamais à revenir ici pour ajouter un service.

Si vous passez par un tunnel Cloudflare, ce sont les enregistrements du tunnel qui font ce travail, et l'IP publique ne sort jamais.

Vérifiez que ça a pris avant d'aller plus loin — la propagation DNS prend de quelques minutes à quelques heures :

dig +short photos.exemple.fr

Une adresse qui s'affiche, c'est bon. Rien du tout, attendez : demander un certificat maintenant échouerait sans que le message ne dise pourquoi.

Étape 5 — Le premier hôte

Dans Hosts → Proxy Hosts → Add Proxy Host :

  • Domain Names : photos.exemple.fr
  • Scheme : http
  • Forward Hostname / IP : l'IP locale du serveur
  • Forward Port : 2283
  • Block Common Exploits : coché

Puis l'onglet SSL :

  • SSL Certificate : Request a new SSL Certificate
  • Force SSL : coché — sinon le service reste joignable en clair
  • HTTP/2 Support : coché
  • Votre adresse e-mail, et accepter les conditions de Let's Encrypt

Enregistrez. Une dizaine de secondes plus tard, https://photos.exemple.fr répond, avec un cadenas.

L'erreur qui va vous arriver : « Internal Error »

C'est le message que renvoie Nginx Proxy Manager quand Let's Encrypt n'a pas pu vérifier le domaine. Il ne dit jamais pourquoi. Les trois causes, dans l'ordre de fréquence :

  1. Le DNS ne pointe pas encore ici. Revérifiez avec dig.
  2. Le port 80 n'arrive pas jusqu'au proxy. Let's Encrypt vérifie en se connectant sur le port 80 depuis l'extérieur — même si vous ne comptez servir qu'en HTTPS. Sans redirection de ce port, la validation échoue.
  3. Votre opérateur bloque le port 80. C'est courant. Dans ce cas, passez à la validation par DNS : dans l'onglet SSL, cochez Use a DNS Challenge et choisissez votre fournisseur. Aucun port n'est nécessaire, et c'est le seul moyen d'obtenir un certificat joker.

En local seulement, sans rien exposer

Vous pouvez avoir des noms et du HTTPS sans qu'aucun paquet n'entre chez vous :

  1. Prenez un vrai domaine, mais faites pointer ses enregistrements vers l'IP privée du serveur (192.168.1.42). C'est autorisé, et invisible depuis l'extérieur.
  2. Utilisez la validation DNS pour le certificat : Let's Encrypt n'a alors pas besoin d'atteindre votre machine.

Résultat : https://photos.exemple.fr fonctionne à la maison et nulle part ailleurs. C'est souvent exactement ce qu'on veut.

Ce que ça ne fait pas

Un reverse proxy n'est pas une authentification. Il chiffre le transport et range les adresses ; il n'empêche personne d'ouvrir la page. Ce qui protège un service, c'est son propre mot de passe — et le fait de ne pas l'exposer du tout quand rien ne l'exige.

Ne mettez pas l'interface du proxy (le port 81) derrière un sous-domaine public. C'est la clé de tout le reste.

Et ensuite

Video

Korben monte un reverse proxy avec nginx et Docker. La configuration s'y écrit à la main plutôt que par l'interface de Nginx Proxy Manager : le principe est le même, et voir les fichiers aide à comprendre ce que l'interface rédige à votre place.

Nothing is sent to YouTube until you press play. This site sets no cookies of its own.Watch on YouTube