UDP load balancing

Install the HAProxy Enterprise UDP module

Available since

  • HAProxy Enterprise 2.8r1

HTTP/3 over QUIC

For load balancing HTTP/3 over QUIC, instead see HTTP/3.

The HAProxy Enterprise UDP module enables you to load balance application-layer protocols that are transported over UDP such as syslog, DNS, NTP, and RADIUS.

When configuring the UDP module, you will define a udp-lb section that declares the address and port on which to listen and also the servers to relay UDP traffic to.

Install the UDP module Jump to heading

To enable UDP load balancing, first install the module:

  1. Install the UDP module according to your platform:

    nix
    sudo apt-get install hapee-<VERSION>-lb-udp
    nix
    sudo apt-get install hapee-<VERSION>-lb-udp

    Example for HAProxy Enterprise 3.0r1:

    nix
    sudo apt-get install hapee-3.0r1-lb-udp
    nix
    sudo apt-get install hapee-3.0r1-lb-udp
    nix
    sudo yum install hapee-<VERSION>-lb-udp
    nix
    sudo yum install hapee-<VERSION>-lb-udp

    Example for HAProxy Enterprise 3.0r1:

    nix
    sudo yum install hapee-3.0r1-lb-udp
    nix
    sudo yum install hapee-3.0r1-lb-udp
    nix
    sudo zypper install hapee-<VERSION>-lb-udp
    nix
    sudo zypper install hapee-<VERSION>-lb-udp

    Example for HAProxy Enterprise 3.0r1:

    nix
    sudo zypper install hapee-3.0r1-lb-udp
    nix
    sudo zypper install hapee-3.0r1-lb-udp
    nix
    sudo pkg install hapee-<VERSION>-lb-udp
    nix
    sudo pkg install hapee-<VERSION>-lb-udp

    Example for HAProxy Enterprise 3.0r1:

    nix
    sudo pkg install hapee-3.0r1-lb-udp
    nix
    sudo pkg install hapee-3.0r1-lb-udp
  2. In the global section of your configuration file, add a module-load directive to load the UDP module:

    haproxy
    global
    module-path /opt/hapee-3.0/modules
    module-load hapee-lb-udp.so
    haproxy
    global
    module-path /opt/hapee-3.0/modules
    module-load hapee-lb-udp.so

Enable logging Jump to heading

Available since

  • HAProxy Enterprise 3.0r1

You can enable logging of UDP traffic through the load balancer. HAProxy Enterprise will log a message each time it receives a request datagram and forwards it to the backend server, or when the response datagram is sent back to the client. The log output format contains the source and destination addresses, bytes received or sent, the instance name, and the server if available.

  1. Add the log global directive to your udp-lb section to send log messages to the syslog server declared in the global section:

    haproxy
    global
    maxconn 10000
    log 127.0.0.1 local0
    log 127.0.0.1 local1 notice
    ...
    udp-lb dns
    dgram-bind 192.168.56.25:53
    log global
    proxy-requests 1
    balance roundrobin
    option udp-check
    server dns1 10.10.10.10:53 check
    server dns2 10.10.10.20:53 check
    haproxy
    global
    maxconn 10000
    log 127.0.0.1 local0
    log 127.0.0.1 local1 notice
    ...
    udp-lb dns
    dgram-bind 192.168.56.25:53
    log global
    proxy-requests 1
    balance roundrobin
    option udp-check
    server dns1 10.10.10.10:53 check
    server dns2 10.10.10.20:53 check

    Example log messages:

    log
    Nov 7 20:40:54 hapee hapee-lb[1254]: UDP: request received (58 bytes) from 192.168.56.1:50806 to 192.168.56.25:53 (dns/dns2) Nov 7 20:40:54 hapee hapee-lb[1254]: UDP: response sent (181 bytes) from 192.168.56.25:53 to 192.168.56.1:50806 (dns/dns2)
    log
    Nov 7 20:40:54 hapee hapee-lb[1254]: UDP: request received (58 bytes) from 192.168.56.1:50806 to 192.168.56.25:53 (dns/dns2) Nov 7 20:40:54 hapee hapee-lb[1254]: UDP: response sent (181 bytes) from 192.168.56.25:53 to 192.168.56.1:50806 (dns/dns2)

    Alternatively, you can define a log directive directly in the udp-lb section to set target syslog servers, facility code, and severity level there. For details, see log reference.

  2. Optional: Set log-tag to indicate in the logs which load balancer server proxied the traffic. On the rsyslog side, this sets the $programname variable. It defaults to hapee-lb.

    haproxy
    udp-lb dns
    dgram-bind 192.168.56.25:53
    log global
    log-tag hapee-lb-server1
    proxy-requests 1
    balance roundrobin
    option udp-check
    server dns1 10.10.10.10:53 check
    server dns2 10.10.10.20:53 check
    haproxy
    udp-lb dns
    dgram-bind 192.168.56.25:53
    log global
    log-tag hapee-lb-server1
    proxy-requests 1
    balance roundrobin
    option udp-check
    server dns1 10.10.10.10:53 check
    server dns2 10.10.10.20:53 check

    Example log messages:

    log
    Nov 7 21:20:45 hapee hapee-lb-server1[1433]: UDP: request received (58 bytes) from 192.168.56.1:50768 to 192.168.56.25:53 (dns/dns1) Nov 7 21:20:45 hapee hapee-lb-server1[1433]: UDP: response sent (181 bytes) from 192.168.56.25:53 to 192.168.56.1:50768 (dns/dns1)
    log
    Nov 7 21:20:45 hapee hapee-lb-server1[1433]: UDP: request received (58 bytes) from 192.168.56.1:50768 to 192.168.56.25:53 (dns/dns1) Nov 7 21:20:45 hapee hapee-lb-server1[1433]: UDP: response sent (181 bytes) from 192.168.56.25:53 to 192.168.56.1:50768 (dns/dns1)

Examples Jump to heading

In this section, you’ll see examples of using the UDP module to load balance different types of applications. This will give you an understanding of the syntax, in case you want to load balance an application not shown here.

Load balance syslog Jump to heading

You can use the UDP module to load balance syslog traffic. The UDP module listens on the configured port and will load balance incoming messages to the list of configured servers. Consider the example configuration below:

haproxy
udp-lb syslog-example
dgram-bind 192.168.56.25:3516
proxy-requests 1
proxy-responses 0
balance roundrobin
option udp-check
server srv1 10.10.10.10:1514 check
server srv2 10.10.10.20:1514 check
server srv3 10.10.10.30:1514 check
haproxy
udp-lb syslog-example
dgram-bind 192.168.56.25:3516
proxy-requests 1
proxy-responses 0
balance roundrobin
option udp-check
server srv1 10.10.10.10:1514 check
server srv2 10.10.10.20:1514 check
server srv3 10.10.10.30:1514 check
  • We declare a UDP section using the udp-lb directive and name it syslog-example.
  • We specify a dgram-bind on localhost port 3516. This is where we expect to receive the UDP syslog traffic.

    Listen port

    Use caution when specifying a port for listening for syslog messages. The default rsyslog configuration for HAProxy Enterprise listens for traffic on localhost port 514. If you try to specify the same interface and port, the load balancer will be unable to bind on that interface and will receive no messages.

  • We set proxy-requests to 1. This specifies that the load balancer should load balance on each datagram it receives, since each syslog message will fit into a single datagram.
  • We set proxy-responses to 0. This specifies that the load balancer shouldn’t expect a response from the server.
  • We set the load balancing algorithm to roundrobin.
  • We enable health checks over ICMP with option udp-check. Be sure to enable ICMP traffic in your network to allow this behavior.
    • Note that you could also enable health checks over TCP using option tcp-check.
  • We list three servers that will receive the load balanced syslog traffic. These servers have been configured via rsyslog to expect UDP log traffic on port 1514.

Note that for the best performance for load balancing syslog, it’s recommended that proxy-requests is set to 1 and proxy-responses is set to 0.

Tip

For best performance, add the shards <number> by-thread option to your dgram-bind line. This will distribute incoming traffic over multiple sockets by creating this <number> of listeners and giving each listener its own thread. The example below is for a CPU with 48 cores so that it will use 48 threads, and the traffic will be distributed evenly among the threads since we have specified the by-thread option:

haproxy
udp-lb myudp1
dgram-bind 192.168.56.25:3516 shards 48 by-thread
haproxy
udp-lb myudp1
dgram-bind 192.168.56.25:3516 shards 48 by-thread

Use caution with this option because, while it improves performance, it also increases CPU usage. For more information, see shards reference.

Load balance DNS Jump to heading

You can use the UDP module to load balance DNS traffic over UDP. However, in cases where the DNS response may be larger than one datagram, it’s better to load balance DNS over TCP because TCP supports larger responses. This scenario may occur with DNS-based service discovery. In most cases, a DNS request fits within one datagram, and UDP is sufficient.

Consider the example configuration below:

haproxy
udp-lb udp-dns
dgram-bind 192.168.56.25:53
proxy-requests 1
balance roundrobin
option udp-check
server dns1 10.10.10.10:53 check
server dns2 10.10.10.20:53 check
frontend tcp-dns
mode tcp
bind 192.168.56.25:53
default_backend tcp-dns-backend
backend tcp-dns-backend
mode tcp
balance roundrobin
server srv1 10.10.10.10:53 check
server srv2 10.10.10.20:53 check
server srv3 10.10.10.30:53 check
haproxy
udp-lb udp-dns
dgram-bind 192.168.56.25:53
proxy-requests 1
balance roundrobin
option udp-check
server dns1 10.10.10.10:53 check
server dns2 10.10.10.20:53 check
frontend tcp-dns
mode tcp
bind 192.168.56.25:53
default_backend tcp-dns-backend
backend tcp-dns-backend
mode tcp
balance roundrobin
server srv1 10.10.10.10:53 check
server srv2 10.10.10.20:53 check
server srv3 10.10.10.30:53 check
  • UDP
    • We declare a UDP section using the udp-lb directive and name it udp-dns.
    • We specify a dgram-bind on 192.168.56.25:53.
    • We set proxy-requests to 1. This specifies that the load balancer should load balance on each datagram it receives, since each DNS request will fit into a single datagram.

      proxy-responses

      Unlike our other examples which explicitly set a value for proxy-responses, in the case for DNS, we leave this option unset. By leaving it unset, this specifies that the load balancer should expect an unlimited number of responses from the DNS server. It will forward all responses back to the client.

    • We set the load balancing algorithm to roundrobin.
    • We enable health checks over ICMP with option udp-check. Be sure to enable ICMP traffic in your network to allow this behavior.
      • Note that you could also enable health checks over TCP using option tcp-check.
    • We list two servers that will receive and provide responses for the load-balanced DNS requests.
  • TCP
    • We define a frontend named tcp-dns and a backend named tcp-dns-backend. This frontend and backend will load balance DNS traffic over TCP.
    • We enable TCP healthchecks using check.
    • We list three servers that will receive and provide responses for the load-balanced DNS requests.

For more information, see DNS service discovery.

Alternative configuration

If the port on the dgram-bind line in the udp-lb section is the same as the port you specified on the server lines, you can omit the port from the server lines. Consider the previous example where the load balancer will listen via dgram-bind on 192.168.56.25 on port 53 and then forward requests to servers, also on port 53. You can configure your udp-lb section as follows instead, leaving off the ports on the server lines:

haproxy
udp-lb udp-dns
dgram-bind 192.168.56.25:53
proxy-requests 1
balance roundrobin
option udp-check
server dns1 10.10.10.10 check
server dns2 10.10.10.20 check
haproxy
udp-lb udp-dns
dgram-bind 192.168.56.25:53
proxy-requests 1
balance roundrobin
option udp-check
server dns1 10.10.10.10 check
server dns2 10.10.10.20 check

Load balance NTP Jump to heading

You can use the UDP module to load balance NTP traffic. The UDP module listens on the configured port and will load balance incoming NTP requests to the list of configured NTP servers. It will then return the response to the appropriate client.

Consider the example configuration below:

haproxy
udp-lb ntp
dgram-bind 192.168.56.25:123
proxy-requests 1
proxy-responses 1
balance roundrobin
option udp-check
server srv1 10.10.10.10:123 check
server srv2 10.10.10.20:123 check
server srv2 10.10.10.30:123 check
haproxy
udp-lb ntp
dgram-bind 192.168.56.25:123
proxy-requests 1
proxy-responses 1
balance roundrobin
option udp-check
server srv1 10.10.10.10:123 check
server srv2 10.10.10.20:123 check
server srv2 10.10.10.30:123 check
  • We declare a UDP section using the udp-lb directive and name it ntp.
  • We specify a dgram-bind on all interfaces on port 123. This is the standard NTP port where we expect to receive NTP requests.

    NTP servers

    UDP Port 123 is the standard port for NTP and most implementations don’t allow you to change it. As such, your load balancer and NTP server(s) should not be the same server. The load balancer must bind on port 123 to load balance the NTP requests, which it would be unable to do if the server it runs on is also running as an NTP server (and therefore is already using UDP port 123).

  • We set proxy-requests to 1. This specifies that the load balancer should load balance on each datagram it receives, since each NTP request will fit into a single datagram.
  • We set proxy-responses to 1. This specifies that the load balancer should expect one response from the NTP server. It will then relay the response back to the client.
  • We set the load balancing algorithm to roundrobin.
  • We enable health checks over ICMP with option udp-check. Be sure to enable ICMP traffic in your network to allow this behavior.
    • Note that you could also enable health checks over TCP using option tcp-check.
  • We list three servers that will receive the load balanced NTP traffic. These servers have been configured as NTP servers and will respond to requests on the standard UDP NTP port 123.
Alternative configuration

If the port on the dgram-bind line is the same as the port you specified on the server lines, you can omit the port from the server lines. Consider the previous example where the load balancer will listen via dgram-bind on 192.168.56.25 on port 123 and then forward requests to servers, also on port 123. You can configure your udp-lb section as follows instead, leaving off the ports on the server lines:

haproxy
udp-lb ntp
dgram-bind 192.168.56.25:123
proxy-requests 1
proxy-responses 1
balance roundrobin
option udp-check
server srv1 10.10.10.10 check
server srv2 10.10.10.20 check
server srv2 10.10.10.30 check
haproxy
udp-lb ntp
dgram-bind 192.168.56.25:123
proxy-requests 1
proxy-responses 1
balance roundrobin
option udp-check
server srv1 10.10.10.10 check
server srv2 10.10.10.20 check
server srv2 10.10.10.30 check

Load balance RADIUS Jump to heading

You can use the UDP module to load balance RADIUS authentication traffic. The UDP module listens on the configured ports and will load balance incoming requests to the list of configured RADIUS servers. It will then return the responses to the appropriate client.

Consider the example configuration below where the load balancer is configured to route traffic to both RADIUS authentication (1812) and accounting (1813) ports:

haproxy
udp-lb radius-auth
dgram-bind 192.168.56.25:1812
balance source
server srv1 10.10.10.10:1812
server srv2 10.10.10.20:1812
server srv3 10.10.10.30:1812
udp-lb radius-accounting
dgram-bind 192.168.56.25:1813
balance source
server srv1 10.10.10.10:1813
server srv2 10.10.10.20:1813
server srv3 10.10.10.30:1813
haproxy
udp-lb radius-auth
dgram-bind 192.168.56.25:1812
balance source
server srv1 10.10.10.10:1812
server srv2 10.10.10.20:1812
server srv3 10.10.10.30:1812
udp-lb radius-accounting
dgram-bind 192.168.56.25:1813
balance source
server srv1 10.10.10.10:1813
server srv2 10.10.10.20:1813
server srv3 10.10.10.30:1813
  • We declare two UDP sections using the udp-lb directive and name them radius-auth and radius-accounting.
  • We specify a dgram-bind on all interfaces on port 1812 for radius-auth and port 1813 for radius-accounting.
    • Ensure that the ports you specify match the ports defined in your RADIUS configuration (1812 and 1813 are the RADIUS defaults).
  • We set the load balancing algorithm to source. This is required so that that requests from the same client are routed to the same server.
  • We don’t set proxy-requests. There will be multiple requests from the client, and we want all requests from the same client to be routed to the same server. This applies regardless of any timeout value specified since we have also set balance to source.
  • We don’t set proxy-responses. There will be multiple responses from the RADIUS server.
  • We list three servers that will receive the load balanced RADIUS traffic. These servers have been configured as RADIUS servers and will respond to requests on the default RADIUS ports 1812 and 1813.
Alternative configuration

If the ports on the dgram-bind lines in the udp-lb sections are the same as the ports you specified on the server lines, you can omit the ports from the server lines. Consider the previous example where the load balancer will listen via dgram-bind on 192.168.56.25 on ports 1812 and ports 1813 and then forward requests to servers, either on port 1812 or 1813, depending on what port the load balancer received the request. You can configure your udp-lb section as follows instead, leaving off the ports on the server lines and combining the two udp-lb sections:

haproxy
udp-lb radius
dgram-bind 192.168.56.25:1812
dgram-bind 192.168.56.25:1813
balance source
server srv1 10.10.10.10
server srv2 10.10.10.20
server srv3 10.10.10.30
haproxy
udp-lb radius
dgram-bind 192.168.56.25:1812
dgram-bind 192.168.56.25:1813
balance source
server srv1 10.10.10.10
server srv2 10.10.10.20
server srv3 10.10.10.30

Do you have any suggestions on how we can improve the content of this page?