1*3965be93SchristosLDAP Support in DHCP
2*3965be93SchristosOriginal Author: Brian Masney <masneyb@gftp.org>
3*3965be93SchristosCurrent Maintainer: David Cantrell <dcantrell@redhat.com>
4*3965be93SchristosLast updated 07-Jul-2009
5*3965be93Schristos
6*3965be93SchristosThis document describes setting up the DHCP server to read it's configuration
7*3965be93Schristosfrom LDAP.  This work is based on the IETF document
8*3965be93Schristosdraft-ietf-dhc-ldap-schema-01.txt included in the doc directory.  For the
9*3965be93Schristoslatest version of this document, please see
10*3965be93Schristoshttp://dcantrel.fedorapeople.org/dhcp/ldap-patch/
11*3965be93Schristos
12*3965be93SchristosFirst question on most people's mind is "Why do I want to store my
13*3965be93Schristosconfiguration in LDAP?"  If you run a small DHCP server, and the configuration
14*3965be93Schristoson it rarely changes, then you won't need to store your configuration in LDAP.
15*3965be93SchristosBut, if you have several DHCP servers, and you want an easy way to manage your
16*3965be93Schristosconfiguration, this can be a solution.
17*3965be93Schristos
18*3965be93SchristosThe first step will be to setup your LDAP server.  I am using OpenLDAP from
19*3965be93Schristoswww.openldap.org.  Building and installing OpenLDAP is beyond the scope of
20*3965be93Schristosthis document.  There is plenty of documentation out there about this.  Once
21*3965be93Schristosyou have OpenLDAP installed, you will have to edit your slapd.conf file.  I
22*3965be93Schristosadded the following 2 lines to my configuration file:
23*3965be93Schristos
24*3965be93Schristosinclude         /etc/ldap/schema/dhcp.schema
25*3965be93Schristosindex           dhcpHWAddress eq
26*3965be93Schristosindex           dhcpClassData eq
27*3965be93Schristos
28*3965be93SchristosThe first line tells it to include the dhcp schema file.  You will find this
29*3965be93Schristosfile under the contrib directory in this distribution.  You will need to copy
30*3965be93Schristosthis file to where your other schema files are (maybe /etc/openldap/schema/).
31*3965be93SchristosThe second line sets up an index for the dhcpHWAddress parameter.  The third
32*3965be93Schristosparameter is for reading subclasses from LDAP every time a DHCP request comes
33*3965be93Schristosin.  Make sure you run the slapindex command and restart slapd to have these
34*3965be93Schristoschanges to into effect.
35*3965be93Schristos
36*3965be93SchristosNow that you have LDAP setup, you should be able to use gq
37*3965be93Schristos(http://biot.com/gq/) to verify that the dhcp schema file is loaded into LDAP.
38*3965be93SchristosPull up gq, and click on the Schema tab.  Go under objectClasses, and you
39*3965be93Schristosshould see at least the following object classes listed: dhcpClass, dhcpGroup,
40*3965be93SchristosdhcpHost, dhcpOptions, dhcpPool, dhcpServer, dhcpService, dhcpSharedNetwork,
41*3965be93SchristosdhcpSubClass, and dhcpSubnet.  If you do not see these, you need to check over
42*3965be93Schristosyour LDAP configuration before you go any further.
43*3965be93Schristos
44*3965be93SchristosYou should now be ready to build DHCP.  If you would like to enable LDAP in
45*3965be93Schristosdhcpd, you will need to perform the following steps:
46*3965be93Schristos
47*3965be93Schristos  * Apply the patch here to the unpacked ISC dhcp source tree.
48*3965be93Schristos  * Regenerate the configure script (requires GNU autoconf and automake):
49*3965be93Schristos        aclocal
50*3965be93Schristos        libtoolize --copy --force
51*3965be93Schristos        autoconf
52*3965be93Schristos        autoheader
53*3965be93Schristos        automake --foreign --add-missing --copy
54*3965be93Schristos  * Run ./configure with the '--with-ldap' argument to enable OpenLDAP.
55*3965be93Schristos    If you want LDAP over SSL, also use the '--with-ldapcrypto' argument.
56*3965be93Schristos  * Run 'make' to build ISC dhcp.
57*3965be93Schristos
58*3965be93SchristosOnce you have DHCP installed, you will need to setup your initial plaintext
59*3965be93Schristosconfig file. In my /etc/dhcpd.conf file, I have:
60*3965be93Schristos
61*3965be93Schristosldap-server "localhost";
62*3965be93Schristosldap-port 389;
63*3965be93Schristosldap-username "cn=DHCP User, dc=ntelos, dc=net";
64*3965be93Schristosldap-password "blah";
65*3965be93Schristosldap-base-dn "dc=ntelos, dc=net";
66*3965be93Schristosldap-method dynamic;
67*3965be93Schristosldap-debug-file "/var/log/dhcp-ldap-startup.log";
68*3965be93Schristos
69*3965be93SchristosIf SSL has been enabled at compile time, the dhcp server trys to use TLS if
70*3965be93Schristospossible, but continues without TLS if not.
71*3965be93Schristos
72*3965be93SchristosYou can modify this behaviour using following option in /etc/dhcp/dhcpd.conf:
73*3965be93Schristos
74*3965be93Schristosldap-ssl <off | ldaps | start_tls | on>
75*3965be93Schristos   off:       disables TLS/LDAPS.
76*3965be93Schristos   ldaps:     enables LDAPS -- don't forget to set ldap-port to 636.
77*3965be93Schristos   start_tls: enables TLS using START_TLS command
78*3965be93Schristos   on:        enables LDAPS if ldap-port is set to 636 or TLS in
79*3965be93Schristos              other cases.
80*3965be93Schristos
81*3965be93SchristosSee also "man 5 ldap.conf" for description the following TLS related
82*3965be93Schristosoptions:
83*3965be93Schristos   ldap-tls-reqcert, ldap-tls-ca-file, ldap-tls-ca-dir, ldap-tls-cert
84*3965be93Schristos   ldap-tls-key, ldap-tls-crlcheck, ldap-tls-ciphers, ldap-tls-randfile
85*3965be93Schristos
86*3965be93SchristosThe ldap-init-retry <num> enables an optional ldap connect retry loop with
87*3965be93Schristosthe specified number of retries with a one second sleep between each try
88*3965be93Schristosduring the initial startup of the dhcp server.
89*3965be93SchristosIt allows to catch the condition, that the (remote) ldap server is not yet
90*3965be93Schristosstarted at the start time of the dhcp server.
91*3965be93Schristos
92*3965be93SchristosAll of these parameters should be self explanatory except for the ldap-method.
93*3965be93SchristosYou can set this to static or dynamic.  If you set it to static, the
94*3965be93Schristosconfiguration is read once on startup, and LDAP isn't used anymore.  But, if
95*3965be93Schristosyou set this to dynamic, the configuration is read once on startup, and the
96*3965be93Schristoshosts that are stored in LDAP are looked up every time a DHCP request comes
97*3965be93Schristosin.
98*3965be93Schristos
99*3965be93SchristosWhen the optional statement ldap-debug-file is specified, on startup the DHCP
100*3965be93Schristosserver will write out the configuration that it generated from LDAP.  If you
101*3965be93Schristosare getting errors about your LDAP configuration, this is a good place to
102*3965be93Schristosstart looking.
103*3965be93Schristos
104*3965be93SchristosThe next step is to set up your LDAP tree. Here is an example config that will
105*3965be93Schristosgive a 10.100.0.x address to machines that have a host entry in LDAP.
106*3965be93SchristosOtherwise, it will give a 10.200.0.x address to them.  (NOTE: replace
107*3965be93Schristosdc=ntelos, dc=net with your base dn). If you would like to convert your
108*3965be93Schristosexisting dhcpd.conf file to LDIF format, there is a script
109*3965be93Schristosdhcpd-conf-to-ldap that will convert it for you.  Type
110*3965be93Schristosdhcpd-conf-to-ldap --help to see the usage information for this script.
111*3965be93Schristos
112*3965be93Schristos# You must specify the server's host name in LDAP that you are going to run
113*3965be93Schristos# DHCP on and point it to which config tree you want to use.  Whenever DHCP
114*3965be93Schristos# first starts up, it will do a search for this entry to find out which
115*3965be93Schristos# config to use
116*3965be93Schristosdn: cn=brian.ntelos.net, dc=ntelos, dc=net
117*3965be93SchristosobjectClass: top
118*3965be93SchristosobjectClass: dhcpServer
119*3965be93Schristoscn: brian.ntelos.net
120*3965be93SchristosdhcpServiceDN: cn=DHCP Service Config, dc=ntelos, dc=net
121*3965be93Schristos
122*3965be93Schristos# Here is the config tree that brian.ntelos.net points to.
123*3965be93Schristosdn: cn=DHCP Service Config, dc=ntelos, dc=net
124*3965be93Schristoscn: DHCP Service Config
125*3965be93SchristosobjectClass: top
126*3965be93SchristosobjectClass: dhcpService
127*3965be93SchristosdhcpPrimaryDN: dc=ntelos, dc=net
128*3965be93SchristosdhcpStatements: ddns-update-style none
129*3965be93SchristosdhcpStatements: default-lease-time 600
130*3965be93SchristosdhcpStatements: max-lease-time 7200
131*3965be93Schristos
132*3965be93Schristos# Set up a shared network segment
133*3965be93Schristosdn: cn=WV Test, cn=DHCP Service Config, dc=ntelos, dc=net
134*3965be93Schristoscn: WV
135*3965be93SchristosobjectClass: top
136*3965be93SchristosobjectClass: dhcpSharedNetwork
137*3965be93Schristos
138*3965be93Schristos# Set up a subnet declaration with a pool statement.  Also note that we have
139*3965be93Schristos# a dhcpOptions object with this entry
140*3965be93Schristosdn: cn=10.100.0.0, cn=WV Test, cn=DHCP Service Config, dc=ntelos, dc=net
141*3965be93Schristoscn: 10.100.0.0
142*3965be93SchristosobjectClass: top
143*3965be93SchristosobjectClass: dhcpSubnet
144*3965be93SchristosobjectClass: dhcpOptions
145*3965be93SchristosdhcpOption: domain-name-servers 10.100.0.2
146*3965be93SchristosdhcpOption: routers 10.100.0.1
147*3965be93SchristosdhcpOption: subnet-mask 255.255.255.0
148*3965be93SchristosdhcpOption: broadcast-address 10.100.0.255
149*3965be93SchristosdhcpNetMask: 24
150*3965be93Schristos
151*3965be93Schristos# Set up a pool for this subnet.  Only known hosts will get these IPs
152*3965be93Schristosdn: cn=Known Pool, cn=10.100.0.0, cn=WV Test, cn=DHCP Service Config, dc=ntelos, dc=net
153*3965be93Schristoscn: Known Pool
154*3965be93SchristosobjectClass: top
155*3965be93SchristosobjectClass: dhcpPool
156*3965be93SchristosdhcpRange: 10.100.0.3 10.100.0.254
157*3965be93SchristosdhcpPermitList: deny unknown-clients
158*3965be93Schristos
159*3965be93Schristos# Set up another subnet declaration with a pool statement
160*3965be93Schristosdn: cn=10.200.0.0, cn=WV Test, cn=DHCP Service Config, dc=ntelos, dc=net
161*3965be93Schristoscn: 10.200.0.0
162*3965be93SchristosobjectClass: top
163*3965be93SchristosobjectClass: dhcpSubnet
164*3965be93SchristosobjectClass: dhcpOptions
165*3965be93SchristosdhcpOption: domain-name-servers 10.200.0.2
166*3965be93SchristosdhcpOption: routers 10.200.0.1
167*3965be93SchristosdhcpOption: subnet-mask 255.255.255.0
168*3965be93SchristosdhcpOption: broadcast-address 10.200.0.255
169*3965be93SchristosdhcpNetMask: 24
170*3965be93Schristos
171*3965be93Schristos# Set up a pool for this subnet. Only unknown hosts will get these IPs
172*3965be93Schristosdn: cn=Known Pool, cn=10.200.0.0, cn=WV Test, cn=DHCP Service Config, dc=ntelos, dc=net
173*3965be93Schristoscn: Known Pool
174*3965be93SchristosobjectClass: top
175*3965be93SchristosobjectClass: dhcpPool
176*3965be93SchristosdhcpRange: 10.200.0.3 10.200.0.254
177*3965be93SchristosdhcpPermitList: deny known clients
178*3965be93Schristos
179*3965be93Schristos# Set aside a group for all of our known MAC addresses
180*3965be93Schristosdn: cn=Customers, cn=DHCP Service Config, dc=ntelos, dc=net
181*3965be93SchristosobjectClass: top
182*3965be93SchristosobjectClass: dhcpGroup
183*3965be93Schristoscn: Customers
184*3965be93Schristos
185*3965be93Schristos# Host entry for my laptop
186*3965be93Schristosdn: cn=brianlaptop, cn=Customers, cn=DHCP Service Config, dc=ntelos, dc=net
187*3965be93SchristosobjectClass: top
188*3965be93SchristosobjectClass: dhcpHost
189*3965be93Schristoscn: brianlaptop
190*3965be93SchristosdhcpHWAddress: ethernet 00:00:00:00:00:00
191*3965be93Schristos
192*3965be93SchristosYou can use the command ldapadd to load all of these entries into your LDAP
193*3965be93Schristosserver. After you load this, you should be able to start up DHCP. If you run
194*3965be93Schristosinto problems reading the configuration, try running dhcpd with the -d flag.
195*3965be93SchristosIf you still have problems, edit the site.conf file in the DHCP source and
196*3965be93Schristosadd the line: COPTS= -DDEBUG_LDAP and recompile DHCP. (make sure you run make
197*3965be93Schristosclean and rerun configure before you rebuild).
198*3965be93Schristos
199*3965be93SchristosDHCPv6 requires a separate instance of the dhcpd server from the
200*3965be93SchristosDHCPv4 server.
201*3965be93Schristos
202*3965be93SchristosIt is convenient to use distinct LDAP login DNs for the two servers,
203*3965be93Schristosand setup LDAP access restrictions in the LDAP server, so that each
204*3965be93SchristosDHCP server only has access to its own data.
205*3965be93Schristos
206*3965be93SchristosYou will need to create a separate configuration file,
207*3965be93Schristoscall it /etc/dhcpd6.conf.  For example:
208*3965be93Schristos
209*3965be93Schristosldap-server "localhost";
210*3965be93Schristosldap-port 389;
211*3965be93Schristosldap-username "cn=DHCPv6 User, dc=ntelos, dc=net";
212*3965be93Schristosldap-password "blahblah";
213*3965be93Schristosldap-base-dn "dc=ntelos, dc=net";
214*3965be93Schristosldap-method dynamic;
215*3965be93Schristosldap-debug-file "/var/log/dhcp-ldap-startup.log";
216*3965be93Schristos
217*3965be93SchristosAnd use these command line arguments to dhcpd:
218*3965be93Schristos
219*3965be93Schristosdhcpd eth... -6 -cf /etc/dhcpd6.conf -pf /var/run/dhcpd6.pid -lf /var/lib/dhcpd6/dhcpd.leases
220*3965be93Schristos
221*3965be93SchristosFor DHCPv6, the client configuration is the same, but substitute the
222*3965be93SchristosClient ID for the Ethernet hardware address.  Here is an example of a
223*3965be93Schristoshost definition for a DHCPv6 client:
224*3965be93Schristos
225*3965be93Schristosdn: cn=examplehost,cn=XXXX:XXXX:XXXX:XXXX::/64,cn=Network-eth1,cn=DHCPv6,dc=example,dc=com
226*3965be93SchristosobjectClass: top
227*3965be93SchristosobjectClass: dhcpHost
228*3965be93Schristoscn: examplehost
229*3965be93SchristosdhcpClientId: XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX
230*3965be93SchristosdhcpStatements: fixed-address6 XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX:XXXX
231*3965be93Schristosoption host-name "examplehost.ipv6.example.com"
232*3965be93Schristosoption domain-name "ipv6.example.com"
233