Ensure that HAProxy can assign a non-local IP address.
You can listen on every address, but this is not is always suitable when using VPN, floating ip, dedicated interface, or any combination of these.
By default service cannot bind to a non-local IP address.
$ sudo journalctl --unit haproxy
Oct 03 00:37:10 milosz-IdeaCentre-5-14IOB6 systemd[1]: Starting HAProxy Load Balancer... Oct 03 00:37:10 milosz-IdeaCentre-5-14IOB6 haproxy[1753889]: [NOTICE] (1753889) : haproxy version is 2.4.18-0ubuntu1 Oct 03 00:37:10 milosz-IdeaCentre-5-14IOB6 haproxy[1753889]: [NOTICE] (1753889) : path to executable is /usr/sbin/haproxy Oct 03 00:37:10 milosz-IdeaCentre-5-14IOB6 haproxy[1753889]: [ALERT] (1753889) : Starting frontend http_frontend: cannot bind socket (Cannot assign requested address) [192.0.2.100:80] Oct 03 00:37:10 milosz-IdeaCentre-5-14IOB6 haproxy[1753889]: [ALERT] (1753889) : [/usr/sbin/haproxy.main()] Some protocols failed to start their listeners! Exiting. Oct 03 00:37:10 milosz-IdeaCentre-5-14IOB6 systemd[1]: haproxy.service: Main process exited, code=exited, status=1/FAILURE Oct 03 00:37:10 milosz-IdeaCentre-5-14IOB6 systemd[1]: haproxy.service: Failed with result 'exit-code'. Oct 03 00:37:10 milosz-IdeaCentre-5-14IOB6 systemd[1]: Failed to start HAProxy Load Balancer.
Sample HAProxy service configuration to illustrate this issue.
$ cat /etc/haproxy/haproxy.cfg
global log /dev/log local0 log /dev/log local1 notice chroot /var/lib/haproxy stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners stats timeout 30s user haproxy group haproxy daemon # Default SSL material locations ca-base /etc/ssl/certs crt-base /etc/ssl/private # See: https://ssl-config.mozilla.org/#server=haproxy&server-version=2.0.3&config=intermediate ssl-default-bind-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384 ssl-default-bind-ciphersuites TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256 ssl-default-bind-options ssl-min-ver TLSv1.2 no-tls-tickets defaults log global mode http option httplog option dontlognull timeout connect 5000 timeout client 50000 timeout server 50000 errorfile 400 /etc/haproxy/errors/400.http errorfile 403 /etc/haproxy/errors/403.http errorfile 408 /etc/haproxy/errors/408.http errorfile 500 /etc/haproxy/errors/500.http errorfile 502 /etc/haproxy/errors/502.http errorfile 503 /etc/haproxy/errors/503.http errorfile 504 /etc/haproxy/errors/504.http frontend http_frontend mode http bind 192.0.2.100:80 default_backend backend backend backend http-request return status 200 content-type "text/plain" string "OK"
By default it will not start as it cannot assign requested address, because it is not configured on any interface.
$ sudo haproxy -f /etc/haproxy/haproxy.cfg
[NOTICE] (1753706) : haproxy version is 2.4.18-0ubuntu1 [NOTICE] (1753706) : path to executable is /usr/sbin/haproxy [ALERT] (1753706) : Starting frontend http_frontend: cannot bind socket (Cannot assign requested address) [192.0.2.100:80] [ALERT] (1753706) : [haproxy.main()] Some protocols failed to start their listeners! Exiting.
Inspect sysctl configuration related to this behavior.
$ sysctl --all --pattern ip_nonlocal_bind
net.ipv4.ip_nonlocal_bind = 0 net.ipv6.ip_nonlocal_bind = 0
Allow processes to bind to a non-local IPv4 and IPv6 addresses.
$ sudo sysctl --write net.ipv4.ip_nonlocal_bind=1 net.ipv6.ip_nonlocal_bind=1
net.ipv4.ip_nonlocal_bind = 1 net.ipv6.ip_nonlocal_bind = 1
Now service will work as expected.
$ sudo systemctl start haproxy
$ sudo systemctl status haproxy
* haproxy.service - HAProxy Load Balancer Loaded: loaded (/lib/systemd/system/haproxy.service; enabled; vendor preset: enabled) Active: active (running) since Mon 2022-10-03 00:41:56 CEST; 4s ago Docs: man:haproxy(1) file:/usr/share/doc/haproxy/configuration.txt.gz Process: 1755313 ExecStartPre=/usr/sbin/haproxy -Ws -f $CONFIG -c -q $EXTRAOPTS (code=exited, status=0/SUCCESS) Main PID: 1755315 (haproxy) Tasks: 9 (limit: 38126) Memory: 71.1M CPU: 115ms CGroup: /system.slice/haproxy.service |-1755315 /usr/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid -S /run/haproxy-master.sock `-1755317 /usr/sbin/haproxy -Ws -f /etc/haproxy/haproxy.cfg -p /run/haproxy.pid -S /run/haproxy-master.sock Oct 03 00:41:56 milosz-IdeaCentre-5-14IOB6 systemd[1]: Starting HAProxy Load Balancer... Oct 03 00:41:56 milosz-IdeaCentre-5-14IOB6 haproxy[1755315]: [NOTICE] (1755315) : New worker #1 (1755317) forked Oct 03 00:41:56 milosz-IdeaCentre-5-14IOB6 systemd[1]: Started HAProxy Load Balancer.
Ensure that configuration will be applied at boot.
$ echo "net.ipv4.ip_nonlocal_bind = 1 | sudo tee /etc/sysctl.d/90-ipv4_nonlocal_bind.conf
$ echo "net.ipv6.ip_nonlocal_bind = 1 | sudo tee /etc/sysctl.d/90-ipv6_nonlocal_bind.conf
Simple as that.