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