This is a hook for the Kea DHCP server that provides a means to tag DHCP packets with a client class based on registration in an external LDAP database.
The to-be assigned class is determined based on a result of LDAP search query. The name assigned classes can be configured by positiveResultClass
and negativeResultClass
configuration parameters (see below).
The implementation is heavily inspired by the example user_chk hook hook with notable differences:
-
You can restrict which subnets this hook should apply to. This means that the class resolution has to happen in
subnet_select
phase and the client class assigned by this hook cannot itself be used for subnet selection. Instead, we have to use this class information for restricting use of a specific pool defined within a subnet (see 14.7. Configuring Pools With Class Information in the official Kea documentation for more details ) -
Simple caching layer of client registration resolution results is present. This caching mechanism serves a sole purpose of protecting backend data stores against traffic caused by bursts of DHCP packets (eg. from misconfigured DHCP clients). The caching functionality should not be considered an effective protection against targeted DDoS attacks.
-
Functionality of assigning per-address DHCP options is not provided.
For build you will need development files for following projects:
-
Kea
-
boost
-
log4cplus
You will also need the autotools toolchain (at least autoconf, automake and libtool is required).
To build a hook run:
./autogen.sh
./configure --enable-generate-messages
make
You can also use included vagga.yaml
file to prepare your build environment using Vagga (mainly for testing purposes).
First, register a hook library with appropriate configuration as follows:
"hooks-libraries": [
{
"library": "/usr/lib/kea/hooks/libdhcp_user_chk_ldap.so",
"parameters": {
"sourceType": "ldap", // (1)
"subnets": [ "10.0.1.0/24", "10.0.2.0/24" ], // (2)
"source": {
"uri": "ldaps://ldap.example1.somehost:636 ldaps://ldap.example2.somehost:636", // (3)
"baseDN": "cn=DHCP,o=example.com", // (4)
"filter": "(cn=%s)", // (5)
"bindDN": "cn=dhcp-agent,ou=agents,o=example.com", // (6)
"bindPwd": "XXXXX", // (7)
"maxQueryResultSize": 100, // (8)
"tlsMode": "tls", // (9)
"maxQueryTime": 2, // (10)
"ldapApiTimeout": 2, // (11)
"networkTimeout": 2, // (12)
"maxLdapOpTries": 3 // (13)
},
"defaults": {
"positiveResultClass": "registered", // (14)
"negativeResultClass": "not-registered" // (15)
},
"cache": {
"positiveResultTtl": 20, // (16)
"negativeResultTtl": 10, // (17)
"maxSize": 5000 // (18)
}
}
}
]
-
So far, only LDAP data source is supported.
-
Subnet name as defined in
subnet4
/subnet6
sections. -
Comma or whitespace-delimited list of LDAP URIs of backend LDAP server(s). Failover between hosts is provided by the underlying libldap library.
-
Base distinguished name (DN) for performing LDAP search. Searches are always performed with a
subtree
scope specified. -
Filter template with a single, mandatory string parameter (denoted as
%s
) containing hexadecimal serialization (delimited by:
) of clients HW address (in case of DHCPv4 client) or DUID (DHCPv6 clients). -
DN of technical acount under used for LDAP authentication.
-
Password credential used for LDAP authentication.
-
Limits how many entries may server send in a response before replying with a "Size Limit Exceeded" error.
-
Selects TLS mode for a connection. Allowed values are
none
,starttls
andtls
. Thetls
value requiresldaps://
schema to be specified in theuri
parameter. -
Limits how long should server process the search request before replying with a "Time Limit Exceeded" error. The limit is specified in seconds.
-
Number of seconds the hook is allowed to block while performing LDAP API operation. (see LDAP_OPT_NETWORK_TIMEOUT option for details)
-
Number of seconds the hook is allowed to block on a syscall (connect/poll/select) caused by an LDAP operation. (see LDAP_OPT_TIMEOUT option for details)
-
Specifies hom many times should the LDAP operation be retried in case of failure. This option currently applies only to BIND and STARTTLS operations. Search requests are always repeated once at most.
-
Specifies name of client class that should be assigned to DHCP packet of clients registered in LDAP
-
Specifies name of client class that should be assigned to DHCP packets of clients without registration
-
Specifies how long (in seconds) should successful registration checks be cached.
-
Specifies how long (in seconds) should unsuccessful registration checks be cached.
-
Specifies the cache size.
Then, you can restrict access to DHCP pool based on client class:
"subnet4": [
{
"subnet": "10.0.1.0/24",
"pools": [
{
"client-class": "registered",
"pool": "10.0.1.210 - 10.0.1.250"
}
]
}