IP distantes avec HAProxy


19

Je teste une nouvelle configuration de serveur Web qui rencontre quelques problèmes. Essentiellement, nous avons un serveur Web, où le code utilise l'IP distante pour certaines choses intéressantes, ainsi que des répertoires apache sécurisés vers certains IP (notre bureau, etc.).

Cependant, nous venons de jeter cela derrière ha_proxy afin que nous puissions envisager d'ajouter d'autres serveurs d'applications, mais maintenant l'IP distante est toujours transmise en tant qu'IP proxy, pas le véritable utilisateur distant. Cela signifie que nous ne pouvons pas accéder à certains endroits, et notre application se comporte un peu bizarrement là où l'IP de l'utilisateur est importante.

Notre configuration est la suivante:

global
      maxconn 4096
      pidfile /var/run/haproxy.pid
      daemon

defaults
      mode http
      retries 3
      option redispatch
      maxconn 2000
      contimeout 5000
      clitimeout 50000
      srvtimeout 50000

listen farm xxx.xxx.xxx.xxx:80
      mode http
      cookie GALAXY insert
      balance roundrobin
      option httpclose
      option forwardfor
      stats enable
      stats auth username:userpass

      server app1 xxx.xxx.xxx.xxx:80 maxconn 1 check

Réponses:


31

Cité dans le doc HAProxy sur haproxy.1wt.eu .

- si l'application doit enregistrer l'adresse IP du client d'origine, utilisez le
  option "forwardfor" qui ajoutera un en-tête "X-Forwarded-For" avec le
  l'adresse IP du client d'origine. Vous devez également utiliser "httpclose" pour vous assurer
  que vous réécrirez toutes les demandes et pas seulement la première de chaque
  session:
        option httpclose
        option forwardfor

Il est indiqué que l'application doit traiter l'en-tête HTTP X-Forwarded-For pour connaître l'adresse IP du client. Semble être la seule façon d'aller dans votre cas.

Mis à jour pour HAProxy 1.4

Haproxy 1.4 a introduit un nouveau mode avec "option http-server-close". Il a toujours fermé la connexion au serveur, mais maintient la connexion avec le client si possible et utilisé. Sur la plupart des configurations, vous voudrez probablement l'utiliser car cela aide à la latence sur la seule partie à latence élevée de votre connexion (entre Haproxy et le client).

   option http-server-close
   option forwardfor

2
Mieux utiliser option forwardfor header X-Real-IPet reqidel ^X-Real-IP:cela arrête de truquer les adresses IP dans vos journaux. FYI: X-Real-IPest l'en-tête par défaut pour NginXl'option ' set_real_ip_from.
Tino

La question ne mentionne pas nginx. X-Real-IP ne fonctionnerait pas.
Rick Fletcher

1. ces deux options doivent-elles être définies dans la section de configuration frontend ou backend? (Parce qu'ils ne semblent pas fonctionner ici) 2. Un type de configuration est-il également requis au niveau de Tomcat?
yglodt

6

Il existe un moyen de recompiler HAproxy pour inclure Tproxy qui permettra le transfert de l'adresse source.

Il y a un article de blog ici à ce sujet: http://blog.loadbalancer.org/configure-haproxy-with-tproxy-kernel-for-full-transparent-proxy/

Quelques notes:

Le dernier noyau Linux (2.6.28-11-server) inclut la prise en charge de TProxy, il n'est donc pas nécessaire de recompiler le noyau.

Assurez-vous de configurer les serveurs de votre batterie de serveurs Web avec une adresse de passerelle par défaut qui pointe vers le serveur HAProxy.



1

Notez qu'il semblerait que vous pouvez remplacer ce que l'application voit ma modification des en-têtes Apache:

SetEnvIf X-Forwarded-For (.*) REMOTE_ADDR=$1
SetEnvIf X-Forwarded-For (.*) REMOTE_IP=$1

Cependant, cela ne fonctionne pas pour l'accès Apache via "Autoriser à partir de", etc.


Cela peut entraîner des résultats imprévisibles si le client envoie un en- X-Forwarded-Fortête existant lorsque la nouvelle adresse IP est ajoutée à la fin de la liste existante, séparée par une virgule et un espace. Modifiez le (.*)pour ([^ ]*)$récupérer uniquement la dernière IP ... ou utilisez mod_rpafou mod_remoteippour Apache 2.4 ou version ultérieure.
Ladadadada

1

HAProxy, de par sa conception, ne peut pas transmettre l'adresse IP d'origine au serveur réel, à peu près comme n'importe quel autre proxy.

Une solution peut être, si votre seul problème est avec un serveur Web, de rechercher dans l'en-tête HTTP X-forwarded-for, qui devrait contenir l'adresse du client. Maintenant, c'est à peu près spécifique à l'application / au langage, mais jetez un œil à cet exemple en php:

$headers = apache_request_headers();

$real_client_ip = $headers["X-Forwarded-For"];

Si vous souhaitez également enregistrer l'adresse d'origine, vous pouvez modifier le LogFormat dans httpd.conf pour qu'il ressemble à ceci:

LogFormat "%h %l %u %t \"%r\" %>s %b \"%{X-Forwarded-For}i\"" common


faux, vous pouvez avec l'option "forwardfor"
wittwerch

Oui, et cette option est activée par défaut, mais elle définit l’en-tête HTTP X-Forwarded-For. Ce que je disais, et il me semble que c'est ce que le demandeur demandait réellement, concernait l'adresse source réelle du paquet IP
Thiagodrv

0

Eh bien, il semble que le X-Forwarded-for ne fonctionne pas bien pour votre configuration. Alors, y a-t-il une raison particulière pour laquelle vous vous en tenez à l'haproxy? Il semble que IPVS soit plus adapté à vos besoins (j'utilise en fait ldirector qui à son tour utilise ipvs).

Jeter un coup d'œil à:

http://kb.linuxvirtualserver.org/wiki/IPVS

et

http://www.vergenet.net/linux/ldirectord/

L'utilisation d'IPVS en mode «Tunneling IP» ou «Routage direct» préserve l'adresse du client.


0

Essayez mod_extract_forwarded depuis http://www.openinfo.co.uk/apache/

LoadModule extract_forwarded_module modules/mod_extract_forwarded.so
MEFOrder refuse,accept
MEFRefuse all
MEFAccept xxx.xxx.xxx.xxx

-1

Moyen simple avec haproxy en mode tcp et nginx:

ajouter send-proxy comme option de serveur:

haproxy.conf:

.

.

écouter ssl 0.0.0.0:443

mode tcp

équilibre lessconn

option httpchk GET / ping

option log-health-checks

serveur w1 192.168.1.1:443 send-proxy vérifier check-ssl vérifier aucun

serveur w2 192.168.1.1:443 envoyer-proxy vérifier check-ssl vérifier aucun

.

.

Nginx doit prendre en charge le protocole proxy

nginx.conf:

.

.

écouter 192.168.1.1:443 ssl proxy_protocol;

.

.

set_real_ip_from 192.168.1.0/24;

real_ip_header proxy_protocol;

.

.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.