yacov
yacov

Reputation: 21

HAPROXY reqirep on Host header not forwarding

I have a web server (actually it's a CF environment, but that doesn't matter much) running behind a haproxy version 1.5-dev19 2013/06/17 that accepts requests only for a certain internal domain, let's call it: internal-address. Meaning, that HTTP requests only work if the host header is suffixed by internal-address, (like: Host: login.internal-address).

Users from the WAN can access this web server by connecting to an external address which has ip forwarding to the internal server. But when a user accesses the external address, the Host header is suffixed with external-address, and the web server behind the haproxy rejects the request.

I added reqirep entries in to haproxy configuration:

global
    log 127.0.0.1   syslog info
    daemon
    user vcap
    group vcap
    maxconn 64000
    spread-checks 4

defaults
    log global
    timeout connect 30000ms
    timeout client 300000ms
    timeout server 300000ms

frontend http-in
    mode http
    bind :80
    option httplog
    option forwardfor
    reqadd X-Forwarded-Proto:\ http
    default_backend http-routers


frontend https-in
    mode http
    bind :443 ssl crt /var/vcap/jobs/haproxy/config/cert.pem
    option httplog
    option forwardfor
    option http-server-close
    reqadd X-Forwarded-Proto:\ https
    default_backend http-routers

frontend ssl-in
    mode tcp
    bind :4443 ssl crt /var/vcap/jobs/haproxy/config/cert.pem
    default_backend tcp-routers


backend http-routers
    mode http
    balance roundrobin
    reqirep ^Host:\ uaa.external-address       Host:\ uaa.internal-address
    reqirep ^Host:\ api.external-address       Host:\ api.internal-address
    reqirep ^Host:\ external-address:4443      Host:\ loggregator.internal-address:4443



        server node0 172.20.0.1:8888 check inter 1000



backend tcp-routers
    mode tcp
    balance roundrobin
    reqirep ^Host:\ external-address:4443      Host:\ loggregator.internal-address:4443


        server node0 172.20.0.1:8888 check inter 1000

And every request sent to uaa.external-address or api.external-address is indeed changed and the web server behind the haproxy receives the request as if the Host header is suffixed with internal-address. But the 3rd rule:

reqirep ^Host:\ external-address:4443      Host:\ loggregator.internal-address:4443

Doesn't work :( The web server's access log shows the Host header is sent from external-address:4443 , which implies that the haproxy didn't match the Host header correctly and then the web server rejects the request. The request issued by the client is:

WEBSOCKET REQUEST: [2014-10-01T10:25:07+03:00]
GET /tail/?app=029a1269-67fe-46e2-85f7-e1b0b5d34193 HTTP/1.1
Host: wss://external-address:4443
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: [HIDDEN]
Origin: http://localhost
Authorization: [PRIVATE DATA HIDDEN]

Does anyone know what's wrong with the rule?

EDIT:

I deleted the rules from the backend and created more generic rules in the frontend, and it still doesn't work for websockets:

frontend https-in
    mode http
    bind :443 ssl crt /var/vcap/jobs/haproxy/config/cert.pem
    option httplog
    option forwardfor
    option http-server-close
    reqadd X-Forwarded-Proto:\ https
    default_backend http-routers
    reqirep ^Host:\ (.*).external-address(.*)  Host:\ \1.internal-address\2


frontend ssl-in
    mode tcp
    bind :4443 ssl crt /var/vcap/jobs/haproxy/config/cert.pem
    default_backend tcp-routers
    reqirep ^Host:\ (.*).external-address(.*)      Host:\ \1.internal-address\2

Thanks in advance.

Upvotes: 2

Views: 10041

Answers (1)

Baptiste
Baptiste

Reputation: 1759

Which version of HAProxy are you running? If 1.4, please add 'option http-server-close' into your defaults section.

By default, 1.4 is in tunnel mode, which let HAProxy analyse the first request and response and transfer subsequent requests and responses as payload.

In 1.5, it should work out of the box. HAProxy uses a new mode "http-keep-alive" which allows HAProxy to analyse all the content all the time.

Baptiste

Upvotes: 1

Related Questions