Haproxy - frontend vs backend ports

Posted on Feb 13, 2017

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.