How to forward client's IP address to Nginx from Haproxy in tcp mode

17,294

Solution 1

You should use listen 443 ssl proxy_protocol; on nginx side and send_proxy directive on Haproxy side.

Using Proxy Protocol with Nginx

Haproxy documentation

Send PROXY protocol header from HAProxy

Solution 2

My working configuration HA side:

# USED FOR some_service
frontend  some_service_https
  mode tcp
  bind *:443
  option tcplog
  option forwardfor
  default_backend some_service_https

backend some_service_https
  balance roundrobin
  stick-table type ip size 1m expire 1h
  stick on src
  server some_service 192.168.1.2:443 send-proxy check

And NGINX side:

set_real_ip_from 192.168.1.1; # HAproxy local IP
set_real_ip_from 183.55.111.30; # HAproxy external IP
real_ip_header proxy_protocol; # proxy_protocol needed
real_ip_recursive on;

upstream some_service {
  server unix:/tmp/unicorn.some_service.sock fail_timeout=0;
}

server {
  server_name some_service.myserver.com some_service_1.myserver.com;
  listen 443 proxy_protocol; # proxy_protocol needed
  root /opt/apps/some_service/current/public;
  add_header X-Whom some_service_1.myserver.com;

Don't forget to add "send-proxy" on HA backend and real_ip_header proxy_protocol and listen proxy_protocol to NGINX. Works even you use 80 or 443 port or both.

Share:
17,294

Related videos on Youtube

Sinai
Author by

Sinai

Linux system administration, Database administration, Linux based server and Database Troubleshooting and Tuning, DevOps tools (e.g. Docker, Jenkins, Ansible, JFrog, Gitlab), Apache Mesos, Ceph, Specialized in Zabbix monitoring solution, Linux Shell scripting and Python programming. Interested in NoSql DBMSs, Wireless sensor networks, Network security, innovating high-tech appliances and embedded systems.

Updated on September 18, 2022

Comments

  • Sinai
    Sinai over 1 year

    I want to forward real client's ip address from haproxy to my backend servers in tcp mode. The configuration of Haproxy is as follows:

    frontend main
        bind *:80
        mode http
        option forwardfor
        option http-server-close    
        default_backend app-main
    
    frontend https_main
        bind *:443
        mode tcp
        option tcplog
        option tcpka
        default_backend app-ssl
    
    backend app-main
        balance roundrobin
        server web1 192.168.1.22:8080 check fall 3 rise 2
        server web2 192.168.1.33:8080 check fall 3 rise 2
    
    backend app-ssl
        balance roundrobin
        mode tcp
        option ssl-hello-chk
        server web3 192.168.1.44:443
    

    backend servers for http requests are apache and I have replaced the following line in httpd.conf with log lines, so I can now get the client's ip addreses correctly:

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

    My backend server for https uses Nginx as a reverse_proxy for ssl termination and sends the requests to apache backends. My problem is that I don't know how can I get the real client's ip address in nginx logs? I googled a lot and found some solution on serverfault and stackoverflow, but none of them resolved my problem in forwarding client's ip address in tcp mode in haproxy. Any help is appreciated.

  • Jose Cifuentes
    Jose Cifuentes over 6 years
    If the backend server is a standard Jetty server with SSL enabled instead of NGinx, how does the picture change? Do I need to do a any particular configuration on the Java side?
  • Jose Cifuentes
    Jose Cifuentes about 6 years
    Isn't the proxy protocol an attack vector? It looks like a plain unencrypted header that could be intercepted and modified. Any comments?
  • James White
    James White about 4 years
    option forwardfor won't do anything in TCP mode.