Projet

Général

Profil

Actions

Anomalie #1840

fermé

Propagation des adresses IP à travers le proxypass nginx

Ajouté par Quentin Gibeaux il y a environ 8 ans. Mis à jour il y a presque 4 ans.

Statut:
Fermé
Priorité:
Normale
Assigné à:
Catégorie:
-
Version cible:
-
Début:
21/12/2016
Echéance:
% réalisé:

0%

Temps estimé:
Temps passé:
Difficulté:
2 Facile

Description

Cet après-midi on a remarqué avec CPM que certaines requêtes n'avaient pas les adresses IP des clients dans les logs apache de drupal6, mais celle du bastion nginx.
Cela ne viendrait pas du fait que seules les routes https sont configurées avec les champs suivants ?

        proxy_set_header Host       $http_host;
        proxy_set_header X-Forwarded-Proto $scheme;

Il y a une raison particulière à ne pas ajouter ces champs également à la configuration sur le port 80, ou est-ce un simple oubli ?

Mis à jour par François Poulain il y a presque 8 ans

Non, ce qui est utile est ça :

/etc/nginx/conf.d/local.conf : proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

Le X-Forwarded-Proto sert à faire connaître au serveur backend que le protocole est https. Mais plein d'applications ignorent cette variable.

J'ai créé (le 23 nov dernier) sur chaque apache une conf de log qui utilise le X-Forwarded-For. Cette conf est utilisable en mettant :

CustomLog ${APACHE_LOG_DIR}/www.april.org.access.log combined-proxy

au lieu de l'habituel
CustomLog ${APACHE_LOG_DIR}/www.april.org.access.log combined

Ceci étant, effectivement, pour une raison qui m'échappe pour le moment, le logs ne fonctionnent effectivement pas comme attendu avec des requêtes https.

Mis à jour par François Poulain il y a presque 8 ans

J'ai temporairement commi

root@drupal6:/etc# cat /var/lib/drupal6/files/eiFeiK5o.php

<?php
$headers = apache_request_headers();

foreach ($headers as $header => $value) {
        echo "$header: $value <br />\n";
}
?>

Ça donne ceci :

$ curl http://april.org/sites/default/files/eiFeiK5o.php

Host: april.org <br />
HTTP_CLIENT_IP: 82.67.196.191 <br />
Connection: close <br />
User-Agent: curl/7.38.0 <br />
Accept: */* <br />

$ curl https://april.org/sites/default/files/eiFeiK5o.php

Host: april.org <br />
X-Forwarded-Proto: https <br />
Connection: close <br />
User-Agent: curl/7.38.0 <br />
Accept: */* <br />

Mis à jour par François Poulain il y a presque 8 ans

Je pense que le nœud du problème se situe ici : la conf local.conf n'est pas chargé par nginx car dans nginx.conf les inclusions de conf.d/*.conf ne sont faites que pour le proto http.

Si c'est le cas, j'ai du mal à savoir comment le serveur tient debout. :)

Mis à jour par Vincent-Xavier JUMEL il y a presque 8 ans

On voit ici l'utilisation de proxy_set_header X-Real-IP $remote_addr;

À titre perso, j'ajouterai bien

    proxy_set_header  X-Real-IP $remote_addr;
    proxy_set_header  X-Forwarded-Proto https;
    proxy_set_header  X-Forwarded-For $remote_addr;
    proxy_set_header  X-Forwarded-Host $remote_addr;

qui me semble correspondre à l'ancienne configuration.

Mis à jour par Vincent-Xavier JUMEL il y a presque 8 ans

Bon, après quelques tests avec tcpdump pour lire le trafic réseau entre le frontal et l'applicatif, il semble qu'il faille rajouter proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; dans le bloc location <uri> {} kivabien.

Je ne suis pas sûr qu'un include /etc/nginx/proxy_set_header.conf; soit possible et en tout cas un fichier dans /etc/nginx/conf.d/ ne fonctionne pas. Du moins, je ne sais pas comment nginx lit les directives de configuration et quelles précédences elles ont.

Mis à jour par Vincent-Xavier JUMEL il y a presque 8 ans

François Poulain a écrit :

Je pense que le nœud du problème se situe ici : la conf local.conf n'est pas chargé par nginx car dans nginx.conf les inclusions de conf.d/*.conf ne sont faites que pour le proto http.

Si c'est le cas, j'ai du mal à savoir comment le serveur tient debout. :)

De façon plus générale, la lecture des directives depuis les includes se fait de façon très hasardeuses.

Mis à jour par François Poulain il y a presque 8 ans

  • Statut changé de Nouveau à Résolu

Le soucis est multiple :

D'une part « add_header » ne transmet pas au serveur final le header. Il ne fait que l'ajouter à la réponse en direction du client. Cf http://nginx.org/en/docs/http/ngx_http_headers_module.html#add_header :

Adds the specified field to a response header

Donc clairement dans notre cas les nombreux add_header X_FORWARDED_PROTO https; trouvés dans la conf sont inutiles.

D'autre part il y a eu méprise sur le fonctionnement de proxy_set_header. On en retrouve un peu partout dans la conf, à différents niveaux de blocs. Or, la doc d'nginx précise :

Allows redefining or appending fields to the request header passed to the proxied server. The value can contain text, variables, and their combinations. These directives are inherited from the previous level if and only if there are no proxy_set_header directives defined on the current level.

C'est écrit subtilement mais de fait c'est à prendre au sens strict : il n'y a pas d'héritage comme on pourrait l'attendre intuitivement.

Nous ne sommes pas les seuls à nous être fait avoir, cf par exemple http://serverfault.com/questions/777363/inherit-proxy-set-header-when-using-it-in-location-block

J'ai donc centralisé le proxy_set_header X-Forwarded-Proto $scheme; dans conf.d/local.conf et retiré tous les proxy_set_header inutiles (et sources de bugs) des blocs des sites.

La conf fonctionne pour le drupal (les logs http et https mentionent bien la bonne ip), le icinga est au vert, et au passage ça a résolu le bug #1350.

Mis à jour par Quentin Gibeaux il y a plus de 5 ans

  • Statut changé de Résolu à Fermé

Mis à jour par Christian P. Momon il y a presque 4 ans

  • Assigné à mis à François Poulain
Actions

Formats disponibles : Atom PDF