First, a few assumptions:
- You have an AD DNS server already operational. It has a zone configured which allows updates as long as the updates are secure.
- You have some AD credentials with permissions to update the zone. I think perhaps the
DNSAdmin
group might be granted permission by default (not sure), so make your user is a member of that. It's best to use a service account with lowest possible privileges.
- You have a Linux box from which to send updates. Your version of
nsupdate
supports the -g
flag which enables GSS-TSIG.
Let's get started. We need to do some setup.
First, we need to get and configure the Kerberos 5 authentication backend.
- If you're on Ubuntu, the tools you need can be installed using
apt install sssd-krb5 krb5-user
. If you're on another distribution, check the comments to see if someone has indicated what packages you need.
- Next, we need to add the info for our AD. This is not DNS info, it's Kerberos info about how to get tickets. Use your favorite text editor to open the
krb5.conf
file; for Ubuntu that is /etc/krb5.conf
.
- Under the
[libdefaults]
section, it would be wise to add an entry like this: default_realm = CORP.EXAMPLE.LOCAL
. Not sure why, but the Realm seems to need to be uppercase.
- Under the
[realms]
section, we need to add the AD domain and the server (domain controllers) info. Follow this template. Again, make the realm name UPPERCASE.
[realms]
CORP.EXAMPLE.LOCAL = {
kdc = ms-dc-01.corp.example.local:88
kdc = ms-dc-02.corp.example.local:88
admin_server = ms-dc-01.corp.example.local
default_domain = corp.example.local
}
Ok, let's see if it works.
Next, we'll try to get a Kerberos ticket from AD by authenticating.
- Run the command
kinit [email protected]
. Hopefully it prompts you for a password. And hopefully nothing more.
- Having a problem getting
kinit
to accept your password? Try enabling trace output like this: KRB5_TRACE=/dev/stdout kinit ...
. Note that sometimes the username can cause CaSeSeNsItIvItY problems.
- See if you have a ticket. Run the command
klist
. Hopefully you see something similar to this. If you don't, go back one step and try reading the trace output.
Valid starting Expires Service principal
05/19/2023 17:22:42 05/20/2023 03:22:42 krbtgt/[email protected]
- Pause here for just a moment. What we did was ask AD for a Kerberos ticket by using our credentials. If the ticket was granted, it was placed into the client's cache. You are viewing the cache when you use
klist
. You probably ought not leave that in the cache for longer than you need to, since the cache can be read and used by root Linux users. You can terminate a ticket by using the kdestroy
command.
- With that ticket, let's see if we can send a DNS update to the DNS server. Run the
nsupdate
command. This will give you a new command prompt waiting for instructions about what you'd like to do. Enter these commands:
gsstsig
server chicago-dns-14.corp.example.local
zone corp.example.local.
update add my-new-test-record.corp.example.local. 3600 A 1.1.1.1
show
send
quit
Note, some servers don't require the TTL parameter, some do. Shrug.
- Use your favorite DNS utility to ask the DNS server if it has the record:
host -ta my-new-test-record.corp.example.local chicago-dns-14.corp.example.local
- You can now delete the record in a nearly-identical way. Run
nsupdate
again. Enter these commands:
gsstsig
server chicago-dns-14.corp.example.local
zone corp.example.local.
update delete new-server-test-record.corp.example.local. A 1.1.1.1
send
Note you do not need to include the TTL when deleting.
- Run
kdestroy
to delete your Kerberos ticket from the cache.
Cool, what's next?
Ok, so that was how to do it manually. Now, let's put the password into a keytab file so we don't have to type it each time, yet the password is also not saved in a clear text file for other users to read.
- Run the
ktutil
command. Type this:
addent -password -p [email protected] -k 0 -f
- Hopefully, you get prompted for your password. Then continue:
wkt username.keytab
quit
- Okay, so you hopefully have a keytab file now. This file contains a mostly-secure version of your password. I don't exactly know how, but it's kinda-sorta-encrypted in some way or other.
- Now that we have the keytab file, we can run
kinit
with some new parameters that let us avoid typing the password: kinit -kt username.keytab [email protected]
- Run a
klist
to see if you got a ticket.
- Run a
kdestroy
to tear down your ticket.
Ok, now let's see if we can make this a really complicated one-liner.
- Run the command:
kinit -kt username.keytab [email protected] && echo "gsstsig
server chicago-dns-14.corp.example.local
zone corp.example.local.
update delete new-server-test-record.corp.example.local. 3600 A 1.1.1.1
send" |nsupdate && kdestroy
I know this looks like more than one line, but the quotation on the first line makes Bash wait until you close the quote.
Can you script this?
Sure
#!/bin/bash
if [ $# == 3 ]; then
if [ $1 == "add" ] ; then
kinit -kt DnsAdministrator.keytab [email protected]
echo "gsstsig
server chicago-dns-14.corp.example.local
zone corp.example.local.
update $1 $2.corp.example.local. 7200 A $3
send" |nsupdate
kdestroy
elif [ $1 == "delete" ] || [ $1 == "del" ] ; then
kinit -kt DnsAdministrator.keytab [email protected]
echo "gsstsig
server chicago-dns-14.corp.example.local
zone corp.example.local.
update $1 $2.corp.example.local. A $3
send" |nsupdate
kdestroy
else
echo "<action> must be either add or delete."
fi
else
echo "There must be precisely 3 parameters: <action>, <record-name> and <ip-address>"
fi
And then use it like this:
./my-dns-script.sh add my-new-test-record 1.1.1.1
or
./my-dns-script.sh delete my-new-test-record 1.1.1.1