Wednesday, June 17, 2015

How would you use Lua scripting in a DNS server?

I'm currently putting Lua into a DNS server, and I'm trying to figure out how people would use it.

A typical application would be load-balancing. How I would do this is to create a background Lua thread that frequently (many times a second) queried an external resource to discover current server utilitzation, then rewrote the RRset for that server to put the least utilized server first. This would technically change the zone, but wouldn't be handled as such (i.e. wouldn't trigger serial number changes, wouldn't trigger notification of slave zones).

Such a thread could be used for zone backends. Right now, DNS servers support complex backends like SQL servers and LDAP servers. Instead of making the server code complex, this could easily be done with a Lua thread, that regularly scans an SQL/LDAP server for changes and updates the zone in memory with the changes.

Both these examples are updating static information. One possible alternative is to execute a Lua script on each and every DNS query, such as adding a resource record to a zone that would look like this:

* TXT $LUA:my_script

Every query would cause the script to be executed. There are some issues with this, of course, but for a lot of typical uses, such limitations wouldn't matter. For example, there's complex thread synchronization issues, but I could simply force any use of this feature to go into single threaded mode -- whatever narrow use you'd have for this feature could probably accept the performance hit.

The specific use for this would be, of course, to setup a DNS communication channel. Captive portals forward DNS, but redirect other TCP/UDP packet. Sending messages back and forth through DNS would allow you to do things like tunnel Twitter messages through even without "real" Internet access. As well know, people in the past have written entire VPNs through DNS this way, with custom DNS stacks.

These are my ideas. Maybe you could post some other ideas. I'm looking for either a problem you want solved (without necessarily dictating the precise solution), or a nifty way of integrating Lua (without necessarily any specific problem in mind).


ThingFish said...

Suppose you have two networks connected at once: a connection to work (which naturally has 10.x.y.z IP addresses) and a connection to the Internet. You want some names ("home.intranet" or "dbserver.corp.intranet") to be resolved by the work DNS server, and everything else by . Your Lua scripting should allow that. Of course, a corporate intranet accessible by SSH would also solve this, but we're talking reality here.

Unknown said...

One use would be to return "" (or "::1" for IPv6) for known ad network servers.

Hristos said...

It really sounds like a push/pull choice problem to me.

Personally i would incorporate this script on some nrpe checks on the servers, they would ( on Critical load status for example ) inform the Lua thread to change the DNS settings ( any of them ).

In short, let nrpe checks on SQL/LDAP server inform the DNS server for you with a custom check script, not the other way around, it feels too much of an overhead to do it the way you described on the post ( many times per second etc ).

Terry said...

It just so happens that Verisign offers Global Server Load Balancing based on LUA scripts that is very similar to the model described here. You can see an overview of the service at The Lua scripts run against every query to a DTM-enabled record at any of our global resolution sites.

scalefree said...

You could use it to trigger on patterns indicative of malicious behavior. DNS is often a component of advanced attack patterns.