Bind dynamic option for Linux

I’m trying to find a way to have HAProxy automatically bind to an address when the address is added to an interface by the system.
I want HAProxy to listen to all the addresses of an interface. I don’t want to listen to the wildcard address. I also know that bind can be restricted to accepting connections on a specific interface in Linux (BINDTODEVICE), but it wouldn’t accept connections coming in from an unbound interface for the address of the bound interface.

I’m looking for a solution similar to DNSMasq’s bind-dynamic option.
From what I understand it listens to Linux’s NetLink messages and automatically binds to addresses added to an interface.

Right now my current work around is to listen to address changes on the interface, pass the addresses as variables for HAProxy, and reload HAProxy on changes.
There are complications with this approach when the address isn’t yet available (interface down or the address wasn’t configured yet).

I’d also be happy with a solution that allows changing the bound address through a Unix socket command similar to the way a backend server address can be changed. The command could be something like set bind <frontend>/<so_id> addr <ip4 or ip6 address> [port <port>].
It would be nice in that case to allow a bind configuration that doesn’t actually bind to anything, but is just there waiting to be configured by the management socket.

The issue I see with this runtime binding is privileged ports and HAProxy dropping root. It would require HAProxy to keep the cap_net_bind_service capability.

It is unclear from your original message if:

  • you know that the addresses are always going to be added to a particular interface (say eth0);
  • or, you have multiple interfaces, and the addresses can be added to any of them;

Why doesn’t the bind ipv4@0.0.0.0:80 interface eth0 (i.e. with wildcard) doesn’t work in your case? (What is the issue or the limitation?)


Anyway, if you don’t find an HAProxy native solution, you can always resort to iptables and DNAT:

  • have HAProxy listen on any loopback address, say 127.0.0.2, on a particular port say 80;
  • create a rule like iptables -t nat -A PREROUTING -p tcp -i eth0 -d <PUBLIC-IP> --dport 80 -m state --state new -j DNAT --to-destination 127.0.0.2:80;
  • set sysctl -w -- net.ipv4.conf.eth0.route_localnet=1;

This variant would work even with interfaces not already present when the HAProxy instance was started.