Como ya comentamos en un artÃculo anterior el protocolo ProxyProtocol resulta muy útil cuando estamos balanceando tráfico mediante un HaProxy, de este modo recibiremos la ip del cliente y no la del balanceador en el servidor final. Anteriormente configuramos HaProxy y Apache, en esta ocasión configuraremos Nginx.
Para poder utilizar ProxyProtocol con Nginx necesitamos el módulo RealIp, este viene habilitado en las opciones de compilación por defecto asà que compilamos e instalamos Nginx directamente:
Comprobamos que se haya compilado con el módulo necesario:
configure arguments: --prefix=/usr --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error_log --pid-path=/run/nginx.pid --lock-path=/run/lock/nginx.lock --with-cc-opt=-I/usr/include --with-ld-opt=-L/usr/lib64 --http-log-path=/var/log/nginx/access_log --http-client-body-temp-path=/var/lib/nginx/tmp/client --http-proxy-temp-path=/var/lib/nginx/tmp/proxy --http-fastcgi-temp-path=/var/lib/nginx/tmp/fastcgi --http-scgi-temp-path=/var/lib/nginx/tmp/scgi --http-uwsgi-temp-path=/var/lib/nginx/tmp/uwsgi --with-compat --with-http_v2_module --with-pcre --with-http_realip_module --with-http_ssl_module --without-stream_access_module --without-stream_geo_module --without-stream_limit_conn_module --without-stream_map_module --without-stream_return_module --without-stream_split_clients_module --without-stream_upstream_hash_module --without-stream_upstream_least_conn_module --without-stream_upstream_zone_module --without-mail_imap_module --without-mail_pop3_module --without-mail_smtp_module --user=nginx --group=nginx
Configuramos Nginx para que acepte ProxyProtocol, le indicamos la ip del HaProxy, que sustituya la ip del HaProxy por la recibida por ProxyProtocol, que asigne las variables correctas y que guarde los logs con las variables nuevas:
http {
proxy_set_header X-Real-IP $proxy_protocol_addr;
proxy_set_header X-Forwarded-For $proxy_protocol_addr;
log_format proxyprotocollogformat
'$proxy_protocol_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent"';
server {
listen 80 proxy_protocol;
set_real_ip_from HA_IP/MASK;
real_ip_header proxy_protocol;
access_log /var/log/nginx/localhost.access_log proxyprotocollogformat;
}
}
Los logs obtenidos ahora tendrán la ip del cliente:
CLIENT_IP - - [19/May/2020:10:21:19 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (X11; FreeBSD amd64; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36"
Si lo único que vemos en los logs son entradas como estas:
- - - [02/Jan/2021:20:22:23 +0100] "PROXY TCP4 192.168.69.11 192.168.69.10 12308 443" 400 157 "-" "-"
- - - [02/Jan/2021:20:22:25 +0100] "\x00" 400 157 "-" "-"
Es que no hemos configurado correctamente la lÃnea listen de la sección server de Nginx, falta el parámetro proxy_protocol.
NOTA: Si se habilita ProxyProtocol queda habilitado de forma global, no se puede configurar por Vhost. Otra opción podrÃa ser habilitar ProxyProtocol pero en un puerto distinto y configurar el HaProxy acorde a estos puertos.