(Kea lease allocation, client classification and option assignment)
Created: 2020-10-14 Wed 10:40
VENDOR_CLASS_
and
the result is interpreted as a class
docsis3.0
, so the packet belongs to class
VENDOR_CLASS_docsis3.0
"shared-networks": [ { "name": "kea-net01", "relay": { "ip-address": "192.0.2.1" }, "subnet4": [ { "subnet": "192.0.2.0/24", "client-class": "VENDOR_CLASS_windowsCE", # <-- Windows CE Clients will get # an IP from this subnet "option-data": [{ "name": "routers", "data": "192.0.2.1" }], "pools": [{ "pool": "192.0.2.60 - 192.0.2.220" }] }, { "subnet": "10.0.0.0/24", "client-class": "VENDOR_CLASS_fedoraLinux", # <-- Fedora-Linux Clients will # get an IP from this subnet "option-data": [ [...]
KNOWN
classUNKNOWN
class{ "client-classes": [{ "name": "dependent-class", "test": "member('KNOWN')", "only-if-required": true }] }
"Dhcp4": { "client-classes": [ { "name": "windows", "test": "substring(option[60].hex,0,3) == 'win'", "option-data": [{ "name": "domain-name", "data": "win.example.com" }] }, { "name": "other", "test": "not(substring(option[60].hex,0,3) == 'win')", "option-data": [{ "name": "domain-name", "data": "other.example.com" }] } ], [...]
"shared-networks": [ { "name": "kea-lab01", "relay": { "ip-address": "192.0.2.1" }, "subnet4": [ { "subnet": "192.0.2.0/24", "client-class": "windows", # <-- all Windows Clients will # get IP addresses from this subnet "option-data": [{ "name": "routers", "data": "192.0.2.1" }], "pools": [{ "pool": "192.0.2.60 - 192.0.2.250" }] }, { "subnet": "10.0.0.0/24", "client-class": "other", # <-- non Windows Clients will # get IP addresses from this subnet "option-data": [ [...]
[kea-server]# systemctl stop kea-dhcp4 [kea-server]# kea-dhcp4 -d -c /etc/kea/kea-dhcp4.conf
kea-dhcp4.eval
or
kea-dhcp6.eval
debug logger in the Kea configuration file"Logging": { "loggers": [ { "name": "kea-dhcp4.eval", "output_options": [ { "output": "/var/log/kea-dhcp4-eval.log" } ], "severity": "DEBUG", "debuglevel": 55 } ] }
[kea-server]# tail -f /var/log/kea-dhcp4-eval.log
"Dhcp4": { "option-data": [{ "name": "domain-name-servers", "code": 6, "space": "dhcp4", "csv-format": true, "data": "192.0.2.1, 192.0.2.2" }, ... ]}
code
, space
and
csv-format
can be obmitted"Dhcp4": { "option-data": [{ "name": "domain-name-servers", "data": "192.0.2.1, 192.0.2.2" }, ... ]}
[...] "subnet4": [ { "subnet": "192.0.2.0/24", "pools": [ { "pool": "192.0.2.100 - 192.0.2.200" } ], "option-data": [{ "name": "routers", "data": "192.0.2.1" }, { "name": "domain-name", "data": "a.example.com" } ]}, [...]
"client-classes": [{ "name": "Zimbutsio-Server", "test": "option[vendor-class-identifier].text == 'Zimbutsio'", "option-data": [ { "name": "log-servers", "data": "192.0.2.42" }] }], [...]
{ "Dhcp4": { "option-def": [{ "name": "my-message", "code": 234, "type": "string", "array": false, "record-types": "", "space": "dhcp4", "encapsulate": "" }], "option-data": [{ "name": "my-message", "space": "dhcp4", "csv-format": true, "data": "Hello World" }], [...]
"Dhcp4:" { # This specifies global reservations. They will apply to all subnets that # have global reservations enabled. "reservations": [ { "hw-address": "aa:bb:cc:dd:ee:ff", "hostname": "hw-host-dynamic" }, { "hw-address": "01:02:03:04:05:06", "hostname": "hw-host-fixed", "ip-address": "192.0.1.77" }, # risky! { "circuit-id": "'office042'", "hostname": "circuit-id-host" }, [...]
Command | Description |
---|---|
reservation-add | add a new reservation to the Kea DB |
reservation-get-all | get all reservation information (can be huge) |
reservation-get | get information on a single reservation (by address or identifier) |
reservation-get-page | get all reservation information from a subnet by pages (used for GUI display) |
reservation-get-by-hostname | get the reservation information for one host by its hostname |
reservation-get-by-id | get the reservation information for one host by its identifier (global, since 1.9.0) |
reservation-del | delete a reservation from the database |
$ cat reservation-add.json { "command": "reservation-add", "service": [ "dhcp6" ], "arguments": { "reservation": { "duid": "01:02:03:04:05:06:07:08:09:0A", "hostname": "foo.example.com", "ip-addresses": [ "2001:db8:1::1" ], "option-data": [{ "data": "4491", "name": "vendor-opts" },{ "data": "3000:1::234", "name": "tftp-servers", "space": "vendor-4491" }], "subnet-id": 1 } } }
curl
command can be used to send the request towards the Kea
API$ curl -s -X POST -H "Content-Type: application/json" \ -d @reservation-add.json http://127.0.0.1:8000/ | jq [ { "result": 0, "text": "Host added." } ]
$ cat reservation-get-all.json { "service": [ "dhcp6" ], "command": "reservation-get-all", "arguments": { "subnet-id": 1 } } $ curl -s -X POST -H "Content-Type: application/json" \ -d @reservation-get-all.json http://127.0.0.1:8000/ | jq
[...] "subnet4": [ { "subnet": "10.0.0.0/24", "pools": [ { "pool": "10.0.0.10-10.0.0.200" } ], "reservations": [{ "hw-address": "01:02:03:04:05:06", "client-classes": [ "windows", "staff" ] }] }], [...]
reservation-mode
configuration parameter"Dhcp4": { "subnet4": [{ "subnet": "192.0.2.0/24", "reservation-mode": "disabled", ... }] }
reservation-mode | description |
---|---|
all | reservations can be on global, subnet or inside pool scope, all checks enabled |
out-of-pool | reservations in subnets are always outside the pool |
global | only global reservations allowed, not subnet/pool reservations |
disabled(*) | host reservation support is disabled, no checks for collisions |
hw-address
duid
client-id
circuit-id
flex-id
host-reservation-identifiers
takes a list of
identifier types that Kea will check
"host-reservation-identifiers": [ "circuit-id", "hw-address" ], "subnet4": [{ "subnet": "192.0.2.0/24", ... }]
[...] "shared-networks": [ { "name": "kea-lab01", "relay": { "ip-address": "192.0.2.1" }, "subnet4": [{ "subnet": "192.0.2.0/24", "option-data": [ { "name": "routers", "data": "192.0.2.1" }], "pools": [{ "pool": "192.0.2.20 - 192.0.2.190" }] }, { "subnet": "10.0.0.0/24", "option-data": [ { "name": "routers", "data": "10.0.0.1" }], "pools": [{ "pool": "10.0.0.10 - 10.0.0.200" }] }] ], [...]
yq
is a lightweight and portable command-line YAML processor:
https://mikefarah.gitbook.io/yqyq
yq
tool can be used to convert if JSON file (or JSON coming
from STDIN via shell pipe) into YAML$ yq r --prettyPrint add-reservation.json service: - dhcp6 command: reservation-add arguments: reservation: subnet-id: 1 duid: 01:02:03:04:05:06:07:08:09:0A ip-addresses: - 2001:db8:1::1 hostname: foo.example.com option-data: - name: vendor-opts data: "4491" - name: tftp-servers space: vendor-4491 data: 3000:1::234
yq
also supports the reverse, converting YAML back to JSON# yq r --prettyPrint -j add-reservation.yaml { "arguments": { "reservation": { "duid": "01:02:03:04:05:06:07:08:09:0A", "hostname": "foo.example.com", "ip-addresses": [ "2001:db8:1::1" ], "option-data": [ { "data": "4491", "name": "vendor-opts" }, { "data": "3000:1::234", "name": "tftp-servers", "space": "vendor-4491" } ], "subnet-id": 1 } }, "command": "reservation-add", "service": [ "dhcp6" ] }
kea-cmd
can aid to convert YAML
command-files into JSON and send them to the DHCP server via the
Kea control channel#!/bin/sh curl -s -X POST -H "Content-Type: application/json" \ -d "$(yq r -j ${1})" http://127.0.0.1:8000/ | yq r -P -
successful command
# kea-cmd add-reservation.yaml - result: 0 text: Host added.
error case
# kea-cmd add-reservation.yaml - result: 1 text: specified reservation '2001:db8:1:cafe::1' is not matching the IPv6 subnet prefix '2001:db8:1::/64'
service: - dhcp6 command: reservation-get-all arguments: subnet-id: 1 |
{ "service": [ "dhcp6" ], "command": "reservation-get-all", "arguments": { "subnet-id": 1 } } |