How to bind haproxy on all interfaces except localhost without mentioning each interface separately

haproxy

I've two hosts, host1 and host2. There's HAProxy on both hosts that is currently listening on an ip:port. This does SSL termination for a service listening at localhost:port on both hosts.

Now, we've introduced high availability, so we have a floating IP (let's call it VIP) that resides on only one of the two hosts at any given time, and the clients access the service using this floating IP instead of the one tied to the NIC.

So to continue doing successful SSL termination, we need to bind the the HAProxy on this floating vip on the node that currently owns this VIP. It'll be pretty easy to bind HAProxy on 0.0.0.0 but unfortunately, the service has to be listening on localhost on the same port as HAProxy due to things I've no control of. And I'm not in a position to change the port on which the HAProxy can listen as well.

Is there any way to configure HAProxy to listen on all hosts except localhost?

Best Answer

I don't know any way to exclude a 127.0.0.1 from the wildcard * address. This SO answer says

[On Linux it's] possible to first bind a listening TCP socket to a specific IP address and port combination and later on bind another one to a wildcard IP address and the same port.

So if you start localhost-bound daemon first (lets call it httpservice) and wildcard haproxy second, everything should work as you requested.

But you need to plan what happens if httpservice dies on you. You wouldn't be able to restart it, because haproxy would block your port. To make this more admin-friendly, you would need to delete the rc.d scripts (or systemctl units) and make one shared rc.d script:

  • rc.d script start action:

    if httpservice dead
        stop haproxy
        wait until nothing is bound to *:port
        start httpservice 
        wait until it binds to 127.0.0.1:port
        start haproxy
    else 
        start haproxy
    
  • stop action:

    stop haproxy
    stop httpservice
    wait until nothing is bound to 127.0.0.1:port
    

Ugly as hell.