DMYTRO SHYTYI

isc DHCP openLDAP python

Recenly there was a need to make a testbed for Zero Touch Provisioning of devices with NSO.
I am not ldap guy, but I interoperated a bit with it and thus in this post you may find information
 that is required to proceed with a testbed. Most of this information is available on the internet. This post is a memo.

First we install ISC dhcp server and configuring the ‘schema’

sudo apt-get install isc-dhcp-server-ldap
cd /usr/share/doc/isc-dhcp-server-ldap/
sudo gunzip dhcp.schema.gz 
sudo cp dhcp.schema /etc/ldap/schema/
touch dhcp.conf
echo "include /etc/ldap/schema/dhcp.schema" > dhcp.conf 
mkdir /tmp/dhcp
slaptest -f ./dhcp.conf -F /tmp/dhcp/
cd /tmp/dhcp/cn=config/cn=schema

Next we delete from “cn\=\{0\}dhcp.ldif from the bottom:

structuralObjectClass: olcSchemaConfig
entryUUID: 9bcf5d1c-ee67-1033-8cfe-8d23f897bb77
creatorsName: cn=config
createTimestamp: 20141022184725Z
entryCSN: 20141022184725.031859Z#000000#000#000000
modifiersName: cn=config
modifyTimestamp: 20141022184725Z

And from the top of the file we change values to the next

dn: cn={0}dhcp
objectClass: olcSchemaConfig
cn: {0}dhcp

To

dn: cn=dhcp,cn=schema,cn=config
objectClass: olcSchemaConfig
cn: dhcp

In LDAP directory we distinguish the next nodes defined by X.500 Directory Specification.

  • CN = Common Name
  • OU = Organizational Unit
  • DC = Domain Component

Now we add dhcp organization unit

echo "dn: ou=dhcp,dc=example,dc=com
ou: dhcp
objectClass: top
objectClass: organizationalUnit
description: DHCP Servers" > dhcp.ldif

Apply the data located in the file:

ldapadd  -x -H ldap://localhost/ -D cn=admin,dc=example,dc=com -W -f dhcp.ldif

Add server common name

echo "dn: cn=config, ou=dhcp,dc=example,dc=com
cn: config
objectClass: top
objectClass: dhcpService
dhcpPrimaryDN:  cn=server,ou=dhcp,dc=example,dc=com
dhcpStatements: ddns-update-style none
dhcpStatements: get-lease-hostnames true
dhcpStatements: use-host-decl-names true" > dhcpservice.ldif

Apply the data located in the file:

ldapadd  -x -H ldap://localhost/ -D cn=admin,dc=example,dc=com -W -f dhcpservice.ldif

Add dhcp subnet common name

echo 'dn: cn=192.168.1.0, cn=config, ou=dhcp,dc=example,dc=com
cn: 192.168.1.0
objectClass: top
objectClass: dhcpSubnet
objectClass: dhcpOptions
dhcpNetMask: 24
dhcpRange: 192.168.1.150 192.168.1.200
dhcpStatements: default-lease-time 600
dhcpStatements: max-lease-time 7200
dhcpOption: netbios-name-servers 192.168.1.16
dhcpOption: subnet-mask 255.255.255.0
dhcpOption: routers 192.168.1.1
dhcpOption: domain-name-servers 192.168.1.11
dhcpOption: domain-name "example.com"' > dhcpsubnet.ldif

Apply the data located in the file:

ldapadd  -x -H ldap://localhost/ -D cn=admin,dc=example,dc=com -W -f dhcpsubnet.ldif

Add the client common name:

echo "dn: cn=client01, cn=config, ou=dhcp,dc=example,dc=com
cn: client01
objectClass: top
objectClass: dhcpHost
dhcpHWAddress: ethernet 00:16:3e:3d:eb:87
dhcpStatements: fixed-address 192.168.1.111" > host1.ldif

Apply the data located in the file:

ldapadd  -x -H ldap://localhost/ -D cn=admin,dc=example,dc=com -W -f host.ldif

Modify the next file

vim /etc/dhcp/dhcpd.conf

and put the next information:

ldap-server                 "localhost";
ldap-port                   389;
# We do an anonymous bind
# ldap-username             "cn=directorymanagerloginname";
# ldap-password             "mypassword";
ldap-base-dn                "ou=dhcp,dc=example,dc=com";
ldap-method                 static;
ldap-debug-file             "/var/log/dhcp-ldap-startup.log";
ldap-dhcp-server-cn         "server";

The next step is to use python to search the IP and MAC addresses of assigned to the device:

We are in the python3 interpreter. We have to import the next modules:

from ldap3 import Server, Connection, ALL

Connect to the server installed locally with credentials.

server = ldap3.Server('127.0.0.1')                                                                          
conn = Connection('127.0.0.1', get_info=ALL)                                                              
conn = Connection(server, 'cn=admin,dc=example,dc=com', 'PASSWORD', auto_bind=True)

Search for the object class and retreive the IP and Mac addresses

conn.search('dc=example,dc=com', '(objectclass=dhcpHost)', attributes=['dhcpHWAddress','dhcpStatements'])   
entry = conn.entries[0]     
entry.dhcpHWAddress.value.split()[1]
entry.dhcpStatements.value.split()[1]