X-Forwarded-For not working

Hi,
I am using HTTP mode (ssl traffic) with option forwardfor in the frontend and backend, but I don’t get the header in the backend servers. Is there anything I am missing?

frontend www_el_ssl
  bind 10.11.6.41:443 ssl crt /etc/haproxy/el.pem
  mode http
  default_backend www_el_ssl_back
  description www.el.de SSL version
  log global
  maxconn 8000
  monitor-uri /monitoruri
  option forwardfor
  option httplog
  option dontlognull
  timeout client 30s
  use_backend dm_ssl_back if { hdr(host) -i dm.domain.com }

backend dm_ssl_back
  mode http
  timeout connect 5s
  timeout server 31s
  option forwardfor
  server a1 10.12.33.226:443 check inter 5s fall 4 rise 3 ssl verify none

I tried also to log all headers but I was just receiving {} in the logs.

Thanks.

here is the version:

# haproxy -vv
HA-Proxy version 1.8.14-52e4d43 2018/09/20
Copyright 2000-2018 Willy Tarreau <willy@haproxy.org>

Build options :
  TARGET  = linux2628
  CPU     = generic
  CC      = gcc
  CFLAGS  = -O2 -g -fno-strict-aliasing -Wdeclaration-after-statement -fwrapv -fno-strict-overflow -Wno-unused-label
  OPTIONS = USE_LINUX_TPROXY=1 USE_CRYPT_H=1 USE_GETADDRINFO=1 USE_ZLIB=1 USE_REGPARM=1 USE_OPENSSL=1 USE_LUA=1 USE_SYSTEMD=1 USE_PCRE=1

Default settings :
  maxconn = 2000, bufsize = 16384, maxrewrite = 1024, maxpollevents = 200

Built with OpenSSL version : OpenSSL 1.0.2k-fips  26 Jan 2017
Running on OpenSSL version : OpenSSL 1.0.2k-fips  26 Jan 2017
OpenSSL library supports TLS extensions : yes
OpenSSL library supports SNI : yes
OpenSSL library supports : SSLv3 TLSv1.0 TLSv1.1 TLSv1.2
Built with Lua version : Lua 5.3.4
Built with transparent proxy support using: IP_TRANSPARENT IPV6_TRANSPARENT IP_FREEBIND
Encrypted password support via crypt(3): yes
Built with multi-threading support.
Built with PCRE version : 8.32 2012-11-30
Running on PCRE version : 8.32 2012-11-30
PCRE library supports JIT : no (USE_PCRE_JIT not set)
Built with zlib version : 1.2.7
Running on zlib version : 1.2.7
Compression algorithms supported : identity("identity"), deflate("deflate"), raw-deflate("deflate"), gzip("gzip")
Built with network namespace support.

Available polling systems :
      epoll : pref=300,  test result OK
       poll : pref=200,  test result OK
     select : pref=150,  test result OK
Total: 3 (3 usable), will use epoll.

Available filters :
	[SPOE] spoe
	[COMP] compression
	[TRACE] trace

Did you confirm that your backend is actually looking at this header? How do you know haproxy does not send it?

The backend is Tomcat app so I implemented the config as per Tomcat manual. On the other hand I try to log the request in the HAProxy server like:

 option forwardfor
 log-format X-Forwarded-For\ %[capture.req.hdr(0)]\ %hr\ %hrl\ %hs\ %hsl

but I get {}:

haproxy[65776]: 10.11.108.214:57225 [29/Mar/2019:09:44:32.068] www_el_ssl~ dm_ssl_back/app19 0/0/0/22/22 302 1291 - - ---- 4/4/0/1/0 0/0 {} "POST /vaadinServlet/HEARTBEAT/?v-uiId=4 HTTP/1.1"

I have no idea at this point what you are trying to do.

Sorry, so now I have those 3 lines in the frontend:

  option forwardfor
  capture request header X-Forwarded-For len 15
  log-format %[capture.req.hdr(0)]:%cp\ [%t]\ %f\ %b/%s\ %Tq/%Tw/%Tc/%Tr/%Tt\ %ST\ %B\ %CC\ %CS\ %tsc\ %ac/%fc/%bc/%sc/%rc\ %sq/%bq\ {%hrl}\ {%hsl}\ %{+Q}r

And this is the HAProxy log I get:

haproxy[76963]: 10.11.109.4:35474 [29/Mar/2019:15:51:24.921] www_el_ssl~ archive_ssl_back/r4 0/0/0/2/2 200 428 - - ---- 7/6/0/1/0 0/0 {} "GET /VAADIN/themes/base/shadow/img/bottom-right.png HTTP/1.1"

So I am asuming that inside {} I should see the headers being logged, right? including x-forwarded-for

Logging the headers is just for debugging purpose, I don’t actually need it, I would only need the X-Forwarded-For to be passed to the backend.
So users hit port 80 on HAProxy, then I redirect to 443, then it goes to a backend that could be either SSL or non SSL.

Thanks.

I doubt you can log headers that haproxy inserted itself, how can you be sure the capture happens after the header has been inserted? It is most likely to other way around.

Downgrade the backend to plaintext HTTP for a second and verify with tcpdump if the header is there would be my suggestion.

Otherwise use the openssl command to simulate a test HTTPS server so you can take a look at the request.

I assume Tomcat is incorrectly setup.

I will test it next week. Thanks for your support!

Best.

You are right, port 80 is attaching the X-Forwarded-For, so I guess it has to do with the logging options from the Tomcat.

Thanks for you help.