BIND-OVER-LDAP HOWTO Pascal Jakobi (
[email protected]) Pieter Krul (
[email protected]) Red Hat Today's IT infrastructures generally have 2 different directory systems coexisting : DNS and LDAP. The Domain Name System is primarily used to provide an easy means to link a host name such as www.redhat.com to its corresponding IP address and vice versa. Additional usages include the possibility to provide transparently the address of the “nearest” mail server, etc. LDAP, on the other hand, is initially focused on userrelated data. A typical use of LDAP servers was to provide a means to retrieve some user's email address within a mail client program. However, LDAP tends to be more and more widely used as the repository where to store systems related information. Most notably, Microsoft's Active Directory is heavily used for such a purpose. Therefore, very naturally, solutions that provide convergence between these 2 technologies have emerged. This paper aims at describing what can be done to leverage the best of both technologies. As such, a basic understanding of both LDAP, LDIF (the LDAP Interchange format, file based), and DNS/bind is expected. The paper's technical environment is Red Hat's Entreprise Linux 5/Fedora 7, Directory Server 1.x, bind 9. However, the solutions described below should work in a different context. In particular, no difficulty is expected for users of OpenLDAP instead of RHDS.
BIND
OVERVIEW
In the Linux world, the DNS service is provided by Bind, the Berkeley Internet Name Domain. DNS is split into domains such as redhat.com, and zones, such as corp.redhat.com. Bind deals primarily with zones, which are contained in files (one file/zone). There are master and slave servers : only the first category “owns” domain data, which is then replicated towards slave servers. Below is a simplified architecture for a DNS infrastructure. Master server
Zone files
Slave server Data Replication
Illustration 1: DNS
Sophisticated customers have more than one master server per zone in order to provide service continuity. In order for this infrastructure to work, the zone files have to be constantly uptodate at the master server level. Generally, these zone files are copied from one server to another whenever an update occurs. Configuration of bind servers is controlled by a central file, typically /etc/named.conf. This file has 3
DNS-LDAP Howto v1.1
sections. ●
Its options section, comprises the various data declaration needed for bind to operate. For example, the directory where it is expected to find its configuration data.
●
Its logging statement is used for troubleshooting.
●
At last, the most varying part is the zone declaration.
Every zone is stored within a file in the bind directory (generally /var/named). There are standard zones, such as localdomain.zone, but also zones specific to the domains owned by the current server. zone "test.org" { type master; file "/var/named/test.org.hosts"; }; zone "1.168.192.in-addr.arpa." IN { type master; file "192.168.1.db"; };
The 1.168.192.inaddr.arpa zone is used for address resolution : it contains mostly PTR records that link an IP address to a host name. The linux command host is the typical utility used to retrieve the contents of such files. At last every zone file starts with an SOA (“Start of Authority”) record, followed by machines declarations (A, MX PTR, etc. records).
THE BIND SIMPLIFIED DATABASE BACKEND
PACKAGE
(BIND-SDB)
Obviously, there are better suited technologies for zone data storage than moving files from one server to another. Essentially, 2 types of databases may be used for such usages : SQL RDBs and LDAP Directory servers. The latter technology seems more promising as it leverages an infrastructure widely deployed within the industry. Also most if not all LDAP servers cope very well with replication, so adding DNS data if necessary is a matter of minutes. The bindsdb package (this is an rpm offered in Red Hat's standard repositories such as the Red Hat Network) addresses this need: it provides a means to store zonerelated data within a database or an LDAP enabled Directory. This rpm is the result of the work of S. Venaas, whose web's site (http://www.venaas.no) has proven to be most useful for that matter. Directory infrastructure
DNS server
DNS server DNS server
Illustration 2: DNS over LDAP
2(2)
DNS-LDAP Howto v1.1
There are additional benefits to such an approach. ●
Simplicity. Within such an architecture the configuration of all DNS servers is identical – the only possible difference being the LDAP server's address. This solution also tends to encourage to implement only master servers, as a result of the removal of any local configuration data.
●
Features. Data stored in the directory is instantly available, without having to set any complex mechanism (reloads, dynamic updates, etc.)
INSTALLING BIND-SDB Directory prerequisites ●
Before starting anything, having a Directory in order to work is essential. The reader should most notably check that the ldapadd and ldapsearch commands are operational. He should also have the Directory Manager's Distinguished name and password, etc...
●
Also, for comfort, using the gq (“The gentleman's LDAP client”) browser is strongly encouraged as this will make life much easier. On version 1.2.2. of gq, LDAP servers access is configured under “preferences” (“servers” tab). However, in the following examples, gq is only used to browse the server.
Schema updates Bind-sdb requires access to dNSZone objects. This schema/objectclass for Openldap is included in the bind sdb RPM package. Essentially dNSZone is an object that contains all records that were stored in zone files. ● ●
Its DN (Distinguished Name) corresponds to the machine's FQDN, It may contain attributes for all types of records stored in a zone file (A, MX, CNAME....).
OpenLDAP Openldap will have the needed support for dNSZone as the schema for Openldap is installed with the bindsdb package. Just check if a statement similar to the one below is present in your slapd.conf file after installing bind sdb: include /etc/openldap/schema/dnszone.schema
Red Hat/Fedora Directory Server For Red Hat's Directory Server (or Fedora's, or Sun's), the schema file has to be converted to LDIF. This may be done with the standard Perl script ol-schema-migrate.pl, again widely available (http://directory.fedoraproject.org/download/olschemamigrate.pl, if not available do a search over the internet). Typically, issue a command such as (provided the utility is in the $PATH and the text schema in the current directory) : ol-schema-migrate.pl -b dNSZone-schema.txt > dNSZone.ldif
In order to check everything went OK, check the resulting file. Its ending should look like below : 3(3)
DNS-LDAP Howto v1.1
objectClasses: ( 1.3.6.1.4.1.2428.20.3 NAME 'dNSZone' SUP top STRUCTURAL MUST ( zoneName $ relativeDomainName )
MAY ( DNSTTL $ DNSClass $ ARecord $ MDRecord $ MXRecord $ NSRecord $ SOARecord $ CNAMERecord $ PTRRecord $ HINFORecord $ MINFORecord $ TXTRecord $ AFSDBRecord $ SIGRecord $ KEYRecord $ AAAARecord $ LOCRecord $ NXTRecord $ SRVRecord $ NAPTRRecord $ KXRecord $ CERTRecord $ A6Record $ DNAMERecord $ DSRecord $ SSHFPRecord $ RRSIGRecord $ NSECRecord )) Then, it is necessary to insert the file into the Directory. In RHDS, schema files are stored within a Directory named “/opt//slapd-/config/schema” product stands here for “redhatds” or “fedorads” and the directory instance name is in general “slapd”. Finding it is easy : locate a file named 00core.ldif. Then, store the dNSZone LDIF file in this directory with a file name that starts with a number close to but less than 99 (85dnszone.ldif, for example – there should not be other files starting with the same number). One of the Netscape schemas (RFC2247) needs a small modification in “/opt//slapd/config/schema/05rfc2247.ldif”: Change the line that reads 0.9.2342.19200300.100.1.26 NAME 'dNSRecord' into 0.9.2342.19200300.100.1.26 NAME ( 'aRecord' 'dNSRecord' )
Once this is done, restart the Directory Server instance – you are set ! If you run into trouble with the schema, you can also download 85dnszone.ldif from http://ftp.auxio.org/pub/auxio/directory Checking Directory schema This step provides a means to check that the previous one has been carried out succesfully : we now have to check that dNSZone is correctly recognized by the Directory server. GUI based method Whichever Directory server is used, the most easy way to do so is to use the GQ browser (available at least with fedora 7). You may need information on how to bind to the server (user name, password...), however most servers accept anonymous binds. Once you able to connect, check the schema in order to be sure that dNSZone is recognized.
4(4)
DNS-LDAP Howto v1.1
Illustration 3: dNSZone
Command line method You may also use the ldapsearch command (part of the openldapclients rpm). A command like1 : ldapsearch -x -h host.test.org -b "cn=schema" | grep -i dNSZone
Should result into displaying the dnsZone Object ID : 1.3.6.1.4.1.2428.20.3. Directory Information Tree customizations Once the Directory supports dNSZone, it has to be structured in order to host the various zone files that will be migrated into it. Below is the target structure for a Directory Information Tree that seems to be adequate. We start with a DIT as provided : under the root DSE (dc=test, dc=org), the very standard org units preexist (People, Groups). At the same level we will add a “DNS” org. unit that will contain all zone files2, under appropriate subtrees. This subtree corresponds to the dark blue boxes (dc=inaddr, dc=arpa, ou=DNS) in the schema below :
1 2
The appropriate set of parameters needed for ldapsearch varies according to the Directory installation. This is well documented in its man page. Adding a DNS container is not mandatory, but is obviously a good practice. 5(5)
DNS-LDAP Howto v1.1
test.org
ou=Groups
ou=People
ou=DNS
dc=org dc=test dc=arpa dc=in-addr dc=1.168.192
Illustration 4: Target DIT
The following LDIF file should do the job : changetype: add dn: ou=DNS, dc=test, dc=org ou: DNS objectClass: top objectClass: organizationalUnit changetype: add dn: dc=arpa, ou=DNS, dc=test, dc=org dc: arpa objectClass: top objectClass: domain changetype: add dn: dc=in-addr, dc=arpa, ou=DNS, dc=test, dc=org dc: in-addr objectClass: top objectClass: domain
Updating the Directory is to be done with the ldapadd command see the command's man page to get the list of applicable parameters. In most cases, on RHDS/FDS, a command like the one below would do the job, provided the server runs on the same system and the file above is named test.ldif : ldapadd -W -D "cn=Directory Manager" -x -f test.ldif
Bind-sdb Installation Fundamentally, in order to have bindsdb running, the only thing to do is to install the rpm with the tool of your choice : up2date, yum, rpm.... What the bindsdb rpm does mostly is to replace the standard named program with named-sdb, which was generated with the appropriate set of features. On Fedora/RHEL, the next step is to configure the service. In the /etc/sysconfig/named file, check that ENABLE_SDB is correctly set : ENABLE_SDB=yes
6(6)
DNS-LDAP Howto v1.1
Once this is done, the infrastructure is fully operational.
BIND-SDB
CONFIGURATION
Now that we have the container for DNS zones, we just have to create every zone. There are 3 aspects to take into consideration. First we need to create the subtree, then to store the global zone parameters (what is in the header of a bind zone file). This has to be done for both direct & reverse mappings. Creating the DNS subtree We have created the name server's base infrastructure before. Now everything is in place to add a zone within the Directory tree. As already stated, the is a fixed part for every zone. This is the DIT structure (the “cn=org” and “cn=”test” boxes in the “target DIT” picture above), then the SOA record expected by DNS for every zone, and the reverse zones. Adding the DIT structure can be done with the following LDIF : changetype: add dn: dc=org, ou=DNS, dc=test, dc= org dc: org objectClass: top objectClass: domain changetype: add dn: dc=test, dc=org, ou=DNS, dc=test, dc=org dc: test objectClass: top objectClass: domain dn:dc=1.168.192,dc=in-addr,dc=arpa,ou=DNS,dc=test,dc=org dc:1.168.192 objectClass:top objectClass:domain dn:relativeDomainName=1.168.192.in-addr.arpa, dc=1.168.192,dc=in-addr,dc=arpa,ou=DNS,dc=test,dc=org objectClass: top objectClass: dNSZone nSRecord: gaston.test.org. zoneName: 1.168.192.in-addr.arpa relativeDomainName: @ relativeDomainName: 1.168.192.in-addr.arpa
This LDIF fragment may be used by “ldapadd”. However, use the “c” (“continue on error”) switch as many zones can be added within the “org” domain. Zone subtree – direct mapping Once the structure exists, we have to create first a set of LDAP entries (within the dc=test, dc=org, ou=DNS, dc=test, dc= org subtree) that provide a way to retrieve an IP address from a host name. These entries globally map standard bind zone files. First, for every zone, a declaration record has to be created. Declaration records always have “@” as their relative domain name. Below is the ldif fragment for a zone named “test.org”, located within the ou=DNS,dc=test,dc=org subtree :
7(7)
DNS-LDAP Howto v1.1
dn: relativeDomainName=@+zoneName=test.org,dc=test,dc=org, ou=DNS, dc=test,dc=org nSRecord: gaston.test.org. DNSTTL: 86400 zoneName: test.org objectClass: top objectClass: dNSZone relativeDomainName: @ sOARecord: gaston.test.org. pjakobi.redhat.com. 1182363807 28800 7200 604800 86400
Then every record (one per system) looks like : dn: relativeDomainName=batman+zoneName=test.org,dc=test,dc=org, ou=DNS, dc=test,dc=org aRecord: 192.168.1.5 dNSTTL: 86400 zoneName: test.org objectClass: top objectClass: dNSZone relativeDomainName: batman
Zone subtree – reverse mapping Reverse mapping table are used when there is the need to retrieve a name based on IP address. DNS tables for this usage are very similar to those above. First a header record stored in an LDAP entry. dn: relativeDomainName=@+zoneName=1.168.192.inaddr.arpa,dc=1.168.192,dc=in-addr,dc=arpa, ou=DNS, dc=test,dc=org nSRecord: gaston.test.org. dNSTTL: 86400 zoneName: 2.168.192.in-addr.arpa objectClass: top objectClass: dNSZone relativeDomainName: @
Then, typical records look like : dn: relativeDomainName=5+zoneName=1.168.192.inaddr.arpa,dc=1.168.192,dc=in-addr,dc=arpa, ou=DNS, dc=test,dc=org dNSTTL: 86400 zoneName: 1.168.192.in-addr.arpa objectClass: top objectClass: dNSZone relativeDomainName: 5 pTRRecord: batman.test.org
Bind configuration At last, we have to configure the bind server itself, typically in /etc/named.conf. Fundamentally, we have to let bind know that some zone data has to be searched through LDAP. This is done with clauses such as : zone "test.org" { type master; 8(8)
DNS-LDAP Howto v1.1
database "ldap ldap://192.168.1.2/ou=DNS,dc=test,dc=org 172800"; };
Then for reverse mapping : zone "1.168.192.in-addr.arpa." IN { type master; database "ldap ldap://192.168.1.2/ou=DNS,dc=test,dc=org 172800"; };
Once this is done, the DNS server is ready to restart ('service named restart”).
POST-INSTALLATION
CHECKS
The best way to check a DNS server is working is to use the wellknown host and dig commands to check that the server is operational. In the example above “dig batman.test.org” and “host 192.168.1.5” should be the first commands used to check everything works fine. If something goes wrong, the first thing to check is if the namedsdb server can access correctly the Directory. If you receive an error that databases cannot be found, then please reread “Bindsdb Installation” above again. Then, as usual, the /var/log/messages file should provide useful debugging information.
9(9)