Enabling UDP load-balancing with Nginx on Debian 9 (Stretch)

User Datagram Protocol (UDP) is commonly used for DNS resolution and video/voice streaming applications. The advantage of UDP over TCP is that it has less overhead (smaller packet size). You can therefore send more data on your network with less latency. However this comes at the expense of data reliability.

Lemme guide you to how setup an Nginx server (10.0.0.5) which forwards UDP packets from port 514 to a Graylog server (10.0.0.10) on port 514 itself. We will be sending logs from a VM on 10.0.0.2

On your nginx server:

# echo “deb http://nginx.org/packages/debian/ stretch nginx” > /etc/apt/sources.list.d/nginx.list
# apt-get update
# apt-get install nginx

You should now have nginx installed. Paste the following snippet in your `/etc/nginx/nginx.conf`

stream {
  upstream graylog_upstreams {
    server 10.0.0.10:514;
  }

  server {
    listen 514 udp;
    proxy_pass graylog_upstreams;
    proxy_responses 0;
    proxy_bind $remote_addr transparent;
  }
}

Check if Nginx is listening on UDP port 514

root@prod-r7-nginx:~# ss -ntplu

However if you sending data to this port from another machine, you’ll notice that no data is sent to the backend server. Despite `tcpdump` will see the data coming and being sent.

IP 10.0.0.2.38696 > 10.0.0.5.514: SYSLOG kernel.info, length: 120
IP 10.0.0.2.45605 > 10.0.0.10.514: SYSLOG kernel.info, length: 120

We need to tell the kernel to actually route IP addresses which doesn’t belong to him thus acting like a router. We do so by the following command

sed -i "s/#net.ipv4.ip_forward.*/net.ipv4.ip_forward=1/" /etc/sysctl.conf
echo 1 > /proc/sys/net/ipv4/ip_forward

And that’s it 🙂

Do you like nginx’s UDP loadbalancing feature?

Leave a Reply

Your email address will not be published. Required fields are marked *