Thursday, June 01, 2006

BIND and ADS

In the real world, corporate networks are usually a heterogeneous mix of different makes and models of computers and services. In my probably typical work environment, we mix a few MS Windows Servers in with many Linux and IBM A/S400 servers. While it would be nice to be a homogeneous network, often times, the software required for business just isn't made for your preferred operating system. Hopefully this brief paper will help integrate your rock-solid "legacy" DNS servers running on *NIX with your Active Directory Domain Controllers.

The key to this is a little used (at least in the BIND DNS world) item called a Service Record, or SRV record. SRV records are intended to relay information via DNS regarding which server is providing which service. The server may be on your local LAN, but it's not required. If a Domain Controller (referred to here after as DCs) is on the same LAN as your workstation, the workstation will use it's own mechanism, a network broadcast, to find the DC so a SRV record may not be absolutely required. If however they are on different networks or LANs, SRV records will be required so the workstations knows where the DC is located. If you've read anything about routing, you probably know this is because the router between the 2 LANs will not forward the workstations broadcast traffic to the DCs LAN. Thus the DC cannot answer the broadcast leaving the workstation isolated on the other side of the router.

Don't be alarmed by the funky syntax, but here is a sample SRV record:

_http._tcp.example.com. SRV 10 5 80 www.example.com.

As you can see an SRV record has several fields and a unique system for naming. The naming system is an underscore followed by the name of the service, followed by a period, an underscore, and then the protocol, another dot, and then the name of the domain. The period at the end of the domain is required in this case. This tells BIND not to append another "example.com" to the name making it "_http._tcp.example.com.example.com". Same goes for the period at the end of the target computer as well.

If the fields were labeled by number left to right in the above example. The fields are:
1. The _service._protocol.domainname
2. The Resource Record. As you can guess, it will always be SRV for Service Records. For other types of records it can be different, eg, for Address Records it will be A instead of SRV.
3. The Priority of 10. This sets the preference for a host specified in the target field. DNS clients that query for SRV resource records attempt to contact the first reachable host of the lowest numbered preference listed here. Although target hosts have the same stated preference value, they can be tried in random order. The range of preference values is 0 to 65535. I keep these at 0 (zero) most of the time to make it simpler.
4. The Weight of 5. Can be used in addition to preference to provide a load-balancing mechanism, where multiple servers are specified in the target field and are all set to the same level of preference. When selecting a target server host among those of equal preference, this value can be used to set an added level of preference that can be used to determine the exact order or balancing of selection for the target hosts used in an answered SRV query. When a non-zero value is used, servers of equal preference are tried in proportion to the weight of this value. The range of values is 1 to 65535. If load balancing is not needed, use a value of 0 in this field to make the record easier to read.
5. The Port Number for the service(80). In the example it is the common port for the http service of 80, but it can be anything. For example, if you run http on port 8888, then you would put 8888 in this field. This particular field was the entire reason SRV records surfaced. They were made to allow clients to know which port a service was running on in case it was running on an unusual port number. The *NIX world thought running common services on unusual ports was a bad idea. As a side effect so SRV records were never embraced and are not commonly used by *NIX admins.
6. The target server. This should match the name given by the Address Record of the target server of course.

The SRV record will go in the forward look-up file. This will be the same file containing the A records. If you see files with Pointer Records (PTR) files, you are in the wrong file.

Ok, now the actual part that makes things work. In order for a workstation to find out which server is the DC, four SRV records are required to complete the deal for each DC. This example is for one domain controller, so the weight and priority fields are set to zero (0). Also, you should be able to see that the LDAP service uses port 389, and the Kerberos service uses port 88.

If you have an Address Record (A) that identifies your server name like this:

dc1.example.com. A 111.222.333.444

Then your SRV records for this DC would be as follows

_ldap._tcp.example.com. SRV 0 0 389 dc1.example.com.
_kerberos._tcp.example.com. SRV 0 0 88 dc1.example.com.
_ldap._tcp.dc._msdcs.example.com. SRV 0 0 389 dc1.example.com.
_kerberos._tcp.dc._msdcs.example.com. SRV 0 0 88 dc1.example.com.

You may notice that there are two LDAP and two Kerberos entries that look similar. One simply tell where the LDAP and Kerberos services are running and the other on tell the client that it is the DC for the listed target domain.

If you have 2 or more DCs you can experiment with the priority and the weight fields, but I'll leave that as an exercise for you.

Hopefully with this little bit of info, you can forgo the hardships of trying to make your legacy system work with MSDNS. Why learn more than you have to when, in this instance, the old way is clearly the best way!

No comments: