PowerDNS with LDAP backend setup

What I'm trying to do this days is to unite somehow all used services and have some centralized storage of all logins/passwords and other data. And then build a web based administration tool for this.

As centralized storage of all my data ive chosen LDAP. And a first service im trying to setup is DNS. I've had BIND9 setup with all info stored in plain text files. Now i wanna setup PowerDNS with LDAP backend and keep all my zones in LDAP.

I use debian, so installation procedure is straight-farward:

root@sun:~# apt-get install pdns-server pdns-recursor pdns-backend-ldap slapd
 ldap-utils

Now we need to setup slapd - Stand-alone LDAP daemon: Typical config would look like this:

include         /etc/ldap/schema/core.schema
include         /etc/ldap/schema/cosine.schema
include         /etc/ldap/schema/nis.schema
include         /etc/ldap/schema/inetorgperson.schema
include         /etc/ldap/schema/dnsdomain2.schema

schemacheck     on
pidfile         /var/run/slapd/slapd.pid
argsfile        /var/run/slapd.args
loglevel        0
modulepath      /usr/lib/ldap
moduleload      back_bdb

backend         bdb
checkpoint      512 30

database        bdb
suffix          "dc=example,dc=com"
directory       "/var/lib/ldap"
rootdn          "cn=admin,dc=example,dc=com"
rootpw          {SSHA}YxjoLOLbdXjLYlaKy6uws/Dbyix9AQVh

index           default     pres,eq
index           uid
index           cn,email    pres,eq,sub
index           associatedDomain    pres,eq
index           objectClass eq

lastmod         off

access to attrs=userPassword
        by dn="cn=admin,dc=example,dc=com" write
        by anonymous auth
        by self write
        by * none

access to dn.base="" by * read

access to *
        by dn="cn=admin,dc=example,dc=com" write
        by * read

The line include /etc/ldap/schema/dnsdomain2.schema is optinal - standard ldap schemas are sufficient to run PowerDNS unless you need to handle revers lookups. In this case you'll need to add PTR records into your ldap objects, though this attribute is not available in cosine.schema and you'll have to include another schema, bundled with powerdns-backend-ldap: /etc/ldap/schema/dnsdomain2.schema. It defines dNSDomain2 object, which has PTRRecord as well.

rootdn/rootpw lines are needed only for adding records into the db. Later you can add any account you like and give it access in your slapd.conf. Password can be either plain text or crypted (can be obtained with slappasswd) Alternatively, data can be added using slapadd command locally, though this tool does not perform schema checks and does not check if superior entries exist.

Now we can start slapd

invoke-rc.d slapd start
and add some dns stuff:
#dns.ldif:
dn: dc=example,dc=com
objectClass: dcObject
objectClass: organization
dc: example
o: example
description: http://example.com/

dn: ou=dns,dc=example,dc=com
objectClass: top
objectClass: organizationalUnit
ou: dns

dn: dc=com,ou=dns,dc=example,dc=com
objectClass: dNSDomain2
objectClass: domainRelatedObject
dc: com
associateddomain: com

dn: dc=example,dc=com,ou=dns,dc=example,dc=com
objectClass: dNSDomain2
objectClass: domainRelatedObject
dc: example
SOARecord: ns1.example.com sysadmin@example.com 1 1800 3600 86400 7200
NSRecord: ns1.example.com
NSRecord: ns2.example.com
MXRecord: 10 mail.example.com
ARecord: 10.1.1.1
associatedDomain: example.com

dn: dc=ns1,dc=example,dc=com,ou=dns,dc=example,dc=com
objectClass: dNSDomain2
objectClass: domainRelatedObject
dc: ns1
ARecord: 10.1.1.1
associatedDomain: ns1.example.com

dn: dc=ns2,dc=example,dc=com,ou=dns,dc=example,dc=com
objectClass: dNSDomain2
objectClass: domainRelatedObject
dc: ns2
ARecord: 10.1.1.2
associatedDomain: ns2.example.com

dn: dc=mail,dc=example,dc=com,ou=dns,dc=example,dc=com
objectClass: dNSDomain2
objectClass: domainRelatedObject
dc: mail
ARecord: 10.1.1.3
associatedDomain: mail.example.com

#End

ldapadd -f dns.ldif -x -D 'cn=admin,dc=example,dc=com'  -W
Enter LDAP Password: <rootpw_here>

Here we use 'tree style', that is powerdns looks for entries by translating domain name into ldap DN. E.g. query for mail.example.com domain would be translated into 'dn: dc=mail,dc=example,dc=com,ou=dns,dc=example,dc=com'. This method seems more logical/straightforward to me. Also it gives 7% perfomance advantage of other methods.

The only thing left to do is to tell our PowerDNS to use LDAP backend:

#/etc/powerdns/pdns.d/pdns.local

# host running slapd
ldap-host=127.0.0.1:389
ldap-basedn=ou=dns,dc=example,dc=com
#ldap-binddn=""
#ldap-secret=""
ldap-method="tree"
After this, edit /etc/powerdns/pdns.conf and make sure you have something similar in it:
#/etc/powerdns/pdns.conf

allow-recursion=127.0.0.1,10.1.1.0/24
launch=ldap
local-address=10.1.1.1,192.168.7.1
recursor=127.0.0.1

#/etc/powerdns/recursor.conf
local-address=127.0.0.1

You dont have to run recursor from PowerDNS. E.g. you cant do zone forwarding in pdns-recursor, but you can, for example, use dnscache from djbdns instead or any other server you like :)