I’m not entirely certain that this is useful, but I’ve implemented a Lua back-end for BIND atop the DLZ dlopen() driver. Thinking about the possibilities of DLZ yesterday afternoon got me hacking, and I realized embedding Lua would ease the process, so I tried. The good news is, my copy of BIND 9.9.0b2 doesn’t crash with it, even though there’s still some work to be done, particularly with respect to error-handling. (I also have a cry for help which you’ll see in a moment. :)

When BIND gets a query for a DLZ-configured zone, it dispatches it into the dlz_lua driver. This driver calls a function lookup() which I define in my Lua script. The function returns a table with all the records that satisfy the query, DLZ pushes them into named which answers the query. This is of course a very simple way of describing what happens; consult my chapter on DLZ for an in-depth explanation.

lookup is called with a name (e.g. www or @ for the zone apex), the zone name proper (e.g. example.nil) and the client’s address (or “unknown”).

function lookup(name, zone, client)
   ret = {}

   -- bindlog() is a C function defined in dlz_lua.c
   bindlog("Lua lookup(" .. name .. ", " .. zone .. ", " .. client .. ")")
   
   if name == 'www' then
      ret[1] = { type = "txt",  ttl = 3600, rdata = "Hi JP!" }
      ret[2] = { type = "MX",   ttl = 3600, rdata = "10 mail.gmail.com." }
      ret[3] = { type = "AAAA", ttl = 3600, rdata = "fe80::223:32ff:fed5:3f" }
   end

   return 0, ret
end

The function returns a success code and a table containing the records. (BTW, I was greatly inspired by Bert Hubert’s work on the PowerDNS Recursor and the authoritative server.)

The example.lua script I provide shows such a function. Let me show you some queries:

$ dig +noall +answer time.example.nil any
time.example.nil.  0  IN  TXT  "2011-12-01T11:20:10+0100"

$ dig +noall +answer password.example.nil txt
password.example.nil.  0  IN  TXT  "4@IfKf3%WEE%3Zi"

$ dig +short password.example.nil txt
"As6Fajx2k6#@aIL"

$ dig +short 6.password.example.nil txt      # note pw length as subdomain
"gE4L6k"

A query for the domain name time returns a time stamp, and a query for password gives a random password, which ultimately was the reason for building this whole thing. :-)

The DLZ dlopen driver also supports DNS updates, but I’ve ignored that for the time being, if only because I haven’t thought up any crazy thing to do with updates in Lua. ;-)

You’ll find the code I’ve written, example scripts, etc. at the dlz_lua repository.

And thanks to Peter van Dijk for the prompt patch which fixed my Lua woes.

DNS, BIND, and Lua :: 01 Dec 2011 :: e-mail