0

I have the following setup in HAProxy

global
    log /dev/log    local0
    log /dev/log    local1 notice
    chroot /var/lib/haproxy
    stats socket /run/haproxy/admin.sock mode 660 level admin
    stats timeout 30s
    user haproxy
    group haproxy
    daemon

defaults
    log global
    retries 2
    option  dontlognull
    timeout connect 10000
    timeout server 600000
    timeout client 600000

frontend https
    bind 5.x.x.x:443
    default_backend https

backend https
    mode tcp
    balance roundrobin
    option tcp-check
    server traefik 192.168.128.5:9443 check fall 3 rise 2

And it works as expected, the backend server "traefik" is doing the SSL termination of the requests.

The thing is the client source IP I get in the backend server is the HAProxy's IP and I would like to pass the source IP to the backend server.

Is it possible at all? because I tried all the options I saw in internet.

Thanks.

Iris G.
  • 433
  • 1
  • 6
  • 15
  • 1
    I'm a big fan of HAProxy so don't misinterpret this as a negative comment about HAProxy: If traefik is terminating SSL and you're running HAProxy in TCP mode, then what is the point of using HAProxy at all? I don't see the advantage, unless it's part of a bigger scheme that you haven't explained. – Michael - sqlbot Aug 14 '19 at 22:53
  • Yeah traefik is running in a kubernetes cluster where the servers are not publicly exposed, HAProxy is the only one with access to the internal network and the internet – Iris G. Aug 14 '19 at 23:17

1 Answers1

3

At the end the solution was to use https://www.haproxy.com/blog/haproxy/proxy-protocol/ as it is supported by HAProxy and traefik.

global
    log /dev/log    local0
    log /dev/log    local1 notice
    chroot /var/lib/haproxy
    stats socket /run/haproxy/admin.sock mode 660 level admin
    stats timeout 30s
    user haproxy
    group haproxy
    daemon

defaults
    log global
    retries 2
    option  dontlognull
    timeout connect 10000
    timeout server 600000
    timeout client 600000

frontend https
    bind 5.x.x.x:443
    default_backend https

backend https
    mode tcp
    balance roundrobin
    option tcp-check
    server traefik 192.168.128.5:9443 check fall 3 rise 2 send-proxy

And enabling traefik's entrypoint Proxy Protocol as described here: https://docs.traefik.io/configuration/entrypoints/#proxyprotocol

Iris G.
  • 433
  • 1
  • 6
  • 15
  • this is a great solution. However my situation is just slightly different where my `haproxy` is behind cloudflare which doesn't support the PROXY protocol. In this case `haproxy` is proxying cloudflare's IP address, instead of the client IP. Can't seem to find a way to get the `traefik` to add a x-real-ip header with the actual client IP instead of cloudflare's IP. Are you in the same situation, if so have you managed to solve it ? – L. J. Dec 28 '19 at 07:27
  • of course all of this could be solved if only there was a way simply for `traefik` to be able to get a client ip from a specific http header e.g. `cf-connecting-ip`. I guess I'll have to look around to see if `traefik` finally supports this. – L. J. Dec 28 '19 at 07:31
  • Based on this [answer](https://stackoverflow.com/a/56978671/3891117) it looks like traefik hasn't changed between [`v1.7`](https://github.com/containous/traefik/blob/v1.7.20/vendor/github.com/vulcand/oxy/forward/rewrite.go#L39) and [`v2.1`](https://github.com/containous/traefik/blob/v2.1/pkg/middlewares/forwardedheaders/forwarded_header.go#L130) because it still gets `x-real-ip` from the `remoteAddr`. This means `traefik` cannot set `x-real-ip` based on some other header. – L. J. Dec 28 '19 at 10:28