I had been tasked with finding a way to load balance UDP on AWS. Normally we would use ipvsadm in at layer 4 DR but because of the limitations in EC2 this is not possible so another method was needed.
So this is a short guide on how to get a simple UDP load balancer running. We will be using pen, it is described as a simple tcp load balancer and has been around for a while.
Our current version of Enterprise AWS for EC2 now fully supports UDP load balancing in high performance layer 4 NAT mode.
Even though it is described as a TCP loadbalancer the Zen loadbalancer project has written a patch which will allow pen to load balance UDP which you can download from http://sourceforge.net/projects/zenloadbalancer/files/zenlb_pen_c.patch/
Once you have downloaded the source code, patch and uncompressed them in the same folder you will need to apply the patch by simply running.
root@penudp:~/pen-0.18.0# patch pen.c zenlb_pen_c.patch
From here it is just the normal build.
./configure make make install
And that's it, so now if we run pen we see it now has UDP support.
root@penudp:~/pen-0.18.0# pen usage: pen [-C addr:port] [-X] [-b sec] [-S N] [-c N] [-e host[:port]] [-t sec] [-x N] [-w dir] [-HPWadfhrs] [-o option] [-E certfile] [-K keyfile] [-G cacertfile] [-A cacertdir] [-Z] [-R] [-L protocol] [host:]port h1[:p1[:maxc1[:hard1[:weight1[:prio1]]]]] [h2[:p2[:maxc2[:hard2[:weight2[:prio2]]]]]] ...
-B host:port abuse server for naughty clients -C port control port -T sec tracking time in seconds (0 = forever)  -H add X-Forwarded-For header in http requests -U use udp protocol support
Now to test this I have just brought up a couple of DNS servers running bind.
These have the address 192.168.74.221 and 192.168.74.222. So we start pen by running:
root@penudp:/# pen -r -U 53 192.168.74.221:53 192.168.74.222
This will start pen listening on port 53 and balance the servers 192.168.74.221 and 192.168.74.222 in round robin mode.
We can then check its running with:
root@penudp:/# netstat -tnulp | grep pen udp 0 0 0.0.0.0:53 0.0.0.0:* 29661/pen
To test it is working I have enabled logging on the DNS servers and will use dig and specify the pen server as the name server.
root@penudp:/# dig @127.0.0.1 bbc.com root@penudp:/# dig @127.0.0.1 microsoft.com
Then looking at the bind logs we can see that the connections are being correctly made to each server.
ben@bindd1:~$ tail -n 1 /var/log/syslog Aug 22 12:42:57 bindd1 named: client 192.168.65.219#44048: query: bbc.com IN A +E (192.168.74.221) root@bind2:/home/ben# tail -n 1 /var/log/syslog Aug 22 12:43:07 bind2 named: client 192.168.65.219#57100: query: microsoft.com IN A +E (192.168.74.222)