dnsdhcp - generating dnsd and dhcpd configuration from ldap


dnsdhcp is a minimalistic approach on managing dns and dhcp configuration of hosts recorded and managed in a ldap directory anyways.

Using a template system it enables you to flexibly include hosts information aquired from their ldap entries into configuration files - supposedly dnsd and dhcpd configuration.

So, in a nutshell: The script collects template-files from (possibly) remote locations and processes them using the information grabbed from the ldap. Afterwards the now done files are distributed to their original locations and - if wished - services are restartet.

Access to the source is provided via the public git repository:
git clone

The homepage can be found at


The usage is very simple. Once configured properly there's nothing more to do than executing this script.

Commandline options

Commandline options have precedence over the configuration. Thus you may do a dry-run even if configured otherwise.


As to be expected -n does a dry-run. This includes getting files, processing them but not distributing them to their original locations. The files in /tmp are not deleted, so you may combine this option with later runs using -d and -r.


Only distribute previously generated files in /tmp.


Only restart the services.


Be verbose (equivalent to $debug = 1).


Prints out a short help listing these options.


The whole configuration takes - up to now - place in the script itself. The various options are described below.

Debug Settings

        my $debug = 0;

Setting $debug to 1 will result in debug information being printet out.

        my $dry_run = 0;

Setting $dry_run to 1 will result in the script fetching the files, processing the templates, but not distributing them back to their hosts.

        my $config

is a hash-reference containing the main configuration described in the next two sections.

ldap settings

        ldap_address    => "",
        ldap_binddn     => "cn=nodes,dc=example,dc=com",
        ldap_bindpw     => "secrect",
        ldap_searchbase => "ou=nodes,dc=example,dc=com",

contain all settings concerning the ldap-directory to use.

general settings

The general settings influence the core behaviour of the script.

        file_list => [

file_list is an array-reference. The elements are the names of the files to be processed by this script. They may be remote locations in "scp"-style (host seperated via : from path) or local locations. There need to be the files themselves on the one hand side, on the other the template-files as well. Their name must be the original filename with an attached .tmpl .

        restart_services => 1,

results in the services being restarted. To be precise the restart_cmds are executed only when this is not set to 0.

        restart_cmds => [
                        "ssh extern service bind9 force-reload",
                        "ssh intern service dhcp3-server force-reload",

restart_cmds is an array-reference with the commands to be executed as elements.


        my $ldap_map = {
                dn      => 'cn',
                ip      => 'ipHostNumber',
                mac     => 'macAddress',
                parent  => 'parentNode',
                pool    => 'dnsdhcpPool',
                origin  => 'dnsdhcpOrigin',
                cname   => 'dnsdhcpCname',

ldap_map allows mapping ldap-attribute names to different names which may be used in the templates. This provides some flexibility regarding already existing structures in the ldap used. LHS is the internally (and template-side) used identifier, RHS the ldap attribute name.


As template engine the Template-Toolkit ( is used. The hosts themselves are organized in an array called hostlist. All of them have the attributes defined in $ldap_map which contain the values stored in the ldap.

Some simple examples for dhcp, dns and rdns follow below.


A very simple approach would be the following (only in the context of a group, in the format of isc-dhcp3):

  group {
    option routers;
        # some hosts not in ldap (for some reasons)
    host testhost1 { hardware ethernet 00:15:4f:40:29:8c; fixed-address;  }
    host testhost2 { hardware ethernet 00:15:4f:40:ab:a0; fixed-address;  }
        # all ldap hosts to follow
    [% FOREACH host = hostlist %]
    host [% %] { hardware ethernet [% host.mac %]; fixed-address [% host.ip %]; }
    [% END %]

Now you may want to distinguish certain groups of hosts and place them in different groups or pools in the dhcpd.conf as well. Just use their attributes to do so, possibly:

    [% FOREACH host = hostlist %]
        [% IF host.pool == "mitarbeiter" %]
    host [% %] { hardware ethernet [% host.mac %]; fixed-address [% host.ip %]; }
        [% END %]
    [% END %]


In the dnsd.conf you can do just the same, e.g.:

        ; some hosts not in ldap
        test1           A
        testera                 CNAME   test1
        test2           A
        testerb                 CNAME   test2
        ; clients
        [% FOREACH host = hostlist %]
            [% IF (host.parent == "desktops")  %]
        [% %]         A   [% host.ip %]
                [% FOREACH cname = host.cname %]
        [% cname %]     CNAME   [% %]
                [% END %]
            [% END %]
        [% END %]

Take care of that emty lines - without them it will get messed up. Also, note that the cname attribute is an array and thus to be iterated over.

Concerning reverse-dns there's the reverseip attribute:

        [% FOREACH host = hostlist %]
            [% IF host.pool == "studenten"  %]
        [% host.reverseip %]         PTR   [% host.dn %].
            [% END %]
        [% END %]


You may obtain some information about the internal workings of dnsdhcp below.

Program flow



Collects host information from ldap and reformats it into a nice datastructure.


Collects dnsd and dhcpd configuration file from (possibly remote) hosts.


Processes templatefiles with information collected.


Distributes the configurations files back to their locations.


Helper function. Takes a filename, returns the local-template-filename.


Helper function. Takes a filename, returns the local-filename.


Helper function. Takes an ip, returns the reversed ip.


Restarts dns and dhcp deamons.


Prints some help and exits gracefully.