mirror of
				https://github.com/bklang/ldap2dns.git
				synced 2025-11-03 16:33:13 -05:00 
			
		
		
		
	them via configuration, environment, or cmdline args. * Allow all cmdline args to be set optionally using environment variables * Updated documentation and added plaintext version git-svn-id: https://svn.alkaloid.net/gpl/ldap2dns/trunk@386 06cd67b6-e706-0410-b29e-9de616bca6e9
		
			
				
	
	
		
			428 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			428 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
                              LDAP to DNS gateway
 | 
						|
 | 
						|
ldap2dns is a program to read DNS (Domain Name Service) records from an LDAP
 | 
						|
directory and format them into flat files suitable for TinyDNS (or Bind).
 | 
						|
 | 
						|
ldap2dns reduces all kind of administration overhead: No more flat file
 | 
						|
editing, no more zone file editing. After having installed ldap2dns, the
 | 
						|
administrator only has to modify the data stored in the LDAP directory.
 | 
						|
 | 
						|
Optionally access control can be configured for each zone, GUIs can be more
 | 
						|
easily implemented, and add all other kind of zone and resource record
 | 
						|
information can be managed without interfering with the DNS server.
 | 
						|
 | 
						|
ldap2dns is designed to write ASCII data files used by tinydns from the djbdns
 | 
						|
package, but also may be used to write zone db files used by named as found in
 | 
						|
the BIND package.
 | 
						|
 | 
						|
ldap2dns is known to compile and run under Linux and Solaris using GCC or Sun
 | 
						|
Studio C Compiler.
 | 
						|
 | 
						|
Introduction
 | 
						|
 | 
						|
Often it is desirable to store DNS information in a database rather than in
 | 
						|
flat text files. This can greatly help to reduce administration overhead since
 | 
						|
associate information such as billing contact, account management, etc. can be
 | 
						|
stored and processed inside the same database. Also due to the nature of DNS,
 | 
						|
information must be stored redundantly on two or more hosts. The classical data
 | 
						|
replication through zone transfer is unreliable, insecure and difficult to
 | 
						|
administer.
 | 
						|
 | 
						|
To solve this problem some proprietary attempts have been proposed to store DNS
 | 
						|
information in relational databases. The nature of DNS, however, is
 | 
						|
hierarchical and such should the database be. Using a relational database to
 | 
						|
store DNS information is undesirable, because it becomes difficult to store
 | 
						|
free form information. Within a hierachical data scheme, the administrator
 | 
						|
might define more than one IP-address for each canonical name. To implement
 | 
						|
such a feature in a relational database without breaking the normalization
 | 
						|
rules, one would have to add another table.
 | 
						|
 | 
						|
One of the most widely spread hierarchical database protocols is LDAP. ldap2dns
 | 
						|
retrieves DNS information stored in an LDAP directory service and generates a
 | 
						|
file suitable for name-servers.
 | 
						|
 | 
						|
The two most-widely-used domain name service daemons, named and tinydns are
 | 
						|
supported.
 | 
						|
 | 
						|
ldap2dns specifically has been designed to work with tinydns and is the favored
 | 
						|
name server daemon for the author of this program. ldap2dns can also generate
 | 
						|
files suitable for named version 8 (and possibly version 9), but this feature
 | 
						|
is not well supported.
 | 
						|
 | 
						|
There is a RFC for a format description how to store DNS information in LDAP.
 | 
						|
This paper a draft RFC which expired in February 1999, looks as if it has been
 | 
						|
specially designed to be used by named. This scheme does not have strict
 | 
						|
attribute-value-pair mapping, making it difficult to be used by user
 | 
						|
interfaces. It also lacks of an implementation (or I have never heard of any).
 | 
						|
Since tinydns is going another descriptive way the original author implemented
 | 
						|
a similar object-scheme more suitable for tinydns.
 | 
						|
 | 
						|
Installation
 | 
						|
 | 
						|
  * Install an LDAP server such as openldap. Other LDAP implementations may
 | 
						|
    work but have not been tested. If you are building from source you will
 | 
						|
    need to also install the development libraries and include files. On most
 | 
						|
    package based systems these would be the -devel packages (example:
 | 
						|
    openldap-devel).
 | 
						|
  * Install djbdns or BIND. Configuring the nameserver to automatically start
 | 
						|
    and work in your environment is beyond the scope of this document.
 | 
						|
  * Install ldap2dns
 | 
						|
    From RPM:
 | 
						|
 | 
						|
    $ sudo rpm -Uhv ldap2dns.rpm
 | 
						|
 | 
						|
    Replace "ldap2dns.rpm" with the file you have downloaded.
 | 
						|
    Now that you have it installed, skip to Usage to continue.
 | 
						|
 | 
						|
    To build ldap2dns from source:
 | 
						|
    Unpack the package and build it:
 | 
						|
 | 
						|
    $ gzcat ldap2dns.tar.gz | tar x
 | 
						|
    $ cd ldap2dns-version
 | 
						|
    $ make
 | 
						|
    $ sudo make install
 | 
						|
 | 
						|
 | 
						|
 | 
						|
Configuration
 | 
						|
 | 
						|
  * Copy the file ldap2dns.schema into the directory /etc/openldap/schema. Add
 | 
						|
    the following line to Your slapd.conf file:
 | 
						|
 | 
						|
    include         /etc/openldap/schema/ldap2dns.schema
 | 
						|
 | 
						|
    Now restart your LDAP server.
 | 
						|
 | 
						|
Note: If you are running OpenLDAP 2.0 or earlier look for appropriate schema
 | 
						|
files for your version in the deprecated/ subdirectory. These files are known
 | 
						|
to work as of ldap2dns 0.3.5 but are no longer supported for future feature
 | 
						|
updates.
 | 
						|
 | 
						|
 | 
						|
  * Start to populate your LDAP server with DNS information. As a first test do
 | 
						|
 | 
						|
    $ ldapadd -D "binddn" -w password < example.ldif
 | 
						|
 | 
						|
    Replace 'myorg' and 'binddn' with whatever is appropriate on Your system.
 | 
						|
    Start a search and see if something was added
 | 
						|
 | 
						|
    $ ldapsearch -D "binddn" "objectclass=dnsrrset"
 | 
						|
 | 
						|
  * Test ldap2dns
 | 
						|
 | 
						|
    $ ./ldap2dns -D "binddn" [ -b "searchbase" ] [ -w passwd ] -o data -o db -L
 | 
						|
 | 
						|
    This should create a 'data' file, a 'corp.local.db' file and should print
 | 
						|
    the DNS content.
 | 
						|
    Note: The data file is text data which can be processed with tinydns-data.
 | 
						|
    corp.local.db is the file as used by named. If You are using bind, You also
 | 
						|
    have to adopt the file /etc/named.conf and You have to restart named.
 | 
						|
 | 
						|
 | 
						|
 | 
						|
Schema Documentation
 | 
						|
 | 
						|
Two object-classes have been defined. DNSzone stores all the information to
 | 
						|
define a DNS zone, such as the SOA (Start Of Authority), serial numbers etc.
 | 
						|
DNSrrset is used to store the information for a single resource record, such as
 | 
						|
the domain name, IP-addresses, class and type.
 | 
						|
Here are the tables:
 | 
						|
 | 
						|
DNSzone
 | 
						|
 | 
						|
This object-class represents a DNS zone. It is the container for all the
 | 
						|
resource records within a zone. Zones can be primary or secondary. If used in
 | 
						|
conjunction with tinydns zones are always primary. Secondary zones don't make
 | 
						|
sense anyway! In addition to being a container, the zone object has attributes
 | 
						|
related to the management of the zone. These include the zone's SOA
 | 
						|
information. Each zone-object can have none to many children of class DNSrrset.
 | 
						|
 | 
						|
   ATTRIBUTE               VALUE                          Comment
 | 
						|
objectclass     DNSzone                      required
 | 
						|
cn              common name                  required
 | 
						|
DNSzonename     Name of the zone             required, multivalued
 | 
						|
DNSserial       Serial number of SOA         optional
 | 
						|
DNSrefresh      Refresh time of SOA          optional, only used for zone
 | 
						|
                                             transfers
 | 
						|
DNSretry        Retry time of SOA            optional, only used for zone
 | 
						|
                                             transfers
 | 
						|
DNSexpire       Expire time of SOA           optional, only used for zone
 | 
						|
                                             transfers
 | 
						|
DNSminimum      Minimum time to live         optional, only used for zone
 | 
						|
                                             transfers
 | 
						|
DNSadminmailbox Hostmaster's contact address optional
 | 
						|
DNSzonemaster   Primary nameserver for this  optional
 | 
						|
                zone
 | 
						|
DNStype         SOA                          must be SOA
 | 
						|
DNSclass        IN                           must be IN
 | 
						|
DNSttl          time to live                 optional, only used with tinydns
 | 
						|
DNStimestamp    timestamp                    optional, only used with tinydns
 | 
						|
 | 
						|
  * DNSzonename: This field is required to describe the zone's domain name, for
 | 
						|
    instance myorg.com. More than one DNSzonename my be specified for a DNSzone
 | 
						|
    so that the same host is accessable with different zonenames.
 | 
						|
  * DNSserial: This is the serial number as used for BIND's zone transfers.
 | 
						|
    Here it is used to inform ldap2dns that it has to rebuild its data-file.
 | 
						|
    Without increasing the serial number ldap2dns will ignore all modifications
 | 
						|
    until it is restarted.
 | 
						|
  * DNSrefresh, DNSretry, DNSexpire, DNSminimum: You may safly ignore these
 | 
						|
    numbers if You don't do zone-transfers. Since Your secondary nameserver
 | 
						|
    will connect to the LDAP server the same way Your primary does, You don't
 | 
						|
    need zone-transfers anyway.
 | 
						|
  * DNSzonemaster: Here you specify the canonical name of your primary
 | 
						|
    nameserver.
 | 
						|
  * DNSadminmailbox: This is the contact address of Your DNS-administrator. The
 | 
						|
    first dot is converted to a @.
 | 
						|
  * DNStype: Must be SOA (Start Of Authority)
 | 
						|
  * DNSclass: Must be IN (Internet, or do still use Chaosnet?)
 | 
						|
  * DNSttl: This is the time-to-live value as used by tinydns. If TTL is
 | 
						|
    nonzero (or omitted), the timestamp is a starting time from whereon this
 | 
						|
    zone's information is valid. If TTL is zero, the timestamp is an ending
 | 
						|
    time (``time to die'').
 | 
						|
  * DNStimestamp: This is the timestamp as used by tinydns. It represents a
 | 
						|
    string as external TAI64 timestamp, printed as 16 lowercase hexadecimal
 | 
						|
    characters
 | 
						|
 | 
						|
DNSrrset
 | 
						|
 | 
						|
The Resource Record Set represents all of the resource records for a given host
 | 
						|
name within a zone. It must be a child of a DNSzone object.
 | 
						|
 | 
						|
  ATTRIBUTE             VALUE                          Comment
 | 
						|
objectclass    DNSrrset                required
 | 
						|
cn             common name             required
 | 
						|
DNSdomainname  Name of this record     optional, relative to zonename
 | 
						|
DNSipaddr      IP address              optional, mutivalued
 | 
						|
DNScname       Canonical name          optional, without ending dot relative to
 | 
						|
                                       zonename
 | 
						|
DNSpreference  integer                 optional, only used for MX records
 | 
						|
DNStype        A, CNAME, NS, MX, PTR   must be any valid record type
 | 
						|
               or TXT
 | 
						|
DNSclass       IN                      must be IN
 | 
						|
DNSttl         time to live            optional, only used with tinydns
 | 
						|
DNStimestamp   timestamp               optional, only used with tinydns
 | 
						|
DNSsrvpriority SRV Priority            optional, defaults to 0 for SRV records
 | 
						|
DNSsrvweight   SRV Weight              optional, defaults to 0 for SRV records
 | 
						|
DNSsrvport     SRV Port                Required for SRV records
 | 
						|
 | 
						|
 | 
						|
  * DNSrrset: This object-class must be a direct child of DNSzone. Its dn
 | 
						|
    should be specified as
 | 
						|
 | 
						|
    cn=domainname,cn=zonename,...
 | 
						|
 | 
						|
  * DNSdomainname This is the partial domain-name, ie. the part in front of the
 | 
						|
    zone-name.
 | 
						|
  * DNSipaddr: This specifies the IP-address in dotted format. It can be used
 | 
						|
    for DNSrrset's of type A, NS, MX or PTR. DNSipaddr is multivalued to
 | 
						|
    specifiy more than one IP-address for a service. If used in DNSrrset's with
 | 
						|
    DNStype = PTR it overrides the old-fashioned form used in DNSdomainname
 | 
						|
    such as 13.178.23.in-addr.arpa for reverse lookups.
 | 
						|
  * DNScname: Whenever there is a mapping of a domain-name to a canonical name,
 | 
						|
    use this attribute. DNScname may be used for DNSrrset's with DNStype CNAME,
 | 
						|
    NS, MX, PTR or TXT. If the last character of a CNAME is a dot its name is
 | 
						|
    considered absolute. If it does not contain a dot, its name is prepended to
 | 
						|
    the zone-name.
 | 
						|
  * DNSpreference: This number is the mail-exchange preference as used by BIND.
 | 
						|
  * DNStype: This must be A, CNAME, NS, MX, PTR or TXT. It specifies the
 | 
						|
    DNSrrset type.
 | 
						|
  * DNSclass: Must be IN
 | 
						|
  * DNSttl: This is the time-to-live value as used by tinydns. If TTL is
 | 
						|
    non-zero (or omitted), the time-stamp is a starting time from where-on this
 | 
						|
    zone's information is valid. If TTL is zero, the timestamp is an ending
 | 
						|
    time (``time to die'').
 | 
						|
  * DNStimestamp: This is the timestamp as used by tinydns. It represents a
 | 
						|
    string as external TAI64 time-stamp, printed as 16 lowercase hexadecimal
 | 
						|
    characters
 | 
						|
  * DNSsrvpriority: Integer representing the relative priority of this DNS SRV
 | 
						|
    record. See menandmice.com for more information about DNS SRV records.
 | 
						|
  * DNSsrvweight: DNS SRV record weight field. Integer
 | 
						|
  * DNSsrvport: DNS SRV record port number. Integer
 | 
						|
 | 
						|
 | 
						|
Usage: Running ldap2dns
 | 
						|
 | 
						|
ldap2dns and ldap2dnsd recognize the following options:
 | 
						|
 | 
						|
-D binddn specify the distinguished name to bind to the LDAP directory
 | 
						|
-w bindpasswd use bindpasswd as password for simple authentication
 | 
						|
-b searchbase use searchbase as starting point for search instead default
 | 
						|
-o data generate a "data" file to be processed by tinydns-data
 | 
						|
-o db for each zone generate a "<zonename>.db" file to be used by named
 | 
						|
-L[filename] print output in LDIF format to [filename] or stdout for reimport
 | 
						|
-h host specify the hostname of LDAP directory. Default is localhost
 | 
						|
-p port portnumber to connect to LDAP directory. Defaults is 389
 | 
						|
-H ldapURI URI for LDAP server (examples: ldap://hostname or ldaps://hostname:636)
 | 
						|
-v run in verbose mode
 | 
						|
-vv even more verbose
 | 
						|
-V print version and exit
 | 
						|
-u numsecs update DNS data every numsecs.
 | 
						|
-t timeout timeout for LDAP searches, in seconds
 | 
						|
-M reclimit Limit LDAP results to reclimit number of records.
 | 
						|
 | 
						|
ldap2dns and ldap2dnsd recognize the following environment variables:
 | 
						|
TINYDNSDIR: Specifies the directory where ldap2dns writes its data file.
 | 
						|
LDAP2DNS_UPDATE: Specifies the update intervall as the -u command line option
 | 
						|
would.
 | 
						|
LDAP2DNS_OUTPUT: Specifies the default output, as the -o command line option
 | 
						|
would. ldap2dns and ldap2dnsd use the following parameters from /etc/ldap.conf
 | 
						|
if not specified on the command line: BASE: The LDAP search base.
 | 
						|
HOST: The LDAP server.
 | 
						|
PORT: The LDAP port.
 | 
						|
 | 
						|
If You are a tinydns user, run ldap2dns in /services/tinydns/root.
 | 
						|
If You are an openldap user, the command line switches are the same as for
 | 
						|
ldapsearch or ldapadd.
 | 
						|
 | 
						|
$ ldap2dns -D "binddn" [ -w passwd ] -b "searchbase" \
 | 
						|
-o data -e "cd /var/tinydns/root && /usr/bin/tinydns-data"
 | 
						|
 | 
						|
This generates a data file which is converted into a data.cdb by tinydns-data
 | 
						|
as soon as ldap2dns detects a modification in the LDAP directory. The password
 | 
						|
is required if You restrict read queries to authenticated users only. Test with
 | 
						|
 | 
						|
$ dnsq any corp.local ipaddr
 | 
						|
 | 
						|
Replace ipaddr with whatever You configured tinydns to listen to. If You are a
 | 
						|
BIND user, run ldap2dns in /var/named with
 | 
						|
 | 
						|
$ ldap2dns -D "binddn" -w passwd -b "searchbase" \
 | 
						|
-o db -e "kill -HUP `cat /var/run/named-pid`"
 | 
						|
 | 
						|
Do not forget to add You primary definition to your named.conf file. Your named
 | 
						|
should be restarted automatically as soon as ldap2dns detects a modification in
 | 
						|
the LDAP directory. If bind is not restarted, do so with
 | 
						|
 | 
						|
# kill -HUP PID
 | 
						|
 | 
						|
Now run
 | 
						|
 | 
						|
$ nslookup - localhost
 | 
						|
> ns1.corp.local
 | 
						|
 | 
						|
Note that nslookup only works with tinydns if your nameserver resolves its
 | 
						|
IP-address backwards.
 | 
						|
 | 
						|
Usage: Running ldap2dnsd
 | 
						|
 | 
						|
When ldap2dns is invoked as ldap2dnsd, the program starts as backgound-daemon
 | 
						|
and continuously checks for modifications in the LDAP directory. If the the
 | 
						|
daemon sees a modification in the DNSserial numbers it updates the data or .db
 | 
						|
files, depending what kind of output was configured. This check is done about
 | 
						|
once a minute and is configurable.
 | 
						|
The command-line options for ldap2dnsd are the same as for ldap2dns. Use the -u
 | 
						|
option to modify the update interval. You may also use -u on ldap2dns to start
 | 
						|
as a foreground daemon. This is useful if You want to run ldap2dns from
 | 
						|
daemontools.
 | 
						|
 | 
						|
These instructions assume you will be running ldap2dns under daemontoolsb> and
 | 
						|
that tinydns is also running under daemontools. These instructions also assume
 | 
						|
you are using Dan Bernstein's standard directory locations. Make sure you
 | 
						|
change the below examples to match your environment.
 | 
						|
 | 
						|
Start by creating the a non-root user to run your ldap2dns and associated
 | 
						|
logging mechanism:
 | 
						|
 | 
						|
# groupadd -r ldap2dns
 | 
						|
# useradd -r -d /dev/null -s /bin/false -c "ldap2dns Daemon" \
 | 
						|
 -g ldap2dns ldap2dns
 | 
						|
# groupadd -r l2dnslog
 | 
						|
# useradd -r -d /dev/null -s /bin/false -c "ldap2dns Logger" \
 | 
						|
 -g l2dnslog l2dnslog
 | 
						|
 | 
						|
 | 
						|
Next configure the ldap2dns area to be managed by daemontools. Typically this
 | 
						|
is /etc/ldap2dns
 | 
						|
 | 
						|
# cd /etc
 | 
						|
# ldap2tinydns-conf ldap2dns l2dnslog /etc/ldap2dns /etc/tinydns/root
 | 
						|
 | 
						|
The syntax is close to tinydns-conf except that you will also need to specify
 | 
						|
the path to the root directory for tinydns. This is the directory that holds
 | 
						|
the data file.
 | 
						|
 | 
						|
Next edit the file /etc/ldap2dns/run and optionally the environment variables
 | 
						|
in /etc/ldap2dns/env as necessary for your environment. This may include
 | 
						|
configuring a base DN, a bind DN, a password, and an interval.
 | 
						|
 | 
						|
When everything is ready configured properly create a symlink from /etc/
 | 
						|
ldap2dns into /service. This action will cause daemontools to launch ldap2dns.
 | 
						|
 | 
						|
# ln -s /etc/ldap2dns /service/ldap2dns
 | 
						|
 | 
						|
After a few seconds daemontools starts ldap2dnsd which itself generates data
 | 
						|
files whenever a modification is commited into the LDAP directory.
 | 
						|
 | 
						|
Importing DNS data from an existing AXFR capable (BIND) name server
 | 
						|
 | 
						|
A perl-script import.pl is contained in this package. Edit the first lines of
 | 
						|
the script to conform to Your configuration. If You have installed the Perl
 | 
						|
packages Net::LDAP and Net::DNS skip the following lines, otherwise do
 | 
						|
 | 
						|
# perl -MCPAN -e 'shell'
 | 
						|
(...snip...)
 | 
						|
> install Net::DNS
 | 
						|
> install Net::LDAP
 | 
						|
 | 
						|
Now check that Your nameserver allows zone transfers to your host and run the
 | 
						|
import script:
 | 
						|
 | 
						|
$ echo 'primary mydomain.org ' | ./import.pl
 | 
						|
 | 
						|
for a single domain or
 | 
						|
 | 
						|
# cat named.boot | ./import.pl
 | 
						|
 | 
						|
to populate Your LDAP directory.
 | 
						|
 | 
						|
Importing DNS data from an existing TinyDNS name server
 | 
						|
 | 
						|
Use the supplied data2ldap.pl in the scripts/ directory
 | 
						|
 | 
						|
$ data2ldap.pl data data.ldif ou=DNS,dc=example,dc=com
 | 
						|
 | 
						|
More to come...
 | 
						|
 | 
						|
 | 
						|
Roadmap
 | 
						|
 | 
						|
A browser-based administration toolkit, which connects directly to the
 | 
						|
LDAP-directory service.
 | 
						|
 | 
						|
To Do
 | 
						|
 | 
						|
  * Write a man page.
 | 
						|
  * named.conf should be created automatically.
 | 
						|
 | 
						|
Copyright and Disclaimer
 | 
						|
 | 
						|
This program is Copyright 1999-2004 Jacob Rief and 2005-2006 Ben Klang
 | 
						|
This program is licensed under the GPL version 2
 | 
						|
 | 
						|
ldap2dns was originally written by Jacob Rief (jacob.rief@tiscover.com). It is
 | 
						|
now maintained by Ben Klang (bklang@alkaloid.net). If you run ldap2dns on a
 | 
						|
production nameserver, please send the maintainer an email and mention on what
 | 
						|
OS and with which nameserver you do so.
 | 
						|
 | 
						|
Disclaimer: The author and all contributors disclaim any kind of warranty or
 | 
						|
liability or suitability for any purpose. By running this software you agree
 | 
						|
that you are a competent systems administrator and will bear the responsibility
 | 
						|
for your actions.
 | 
						|
 | 
						|
Download
 | 
						|
 | 
						|
Latest Release: ldap2dns version 0.4.1
 | 
						|
 | 
						|
Released October 19, 2006
 | 
						|
ChangeLog
 | 
						|
 | 
						|
 | 
						|
Developer Access:
 | 
						|
 | 
						|
The bleeding edge of ldap2dns is in the Alkaloid Networks subversion repository
 | 
						|
found at https://svn.alkaloid.net/gpl/ldap2dns/trunk.
 | 
						|
 | 
						|
Following the Subversion standard, releases are kept in /gpl/ldap2dns/tags and
 | 
						|
branches are in /gpl/ldap2dns/branches.
 | 
						|
 |