DNS setup for use with Windows

Setting up DNS using bind

© 2009, 2010 Dennis Leeuw dleeuw at made-it dot com
License: GPLv2 or later

SRV records

Kerberos makes use of the SRV records in DNS to look up its services. To make switching machines easier (when e.g. replacing the KDC) we use CNAMEs to point to the servers in a functional name, however you can not use CNAMEs in SRV records, so we have to use canonical names there. For quick reference we give an overview of what an SRV record looks like, see RFC 2782 for more information:

_service._proto.name ttl IN SRV priority weight port target

The different SRV records defined for kerberos use are:

_kerberos._udp
The default port is 88 and is used to contact the KDC for almost everything.
_kerberos._tcp
Default port is 88, but the MIT KDC is per default not listening on the TCP port, so it is of no use to us (see kdc_tcp_ports in the kdc.conf file).
_kerberos-master._udp
Default port is 88 and should point to the KDC that sees password changes the first. If a user gets a 'wrong password' from e.g. a slave KDC, then this server will be contacted to verify it the password was really incorrect or that the slave was just not updated in time.
_kerberos-adm._tcp
The default port is 749 and should be used by the kadmin utilities, but our MIT version didn't support it, thus you need the admin_server setting in the krb5.conf file (see later).
_kpasswd._udp
The default is port 464 on the master KDC and is used when a user changes his or her password.
_kerberos-iv._udp
Only used for kerberos V.4, which we do not use.

An example zone file

$ORIGIN . 
$TTL 86400      ; 1 day 
@  IN SOA  ns1.example.com. hostmaster.example.com. ( 
                                2009022507 ; serial 
                                10800      ; refresh (3 hours) 
                                900        ; retry (15 minutes) 
                                604800     ; expire (1 week) 
                                86400      ; minimum (1 day) 
                                )

                       	NS      ns1.example.com. 
                       	A       192.168.1.1 
$ORIGIN example.com. 
_kerberos              	TXT     "EXAMPLE.COM"
krb5                 	A       192.168.1.1
ns1				CNAME	   krb5
kerberos			CNAME	   krb5

$ORIGIN _tcp.krb5.example.com.
_kerberos-adm      	SRV     0 0 749 krb5.example.com.

$ORIGIN _udp.krb5.example.com. 
_kerberos               SRV     0 0 88 krb5.example.com. 
_kerberos-master        SRV     0 0 88 krb5.example.com. 
_kpasswd                SRV     0 0 464 krb5.example.com. 

Make sure the reverse zone for this domain is setup correctly, meaning you need reverse resolving for the Kerberos host (!) and later on AD, otherwise Kerberos will not work with DNS, and Kerberos assumes a functioning DNS.

Active Directory integration

To support Active Directory in your bind DNS server you need a couple of extra entries. Below there is a little overview of what Active Directory expects, this overview only deals with the _ldap services but the same holds true for the other services.

.<DNSDomainName>
Resolves the DNS domain
_ldap._tcp
Locates the W2K domain controller.
.<SiteName>._sites.<DNSDomainName>
Resolves the site specific domain records (e.g. newyork._sites.forest.example.com).
_ldap._tcp
Locates the W2K domain controller for a site
_ldap._tcp.pdc._msdcs.<DNSDomainName>
Resolves to the PDC flexible single master object (FSMO) role holder of a mixed-mode domain.
_ldap._tcp.gc._msdcs.<DNSDomainName>
Resolves the Global Catalog (GC) server.
_ldap._tcp._sites.gc._msdcs.<DNSDomainName>
Resolves the site specific Global Catalog server.
_ldap._tcp.<DomainGUID>.domains._msdcs.<DNSDomainName>
Resolves to the domain controller in a domain, based on the domain controller's globally unique ID.

An example list of entries generated by Microsoft Windows 2003 when doing an Active Directory installation looks like this:

_ldap._tcp.forest.example.com.                                    600 IN SRV 0 100 389  adf.forest.example.com.
_gc._tcp.forest.example.com.                                      600 IN SRV 0 100 3268 adf.forest.example.com.
_kerberos._udp.forest.example.com.                                600 IN SRV 0 100 88   adf.forest.example.com.
_kerberos._tcp.forest.example.com.                                600 IN SRV 0 100 88   adf.forest.example.com.
_kpasswd._tcp.forest.example.com.                                 600 IN SRV 0 100 464  adf.forest.example.com.
_kpasswd._udp.forest.example.com.                                 600 IN SRV 0 100 464  adf.forest.example.com.

_ldap._tcp.pdc._msdcs.forest.example.com.                         600 IN SRV 0 100 389  adf.forest.example.com.
34356b88-8d9f-457b-87ae-dd660c028489._msdcs.forest.example.com.   600 IN CNAME          adf.forest.example.com.
_ldap._tcp.f3d8bf35-d00a-48fd-aaf9-c7d1999227f3.domains._msdcs.forest.example.com. 600 IN SRV 0 100 389 adf.forest.example.com.

_ldap._tcp.gc._msdcs.forest.example.com.                          600 IN SRV 0 100 3268 adf.forest.example.com.
_ldap._tcp.Default-First-Site-Name._sites.gc._msdcs.forest.example.com. 600 IN SRV 0 100 3268 adf.forest.example.com.

_ldap._tcp.dc._msdcs.forest.example.com.                          600 IN SRV 0 100 389  adf.forest.example.com.
_kerberos._tcp.dc._msdcs.forest.example.com.                      600 IN SRV 0 100 88   adf.forest.example.com.
_ldap._tcp.Default-First-Site-Name._sites.dc._msdcs.forest.example.com. 600 IN SRV 0 100 389 adf.forest.example.com.
_kerberos._tcp.Default-First-Site-Name._sites.dc._msdcs.forest.example.com. 600 IN SRV 0 100 88 adf.forest.example.com.

_ldap._tcp.Default-First-Site-Name._sites.forest.example.com.     600 IN SRV 0 100 389  adf.forest.example.com.
_gc._tcp.Default-First-Site-Name._sites.forest.example.com.       600 IN SRV 0 100 3268 adf.forest.example.com.
_kerberos._tcp.Default-First-Site-Name._sites.forest.example.com. 600 IN SRV 0 100 88   adf.forest.example.com.

To make sure that our AD server also has this zone file we allow AD to transfer this file so our named.conf has the following setup:

zone krb5.example.com {
        type master;
        file internal/com.example.krb5.zone;
        check-names ignore;
        allow-transfer {
            // ad server
            192.168.1.2;
        };

        allow-update {
            // test client
            192.168.1.3;
        };

        notify no;
};

You will note that we have an entry for a client to do updates, this is so that the client can put its IP address in the zone file, AD relies on the ability to resolve client host names to IP addresses, and since we use DHCP to supply IP addresses to our clients, we need a way to do automatic DNS updates (RFC2136). The reverse is not needed, at least not that we have found.

The integration

It would be a lot of work to make sure your DNS is setup correctly with the above information. Lukily for us there are two ways to make life easier. The first one is to copy the \Windows\System32\Config\netlogon.dns file to your bind server and add the settings to DNS.

An even easier way is to make Active Directory do it automatically. Since we need dynamic DNS updates for the Windows clients anyway, this is the easiest route. Add to your named.conf the following section to your zone entry:

allow-update {
	// Allow DNS updates from our network
	192.168.1.0/24;
	};

For security reasons this might not be the right solution, or you must trust all your employees and anybody that can connect a computer to your network. But it is beyond the scope of this document to handle all the security implications. Maybe I will add more documentation on this later on.

To test the setup use nsupdate:

nsupdate 
> server ns1.example.com
> zone example.com
> update delete bofh011.example.com. A
> update add bofh011.example.com. 86400 A 192.168.1.15
> send
If this works and your AD server is in the same network, it will happily add its own DNS entries.