Esta pagina se ve mejor con JavaScript habilitado

Proxy protocol

 ·  🎃 kr0m

Este protocolo resulta especialmente útil cuando estamos balanceando tráfico SSL donde nos es imposible modificar las cabeceras, la mejor solución es configurar el haproxy en modo passthrough terminando el túnel ssl en el server web, pero pasándole la info de la ip origen mediante el protocolo proxy, de este modo el server web recibe la ip del cliente.

La información proporcionada por el protocolo proxy es la misma obtenida utilizando getsockname() y getpeername()

  • Tipo de dirección (AF_INET - IPv4, AF_INET6 - IPv6, AF_UNIX)
  • Protocolo de socket (SOCK_STREAM - TCP, SOCK_DGRAM - UDP)
  • Dirección origen y destino
  • Puerto origen y destino

El uso del protocolo proxy nos permite encadenar varios balanceadores/proxys sin perder en ningún momento la dirección ip origen, el protocolo simplemente consiste en insertar una cabecera fácilmente parseable al inicio de la conexión.


El protocolo soporta dos formatos de cabecera:

  • send-proxy: V1 fácilmente examinable por el humano
  • send-proxy-v2: V2 formato binario

Ambos protocolos han sido diseñados para funcionar con el tamaño mínimo de segmento TCP (576 - 40 = 536 bytes), esto garantiza que la cabecera entera siempre será entregada en una sola transacción.

El protocolo puede aplicarse a multitud de servicios:

  • HTTP
  • SSL
  • FTP
  • SMTP
  • POP
  • IMAP
  • LDAP
  • SSH
  • RDP

Significa esto que si se salta de server en server vía SSH se puede saber la ip origen?
No, significa que si balanceamos tráfico ssh a través de Haproxy, el servidor ssh final recibirá la ip origen del cliente y no la del balanceador ya que el servidor openssh es capaz de interpretar la información proxy-protocol que le envía el Haproxy, de todos modos el servidor ssh no soporta de forma nativa tal funcionalidad.
http://jonnyzzz.com/blog/2017/05/24/ssh-haproxy/

Haproxy permite tanto recibir la información como emitirla.

Parte servidor: “accept-proxy” se debe configurar en la línea “bind”,  útil si se encadenan varios balanceadores.

frontend web-ssl
        bind *:443 accept-proxy
        mode tcp
        default_backend nodes-ssl
  • Parte cliente: “send-proxy” se debe configurar en la línea “server”
backend nodes-ssl
        balance roundrobin
        mode tcp
        server SRV1 X.X.X.X:443 check send-proxy
        server SRV2 Y.Y.Y.Y:443 check send-proxy

NOTA: Para debugear dejamos send-proxy, para producción send-proxy-v2

Para que el servidor web destino lea la información del protocolo proxy debemos seguir unos pasos determinados dependiendo del web-server utilizado.

Para que Apache lea la info del protocolo proxy:

git clone https://github.com/roadrunner2/mod-proxy-protocol
cd mod-proxy-protocol/
make
cp .libs/mod_proxy_protocol.so /usr/lib/apache2/modules/

vi /etc/apache2/httpd.conf

LoadModule proxy_protocol_module modules/mod_proxy_protocol.so
/etc/init.d/apache2 restart

En la config del vhost en cuestión:

CustomLog ${APACHE_LOG_DIR}/access.log "%a %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\""

Para nginx sería:
https://docs.nginx.com/nginx/admin-guide/load-balancer/using-proxy-protocol/

El protocolo proxy nos permite realizar configuraciones muy avanzadas, por ejemplo balancear tráfico mysql y configurar los permisos de los usuarios en base a la ip origen del cliente:
https://www.haproxy.com/blog/using-haproxy-with-the-proxy-protocol-to-better-secure-your-database/

Si te ha gustado el artículo puedes invitarme a un RedBull aquí