Il est 2h00 du matin. Après le silence absolu de la fibre coupée, je pensais avoir payé mon tribut au chaos numérique. Je me trompais.
La connexion est revenue, mais la porte est fermée.
J'essaie d'accéder à l'administration de mon Ghost. /ghost. Entrée.
L'écran m'insulte : 403 Forbidden.
Pas d'explication. Juste ce mépris algorithmique : "Unable to determine the authenticated user. Check cookies."
La machine ment. Elle ment toujours.

La fausse piste du Reverse Proxy
Dans ces moments-là, on doute de tout. On se dit que c'est Traefik. C'est toujours la faute du reverse proxy. On se persuade que les headers X-Forwarded-Proto se perdent dans la mélasse du réseau.
J'ai passé une heure à modifier mon docker-compose, à forcer des labels, à injecter des headers comme on injecte de l'adrénaline dans un cadavre.
traefik.http.middlewares...
Rien. La 403 me regarde, immuable.

C'est là que j'ai arrêté de regarder la porte pour écouter ce qui se passait derrière. J'ai ouvert les logs, non pas pour chercher une erreur, mais pour chercher le silence.
Et j'ai trouvé le cri étouffé de Ghost :
EmailError: Failed to send email. ETIMEDOUT
Ce n'était pas un problème de cookies. C'était un problème de clé. Depuis la version 5, Ghost a décidé qu'un mot de passe ne suffisait plus. Il veut m'envoyer un code par mail. Sauf qu'il n'y arrive pas.
L'interface web me disait "Interdit". Le backend hurlait "Je ne peux pas sortir".
La prison du conteneur
Le problème, c'est l'isolation. Docker est une cellule capitonnée.
J'ai voulu tester la connexion SMTP depuis l'intérieur du conteneur.
ping ? Inconnu. nc ? Absent. wget ? Non trouvé.
Les images minimalistes, c'est génial pour la CI/CD, c'est un enfer pour le debug. Je suis aveugle, les mains liées, enfermé dans une image Alpine allégée jusqu'à l'os.
Alors j'ai improvisé. J'ai utilisé ce qui traînait : Node.js. J'ai écrit un script de trois lignes pour tenter d'ouvrir un socket TCP vers l'extérieur.
socket.connect(465, 'smtp.eu.mailgun.org', ...)
Verdict : TIMEOUT.
Pourtant, depuis le serveur hôte, ça passe. Le serveur a accès au monde. Le conteneur, lui, regarde le mur.
J'ai pensé au NAT. J'ai pensé aux iptables. J'ai vérifié les règles MASQUERADE. Tout était vert. La logique avait quitté la pièce.
Le gardien silencieux
Il restait une variable. L'hébergeur.
Hetzner. L'efficacité allemande, le prix cassé, et ses règles invisibles.
J'ai changé un chiffre dans mon script de test. J'ai remplacé le port 465 (SSL implicite) par le 587 (STARTTLS).
socket.connect(587, ...)
OK.
La réponse a claqué instantanément.
La vérité était là, brutale : Hetzner bloque le port 465 en sortie par défaut. Une mesure anti-spam radicale qui ne prévient pas. Ils coupent la veine et vous laissent vous demander pourquoi le sang ne coule plus.
Épilogue
J'ai changé la config de Ghost. Port 587. Secure: false.
Le mail est parti. Le lien de connexion est arrivé. Je suis rentré.
C'est une victoire technique, mais une défaite morale.
On se croit architecte de nos systèmes, on se pense libre parce qu'on utilise de l'Open Source et des VPS Linux. Conneries.
On est juste des locataires qui découvrent, à 2h du matin, que le propriétaire a muré la fenêtre de la salle de bain parce qu'il avait peur des courants d'air.
La machine tourne. Pour l'instant.
