Haproxy - frontend vs backend ports
A very simple frontend/backend definition in haproxy can look like this:
frontend http
bind 0.0.0.0:80 tfo
bind 0.0.0.0:443 tfo ssl npn http/1.1,http/1.0 no-sslv3 crt /etc/ssl/services/
default_backend somebackend
backend somebackend
option forwardfor
option httpchk HEAD /check.txt HTTP/1.1\r\nHost:\ somehost
server somebackend1 172.16.0.1 check port 80
$ curl -I http://haproxy.example.com/
Works.
$ curl -I https://haproxy.example.com/
Does not work.
The log snippet also looks ok:
http~ somebackend/somebackend1 0/3004/-1/-1/3005 503 3090 - - SC-- 529/126/0/0/3 0/0 "GET / HTTP/1.1"
But why does it report 503?
As it turns out if you don’t specify a port in the server line, haproxy uses the local port from the frontend connection as destination port for the backend connection. As our backend server was only listening to http, the connect request to the https port timed out and subsequently haproxy reported a 503 to our client connection.
Fix:
backend somebackend
option forwardfor
option httpchk HEAD /check.txt HTTP/1.1\r\nHost:\ somehost
server somebackend1 172.16.0.1:80 check port 80
# ^^^--- Fix
Now we always talk to port 80 of the backend no matter which port the client connects to.