How to add a new subnet via the REST API

Carsten Strotmann

2025/03/20

Adding a new subnet via the Kea-DHCP REST API

Admins can edit the Kea-DHCP configuration file via the REST API enfpoint via the Kea-DHCP Control Agent process.

In this example, the access to the API endpoint is not authenticated or restricted. In production environments, the API endpoint should not be open to the public (for security reasons). The API endpoint in this example runs on the IPv6 loopback address ::1 on port 9099. IP-address and port number can be different in other Kea-DHCP deployments.

Requirements

Step 1: retrieving the current running configuration as a JSON file

curl -s -X POST -H "Content-Type: application/json" \
   -d '{ "command": "config-get", "service": [ "dhcp4" ] }' \
   http://[::1]:9099/ | jq ".[0]" > config1.json

This command reads the current running config from the Kea-DHCPv4 Server and writes it into the local file config1.json. Be aware that the running config can be different from the configuration files on disk.

Step 2: remove the result and hash information from the JSON file

The JSON configuration contains the result code of the last REST API call and the hash over the current configuration. Both cannot be send back to the Kea-DHCP server, so we remove both. The resulting file config3.json now contains a valid Kea-DHCP configuration.

jq "del(.result)" config1.json > config2.json
jq "del(.arguments.hash)" config2.json > config3.json

Step 3: add the new subnet

We write the content of the new subnet definition into a file (file new-subnet.json in this example):

{
  "ID": 1000,
  "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"
    }
  ]
}

Now we add the content of the file to the subnet4 JSON ARRAY in the configuration file:

jq '.arguments.Dhcp4.subnet4 += [input]' config3.json new-subnet.json  > config4.json

Add commands to change the running configuration

Next we add two JSON structures to the configuration file. The config-set command tells Kea-DHCP to apply the recieved JSON as a new configuration, and "service": [ "dhcp4" ] will select the Kea-DHCPv4 service on the system:

jq '."command" = "config-set"' config4.json > config5.json
jq '."service" = [ "dhcp4" ]' config5.json > config6.json

Send the JSON file back to the Kea-DHCP server to change the running config

The resulting configuration file config6.json can now be send back to the Kea-DHCP server to change the running config:

curl -s -X POST \
   -H "Content-Type: application/json" \
   -d @config6.json http://[::1]:9099/ | jq

The output from curl and jq should look similar to this.

[
  {
    "arguments": {
      "hash": "AAAA72192292409CAD2EB00571FF66C6A14B69F576A63EFB91C6A430AF69258F"
    },
    "result": 0,
    "text": "Configuration successful."
  }
]

Writing the running configuration to storage

Now we've changed the running configuration of our Kea-DHCP server. However the config change has not been written to storage. A restart or reboot would activate the old configuration again.

curl -s -X POST -H "Content-Type: application/json" \
     -d '{ "command": "config-write", "arguments": { "filename": "/etc/kea/kea-dhcp4.conf" }, "service": [ "dhcp4" ] }' \
     http://[::1]:9099/ | jq

Optimizations

The tool jq does not support in-place editing of files. yq (https://github.com/mikefarah/yq) can be used as an alternative that supports in-place edits of JSON files.

The steps can be automated with a shell script.