We’ve discussed dynamic DNS updates a few times here, and I’ve given examples of securing updates with TSIG and with SIG(0). Both methods require the updating client has access to a file containing the key; only with that key can a client submit updates to a DNS server. (Unless the server authorizes updates by IP address, which I don’t recommend doing.)
In environments which use Kerberos, administrators already possess a key as part of their Kerberos principal. Can they use that to perform DNS updates against a BIND name server? They can, using GSS-TSIG.
GSS-TSIG (Generic Security Service Algorithm for Secret Key Transaction Authentication for DNS) is defined in RFC 3645. It’s an extension to TSIG, which provides a lightweight protocol for authenticating and protecting the integrity of messages between, say, DNS client and server. GSS-TSIG specifies an alogorithm based on GSS-API which provides authentication based on Kerberos. We’ll use GSS-TSIG to authenticate dynamic DNS updates.
The client
What I want to be able to do is to perform a dynamic DNS update
authenticated by my Kerberos principal. I’m assuming you have
Kerberos client libraries and tools, as well as the the BIND tools (nsupdate
)
installed on your client machine, and that you’re running BIND server (compiled
with --enable-gssapi
) with the required Kerberos libraries installed on the
server.
So, what should be possible is a sequence of the following commands:
Option -g
to nsupdate
specifies that GSS-TSIG is to be used. (Alternatively, I
can use the gsstsig
subcommand to nsupdate
, but I find the option easier.)
Did it work? Yup: My nsupdate
spoke to named and I see a Kerberos ticket
from that server in my credentials cache:
Let’s have a look at how to enable named to allow GSS-TSIG-signed updates.
Configure BIND
BIND requires access to a Kerberos keytab, so I create a Kerberos
service principal called DNS/jmbp.ww.mens.de@MENS.DE
, and extract the principal’s
key into a keytab called DNS.keytab
. I then configure the keytab name in
named.conf
:
I also specify which principals may update what in a zone’s update-policy
stanza:
I’ve used three distinct forms of grant
statement, which we’ll look at in turn.
Individual principals
The first grant
statement (grant f2@MENS.DE zonesub ANY
) permits the specified principal to update any domain
within the zone. I can specify as many individual principals as I wish, of course,
and each can be authorized to perform different types of updates. (Consult the
BIND ARM for more information.)
Map host principals to domain
The second grant statement (grant MENS.DE krb5-self * A;
) allows any
principle in the MENS.DE realm to update its own A record. This rule takes a
Kerberos machine principal (host/machine@REALM) and
converts it to machine.realm. The realm to be matched is in the identity field
(MENS.DE). In other words, any host in my Kerberized environment can, using its
own keytab, update its record in the DNS. An example:
and BIND’s log shows
I’ve used the system’s keytab here, but I can of course use any other keytab.
External authentication
If you wish to defer the decision on whether or not named should grant the
update request, you can do so using the external
method, shown in the third
grant
statement (grant "local:/tmp/auth.sock" external * ANY;
). This
uses a UNIX
socket to communicate with an external process which decides whether the update
is allowed or not, and returns this information to named. I can use this to enable
updates by particular user or service principals without having to reconfigure
named, say, at particular times of the day, or requests with a particular
source IP address.
The following program is basically a copy of bin/tests/system/tsiggss/authsock.pl
from
the BIND source tree: it creates the UNIX domain socket, starts listening for
requests from named and checks the principal name of the requestor (signer)
to decide whether or not to grant update-permission.
Requests from named are sent as datagrams over the UNIX domain socket; our authorization program replies with a four-byte value in network-byte order, specifying whether the update is permitted (1) or not (0).
Here are a few examples printed by my authenticator:
Fin
The flexibility provided by BIND permits just about any combination of authorization of principals updating DNS records that I can think of, and all others should be covered by the external grant-method.
Enjoy!