Corruption de fichiers lors d'un téléchargement depuis NGINX / Apache

Bonjour à tous,

Je viens vous voir ici car je suis complètement perdu par rapport à un problème que je n’ai jamais rencontré.

J’ai un serveur web (NGINX) utilisant PHP5.6 sur une Debian 9 avec un site Internet forcément dessus.
J’ai une section « adhérents » dessus où mon entreprise met à disposition des fichiers de toutes sortes, Excel, images, PDF, etc. Et ils peuvent donc les télécharger pour les consulter.
Cette installation est toute fraîche puisque j’ai changé de serveur, j’étais en Debian 7 avec toujours NGINX et PHP5.6.

Depuis la mise en place sur ce nouveau serveur, TOUS mes fichiers téléchargés sont corrompus !

J’ai essayé tellement de choses… Passer sur Apache, mettre PHP7, retiré le certificat SSL, jouer sur les paramètres de compression gzip/deflate etc. Rien n’y fait.

Je remarque également que mes fichiers perdent leurs propriétés. Lors d’un clic droit puis propriétés, puis détails, n’apparaissent plus : auteurs, dernier enregistrement, nom du programme, entreprise etc.

Je dois préciser que le fait de récupérer le fichier directement avec du SFTP par exemple fonctionne très bien et il n’a pas perdu les infos (metatags je crois) et s’ouvre très bien.

Hormis ceci mon site fonctionne très bien.
Les deux fichiers font exactement la même taille.

Annotation 2020-05-15 135913

Si une âme charitable pouvait me venir en aide ? Ou m’aiguiller… Ce serait fantastique car j’ai déjà perdu trop de temps sur ce problème.

Merci infiniment.

Bonjour,

Déjà ce n’est pas une configuration « normale », la version de PHP fournie par Debian 9 est la 7.0.

Si je comprends bien les fichiers sont corrompus uniquement lorsqu’ils ont téléchargés via l’interface web. Il faut donc voir le code du site qui permet ce téléchargement et surtout examiner les logs du site au moment où un fichier est téléchargé.
Quel est le poids de ces fichiers ?
Comment est réglée la directive client_max_body-size de nginx ?

Bonjour et merci.

J’étais dès l’apparition du problème en 7.0. Et comme avant le site était en 5.6, j’ai installé cette version pensant que cela venait de là.

J’ai encore la 7.0 d’installée, je peux refaire la bascule.

Le fichier fait 378.84 Ko, un autre essai était de 172Ko.

client_max_body_size est sur 1m dans le contexte "http".

Tu as bien compris la problème.

Je viens de repasser sous apache avec PHP7.0, même problème.
Par contre dans les logs je vois ça et je trouve la ligne 2 curieuse :

[Fri May 15 16:11:56.167809 2020] [ssl:debug] [pid 4821] ssl_engine_kernel.c(2042): [client 78.242.101.116:51529] AH02041: Protocol: TLSv1.2, Cipher: ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)
[Fri May 15 16:11:56.740387 2020] [ssl:info] [pid 4822] (70014)End of file found: [client 78.242.101.116:51528] AH01991: SSL input filter read failed.
[Fri May 15 16:11:56.740599 2020] [ssl:debug] [pid 4822] ssl_engine_io.c(1044): [client 78.242.101.116:51528] AH02001: Connection closed to child 9 with standard shutdown (server groupe-pole.com:443)
[Fri May 15 16:12:03.362649 2020] [reqtimeout:info] [pid 4824] [client 49.98.75.237:28923] AH01382: Request header read timeout

Ça survient dès que je clique sur le bouton de téléchargement et que le navigateur me demande si je veux enregistrer ou ouvrir.

Tu utilises nginx comme proxy ?
Que dit la directive client_header_timeout ?

Par conte ce qui précède semble indiquer un problème de configuration TLS, mais je ne sais pas d’où cela vient. Il faudrait pouvoir examiner toute la configuration.
Mais déjà bien vérifier que le client que tu utilises sait gérer TLS 1.2. Le mieux étant de vérifier depuis une Debian 10 :wink:

Merci pour tes réponses.
Oui je trouve curieux aussi cette ligne End of file… Je ne m’y connais pas assez, j’ai posé mes questions aussi sur le forum Let’s Encrypt.

Je n’ai pas de Proxy. De plus je suis repassé sous Apache2. J’ai même désactivé mon pare-feu en frontal (pfSense) pour éliminer cet éventuel paramètre.
Voici la partie SSL de mon virtualhost :

SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/XXXX.com/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/XXXX.com/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/XXXX.com/chain.pem
SSLProtocol all -SSLv3
SSLHonorCipherOrder on
SSLCompression off
SSLOptions +StrictRequire
SSLCipherSuite #ECDHE-RSA-AES128-GCM-....................
#Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"

Debian 10 sous-entend refaire tout depuis le début :cry: Mais s’il le faut… Je vais passer un bon weekend :wink:

Merci pour ton aide.

Non je parlais de tester le téléchargement depuis une machine cliente sous Debian 10 pas le serveur :wink:

Pour la configuration TLS d’Apache, je te conseille de te conformer aux recommandations de Mozilla : https://ssl-config.mozilla.org/

Et attention les fichiers de configuration d’Apache ne gèrent pas les commentaires avec un # au milieu d’un ligne.

Il serait intéressant de voir si tu obtiens les mes erreurs dans les logs d’Apache. Le problème peut aussi se situer au niveau de ton application web.

Ah ! J’ai une Mint 19.3 à ma droite, je teste.

Voilà ouvert avec LibreOffice bien sûr. Breaking file !

Capture du 2020-05-15 17-57-57

Je vais aller voir donc les recommandations.

Merci.

Dans la capture d’écran on reconnaît des éléments d’un fichier OpenDocument (ou peut-être MS Office) : archive pkzip contenant des fichiers XML.

Tu as comparé le contenu binaire des fichiers originels et téléchargés pour voir ce qui est modifié ? Est-ce une troncature, une insertion, une altération partielle ou totale ?
Que donne le transfert d’un fichier de texte brut (.txt) ? Les différences devraient être faciles à visualiser.

Bonjour,

Merci pour ta réponse, j’arrive un peu tard. C’est bien des fichiers Excel.

Je viens de faire un essai avec un document XML tout simple. Surprise le fichier s’ouvre bien mais j’ai une ligne de plus au début du fichier ?! C’est très étrange. Je ne m’attendais pas à ça. Si j’affiche tous les caractères je vois que c’est un « LF »

Je viens de refaire un essai avec un fichier TXT tout bête et pareil, il m’ajoute un « LF » en début de fichier.

Je suis bien perplexe…

Je viens de voir également qu’il me retire le dernier caractère de mon fichier !
Voici ce que j’upload :
Envoi

Et voici ce que je télécharge ensuite :

Dl

Je n’ai jamais vu ça !

Oh mon dieu !!! J’ai trouvé. Ça fonctionne, c’est un Bug de mon CMS !

Grâce à ce forum : https://forum.joomla.org/viewtopic.php?t=229110

Ceci dit comme j’avais la même configuration sur les deux serveurs, l’ancien et le nouveau, je suis tout de même vachement surpris !!!

Merci à tous pour votre aide.

:grinning:

Tu n’avais pas précisé que les fichiers n’étaient pas téléchargés directement comme des ressources HTTP mais à travers un script PHP.

Un « linefeed » inséré au tout début d’un fichier téléchargé via du PHP, cela vient d’un fichier PHP qui a été édité et qui s’est retrouvé avec un « linefeed » (ou tout autre caractère) devant la balise <?php .

C’est juste une mauvaise manipulation, pas un bug.


AnonymousCoward

Je n’ai pourtant jamais modifié ce script et je viens de vérifier, il n’a pas de LF devant la balise <?php…

Alors je ne sais quoi te répondre.

Je ne comprends pas, c’est bien PHP ou autre peu importe qui prépare le téléchargement du fichier lorsqu’on clique sur un lien… Et envoie les headers et tout ce qui va bien.

De plus cela a été réglé en ajoutant dans le code

while(@ob_end_clean());

devant cette préparation des headers justement.

Dans ton cas oui, mais pas forcément dans le cas général. Si le téléchargement se fait en cliquant sur un lien direct vers l’URL de la ressource, ça ne passe pas par du PHP, même si ce lien se trouve dans une page dont le contenu a été généré par du PHP. C’est le serveur HTTP lui-même qui envoie les headers et le contenu.

Il me semblait que cette partie de mon post original aurait suffit, visiblement non.

Elle, selon moi, sous-entendait qu’il ne s’agissait pas de téléchargement direct.

Merci en tout cas.

Les sous-entendus, c’est un peu juste. Quand bien même, je ne vois même pas où ce serait sous-entendu.