Using the right tool for the job…

I encountered an interesting problem after setting up load balancing for a web service one of our devs needed to make available: Accessing a dummy page with a HTTP GET went flawlessly when using a regular web browser, but POSTing to it using his client software or curl resulted in a 503 error. At first I suspected a misconfigured firewall, but when reading the HAProxy logs, I discovered that the 503 error was accompanied by a “<NOSRV>” tag, meaning that HAProxy couldn’t make out to which backend it should forward the client data.

The solution was simple: Up until now, I’d only forwarded traffic from modern web browsers, using the ssl_fc_sni function to find the appropriate backend based on the server name requested by the client. What I forgot when setting up these rules was that the POST wouldn’t be performed by a modern browser, so I had no guarantee that the client would be capable of the SNI (Server Name Indication) protocol extension.

The simple solution was to use the host record from the HTTP header instead:

use_backend backend1 if { hdr(Host) -i service.domain.com }

Note that this requires that SSL is terminated in HAProxy. My configuration terminates SSL, reads and modifies relevant HTTP information, then establishes a new SSL connection to the backend servers using the appropriate certificate checks. This way protocol secrecy should be kept anytime traffic is in transit.