Il n’y avait pourtant rien d’extraordinaire dans cette infrastructure. Un serveur Apache, un Nextcloud bien configuré, un proxy inverse pour absorber le trafic entrant. Des milliers d’organisations font tourner exactement ce type d’architecture, chaque jour, sans encombre. Pourtant, ce matin, le formulaire de connexion s’affichait parfaitement vide. Pas d’erreur explicite. Pas de message d’alerte. Juste… le silence.
Un bug fantôme
À première vue, le problème ressemble à n’importe quelle anomalie JavaScript : la console Firefox remonte une NS_ERROR_..., les variables globales OC et OCA ne sont jamais définies, et l’interface reste inerte. Le réflexe naturel est d’inspecter le code de Nextcloud, de chercher une régression dans une mise à jour récente, de fouiller les logs PHP.
Mais rien. Le serveur répond 200. Les fichiers sont bien servis. Nextcloud, côté serveur, ne sait pas qu’il y a un problème.
C’est précisément ce type de bug qui consume des heures d’ingénierie : tout semble fonctionner, sauf que ça ne fonctionne pas.
La piste du réseau
La clé du mystère se trouve non pas dans le code, mais dans le voyage du fichier core-common.js entre le serveur et le navigateur. Ce fichier — le cœur JavaScript de Nextcloud — pèse 5,5 Mo non compressé. Une taille tout à fait gérable pour un serveur moderne, à condition que la compression soit activée.
Et c’est là que tout déraille.
Le proxy inverse, chargé de filtrer et redistribuer le trafic entrant, supprime silencieusement l’en-tête HTTP Accept-Encoding: gzip avant de transmettre les requêtes à Apache. Ce comportement, peut-être hérité d’une configuration défensive ou d’un middleware trop zélé, passe complètement inaperçu dans les logs habituels.
Apache, ne voyant aucun en-tête signalant que le client accepte la compression, sert le fichier en clair. 5,5 Mo de JavaScript brut partent vers le proxy.
Et le proxy, lui, tronque la réponse.
737 Ko : le seuil de la catastrophe
Le proxy ne remonte aucune erreur. Il transmet simplement ce qu’il peut, jusqu’à sa limite interne : ~737 Ko. Le navigateur reçoit donc un fichier JavaScript amputé de plus de 80 % de son contenu, sans le moindre signal que quelque chose s’est mal passé — pas de code HTTP d’erreur, pas d’en-tête Content-Length incohérent détecté, rien.
Firefox tente de parser ce fragment. Il échoue. OC et OCA — les objets racines de toute l’interface Nextcloud — ne sont jamais instanciés. Le formulaire de login reste vide. L’utilisateur voit une page cassée sans savoir pourquoi, et l’administrateur voit des logs propres sans savoir où chercher.
La correction : une ligne, un principe
La solution tient en une seule directive Apache, ajoutée dans /etc/apache2/sites-enabled/nextcloud.conf :
RequestHeader setifempty Accept-Encoding "gzip,deflate"
setifempty est la subtilité qui change tout : la directive ne force pas l’en-tête si le client l’a déjà fourni, elle le rétablit uniquement s’il est absent. Ainsi, si un vrai navigateur sans support gzip se connecte directement, le comportement reste correct. Mais si le proxy a supprimé l’en-tête, Apache le récupère et peut activer la compression.
Résultat immédiat : core-common.js passe de 5,5 Mo à 1,26 Mo compressé. Le proxy transmet l’intégralité du fichier. Firefox charge un JavaScript complet. Le formulaire de login réapparaît.
Ce que cette affaire révèle
Ce bug illustre une classe de problèmes particulièrement vicieuse dans les architectures à plusieurs couches : la défaillance silencieuse par modification d’en-têtes HTTP.
Les proxies inverses — HAProxy, Nginx, Traefik, Squid et bien d’autres — manipulent régulièrement les en-têtes pour des raisons de sécurité, de normalisation ou de compatibilité. Ces modifications sont rarement documentées de façon exhaustive, et encore plus rarement journalisées de manière exploitable. Le résultat est une zone grise où le client croit parler au serveur, et le serveur croit parler au client, mais les deux s’adressent en réalité à un intermédiaire qui réécrit la conversation à leur insu.
La leçon pratique pour tout administrateur système : lorsqu’une application se comporte de façon erratique derrière un proxy, la première investigation devrait toujours porter sur les en-têtes HTTP réellement reçus par le serveur backend, et non sur ceux émis par le client. Un simple RequestHeader de logging temporaire dans Apache, ou l’inspection des requêtes avec tcpdump côté backend, peut révéler en quelques minutes ce que des heures de débogage applicatif n’auront pas trouvé.
Infrastructure · Apache · Nextcloud · Proxy inverse · HTTP
Commentaires
Aucun commentaire pour l'instant. Soyez le premier !
Laisser un commentaire