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.