Configuration Templates

The following sections include configuration templates for certain deployment types. The example configuration files are also available in the Kea sources, in the doc/examples directory.

Template: Home Network of a Power User

Below are some templates to assist in configuring the home network of a power user; they may also be appropriate for a small office. These templates make the following assumptions:

  • the administrator wants to use a single /24 class of IPv4 addresses.
  • High Availability is desired, so there are two DHCP servers.
  • there are a handful of devices, and some of them (e.g. a printer or NAS) require static addresses or extra options.
  • the administrator does not want to be bothered with database management.
  • the setup is optimized for minimal-to-zero maintenance.
  • performance is not an issue; hundreds of queries per second are not expected.
  • IPv6 is not used.
  • DNS updates will not be performed by Kea.

The logical setup consists of two hosts, each running a Kea DHCPv4 server and a Control Agent (CA). The server connects with the CA using UNIX sockets. Each DHCPv4+CA acts as one partner of the HA pair.

```
 +-host-1-+       +-host-2-+
 |        |       |        |
 |   CA <===\   /===> CA   |    ===== - HTTP connection
 |   #    |  \ /  |   #    |
 |   #    |   X   |   #    |    ##### - UNIX socket
 |   #    |  / \      #    |
 | DHCPv4 ==/   \== DHCPv4 |
 |        |       |        |
 +--------+       +--------+
```

The CA on host-1 and CA on host-2 both listen on port 8000. The DHCP servers communicate with each other via the CAs, which forward control commands to the DHCP servers over the UNIX domain sockets.

Deployment Considerations

The setup is not expected to be very performant; most modest hardware will do. There are successful deployments on Raspberry Pi platforms. If it is running on a VM, 2GB of RAM with one CPU core should be enough. Ubuntu LTS is a choice that is easy to set up and is low maintenance; however, any Linux or FreeBSD operating system is fine. Less popular systems, such as OpenBSD or NetBSD, should also work in principle, but they are not regularly tested.

The assumption is that there are two hosts that are running the Kea setup:

  • 192.168.1.2 - primary HA server (active, handles all the traffic)
  • 192.168.1.3 - secondary HA server (passive, ready to take over if the primary fails)

The network is 192.168.1.0/24. It is assumed that 192.168.1.1 is the default router.

The whole subnet is split into dynamic and static pools:

  • 192.168.1.100 - 192.168.1.199 - this is the dynamic pool. When new devices appear in the network, they are assigned dynamic addresses from this pool.
  • The reservations are done outside of this dynamic range (depending on the addressing preference, either 192.168.1.1-192.168.1.99 or 192.168.1.200-192.168.1.254).

To deploy this setup, conduct the following steps:

  1. Install CA and DHCPv4 on host-1, and copy the configuration files to their typical locations. They are usually in /etc/kea on Linux and /usr/local/etc/kea on FreeBSD, and the files are typically called kea-ctrl-agent.conf and kea-dhcp4.conf. Please consult the start-up scripts for any specific system.

  2. Alter the following to match the local setup:

    • the interface name that Kea should listen on (interfaces in interfaces-config).
    • the interface name that is used to access the subnet (interface in subnet4).
    • the addressing, if using something other than 192.168.1.0/24. Make sure the CA port configuration (http-host and http-port in kea-ca.conf) matches the DHCPv4 server configuration (url in hook-libraries/parameters/high-availability/peers in kea-dhcp4.conf).
    • the router option, to match the actual network.
    • the DNS option, to match the actual network.
    • the path to the hook libraries. This is a very OS-specific parameter; the library names are generally the same everywhere, but the path varies. See Introduction for details.
  3. If using a firewall, make sure host-1 can reach host-2. An easy way to ensure that is to try to retrieve host-2’s config from host-1:

    curl -X POST -H "Content-Type: application/json" -d '{ "command": "config-get", "service": [ "dhcp4" ] }'  http://192.168.1.3:8000/

    The DHCPv4 running configuration should be returned, in JSON format.

  4. Verify that communication between the hosts works in the opposite direction as well (host-2 can connect to host-1), by repeating step 3 from host-2 using host-1’s IP address and port.

  5. Install the CA and DHCPv4 on host-2, as in steps 1 and 2. The config file for the standby server is very similar to the one on the primary server, other than the definition of the this-server-name field (and possibly the interface names).

Possible Extensions

The proposed configuration is somewhat basic, but functional. Once it is set up and running, administrators may wish to consider the following changes:

  • if there is a local DNS server, DNS updates can be configured via Kea. This requires running a DHCP-DDNS update server (kea-dhcp-ddns). See Overview for details.
  • to run Stateful DHCP for IPv6, a kea-dhcp6 server is necessary. Its configuration is very similar to kea-dhcp4, but there are some notable differences: the default gateway is not configured via the DHCPv6 protocol, but via router advertisements sent by the local router. Also, the DHCPv6 concept of prefix delegation does not exist in DHCPv4. See The DHCPv6 Server for details.
  • to expand the local network, adding a MySQL or PostgreSQL database is a popular solution. Users can choose to store leases, host reservations, and even most of the configuration in a database. See Kea Database Administration and the lease-database, hosts-database, and config-control parameters in The DHCPv4 Server.
  • to provide more insight into how the DHCP server operates, Kea’s RESTful API can query for many runtime statistics or even change the configuration during runtime. Users may also consider deploying Stork, which is a new but quickly developing dashboard for Kea. See Monitoring Kea With Stork for more information.
  • all Kea users should read Kea Security: to learn about various trade-offs between convenience and security in Kea.

Some tweaking of these templates may be required to match specific system needs: at a minimum, the lines highlighted in yellow must be adjusted to match the actual deployment.

Server1’s Control Agent configuration file:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
// This is an example of a configuration for Control-Agent (CA) listening
// for incoming HTTP traffic. This is necessary for handling API commands,
// in particular lease update commands needed for HA setup.
{
    "Control-agent":
    {
        // We need to specify where the agent should listen to incoming HTTP
        // queries.
        "http-host": "192.168.1.2",

        // This specifies the port CA will listen on.
        "http-port": 8000,

        "control-sockets":
        {
            // This is how the Agent can communicate with the DHCPv4 server.
            "dhcp4":
            {
                "comment": "socket to DHCP4 server",
                "socket-type": "unix",
                "socket-name": "/tmp/kea4-ctrl-socket"
            },

            // Location of the DHCPv6 command channel socket.
            "dhcp6":
            {
                "socket-type": "unix",
                "socket-name": "/tmp/kea6-ctrl-socket"
            },

            // Location of the D2 command channel socket.
            "d2":
            {
                "socket-type": "unix",
                "socket-name": "/tmp/kea-ddns-ctrl-socket",
                "user-context": { "in-use": false }
            }
        },


        // Similar to other Kea components, CA also uses logging.
        "loggers": [
            {
                "name": "kea-ctrl-agent",
                "output_options": [
                    {
                        "output": "/var/log/kea-ctrl-agent.log",

                        // Several additional parameters are possible in addition
                        // to the typical output. Flush determines whether logger
                        // flushes output to a file. Maxsize determines maximum
                        // filesize before the file is being rotated. maxver
                        // specifies the maximum number of rotated files being
                        // kept.
                        "flush": true,
                        "maxsize": 204800,
                        "maxver": 4,
                        // We use pattern to specify custom log message layout
                        "pattern": "%d{%y.%m.%d %H:%M:%S.%q} %-5p [%c/%i] %m\n"
                    }
                ],
                "severity": "INFO",
                "debuglevel": 0 // debug level only applies when severity is set to DEBUG.
            }
        ]
    }
}

Server1’s DHCPv4 configuration file:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
// This is an example configuration of the Kea DHCPv4 server 1:
//
// - uses High Availability hooks library and Lease Commands hooks library
//   to enable High Availability function for the DHCP server. This config
//   file is for the primary (the active) server.
// - uses memfile, which stores lease data in a local CSV file
// - it assumes a single /24 addressing over a link that is directly reachable
//   (no DHCP relays)
// - there is a handful of IP reservations
//
// It is expected to run with a standby (the passive) server, which has a very similar
// configuration. The only difference is that "this-server-name" must be set to "server2" on the
// other server. Also, the interface configuration depends on the network settings of the
// particular machine.

{

"Dhcp4": {

    // Add names of your network interfaces to listen on.
    "interfaces-config": {
        // The DHCPv4 server listens on this interface. When changing this to
        // the actual name of your interface, make sure to also update the
        // interface parameter in the subnet definition below.
        "interfaces": [ "enp0s8" ]
    },

    // Control socket is required for communication between the Control
    // Agent and the DHCP server. High Availability requires Control Agent
    // to be running because lease updates are sent over the RESTful
    // API between the HA peers.
    "control-socket": {
        "socket-type": "unix",
        "socket-name": "/tmp/kea4-ctrl-socket"
    },

    // Use Memfile lease database backend to store leases in a CSV file.
    // Depending on how Kea was compiled, it may also support SQL databases
    // (MySQL and/or PostgreSQL) and even Cassandra. Those database backends
    // require more parameters, like name, host and possibly user and password.
    // There are dedicated examples for each backend. See Section 7.2.2 "Lease
    // Storage" for details.
    "lease-database": {
        // Memfile is the simplest and easiest backend to use. It's an in-memory
        // database with data being written to a CSV file. It is very similar to
        // what ISC DHCP does.
        "type": "memfile"
    },

    // Let's configure some global parameters. The home network is not very dynamic
    // and there's no shortage of addresses, so no need to recycle aggressively.
    "valid-lifetime": 43200, // leases will be valid for 12h
    "renew-timer": 21600, // clients should renew every 6h
    "rebind-timer": 32400, // clients should start looking for other servers after 9h

    // Kea will clean up its database of expired leases once per hour. However, it
    // will keep the leases in expired state for 2 days. This greatly increases the
    // chances for returning devices to get the same address again. To guarantee that,
    // use host reservation.
    "expired-leases-processing": {
        "reclaim-timer-wait-time": 3600,
        "hold-reclaimed-time": 172800,
        "max-reclaim-leases": 0,
        "max-reclaim-time": 0
    },

    // HA requires two hooks libraries to be loaded: libdhcp_lease_cmds.so and
    // libdhcp_ha.so. The former handles incoming lease updates from the HA peers.
    // The latter implements high availability feature for Kea. Note the library name
    // should be the same, but the path is OS specific.
    "hooks-libraries": [
        // The lease_cmds library must be loaded because HA makes use of it to
        // deliver lease updates to the server as well as synchronize the
        // lease database after failure.
        {
            "library": "/usr/lib/x86_64-linux-gnu/kea/hooks/libdhcp_lease_cmds.so"
        },

        {
            // The HA hooks library should be loaded.
            "library": "/usr/lib/x86_64-linux-gnu/kea/hooks/libdhcp_ha.so",
            "parameters": {
                // Each server should have the same HA configuration, except for the
                // "this-server-name" parameter.
                "high-availability": [ {
                    // This parameter points to this server instance. The respective
                    // HA peers must have this parameter set to their own names.
                    "this-server-name": "server1",
                    // The HA mode is set to hot-standby. In this mode, the active server handles
                    // all the traffic. The standby takes over if the primary becomes unavailable.
                    "mode": "hot-standby",
                    // Heartbeat is to be sent every 10 seconds if no other control
                    // commands are transmitted.
                    "heartbeat-delay": 10000,
                    // Maximum time for partner's response to a heartbeat, after which
                    // failure detection is started. This is specified in milliseconds.
                    // If we don't hear from the partner in 60 seconds, it's time to
                    // start worrying.
                    "max-response-delay": 60000,
                    // The following parameters control how the server detects the
                    // partner's failure. The ACK delay sets the threshold for the
                    // 'secs' field of the received discovers. This is specified in
                    // milliseconds.
                    "max-ack-delay": 5000,
                    // This specifies the number of clients which send messages to
                    // the partner but appear to not receive any response.
                    "max-unacked-clients": 5,
                    // This specifies the maximum timeout (in milliseconds) for the server
                    // to complete sync. If you have a large deployment (high tens or
                    // hundreds of thousands of clients), you may need to increase it
                    // further. The default value is 60000ms (60 seconds).
                    "sync-timeout": 60000,
                    "peers": [
                        // This is the configuration of this server instance.
                        {
                            "name": "server1",
                            // This specifies the URL of our server instance. The
                            // Control Agent must run along with our DHCPv4 server
                            // instance and the "http-host" and "http-port" must be
                            // set to the corresponding values.
                            "url": "http://192.168.1.2:8000/",
                            // This server is primary. The other one must be
                            // secondary.
                            "role": "primary"
                        },
                        // This is the configuration of our HA peer.
                        {
                            "name": "server2",
                            // Specifies the URL on which the partner's control
                            // channel can be reached. The Control Agent is required
                            // to run on the partner's machine with "http-host" and
                            // "http-port" values set to the corresponding values.
                            "url": "http://192.168.1.3:8000/",
                            // The partner is a secondary. Our is primary.
                            "role": "standby"
                        }
                    ]
                } ]
            }
        }
    ],

    // This example contains a single subnet declaration.
    "subnet4": [
        {
            // Subnet prefix.
            "subnet": "192.168.1.0/24",

            // There are no relays in this network, so we need to tell Kea that this subnet
            // is reachable directly via the specified interface.
            "interface": "enp0s8",

            // Specify a dynamic address pool.
            "pools": [
                {
                    "pool": "192.168.1.100-192.168.1.199"
                }
            ],

            // These are options that are subnet specific. In most cases, you need to define at
            // least routers option, as without this option your clients will not be able to reach
            // their default gateway and will not have Internet connectivity. If you have many
            // subnets and they share the same options (e.g. DNS servers typically is the same
            // everywhere), you may define options at the global scope, so you don't repeat them
            // for every network.
            "option-data": [
                {
                    // For each IPv4 subnet you typically need to specify at least one router.
                    "name": "routers",
                    "data": "192.168.1.1"
                },
                {
                    // Using cloudflare or Quad9 is a reasonable option. Change this
                    // to your own DNS servers is you have them. Another popular
                    // choice is 8.8.8.8, owned by Google. Using third party DNS
                    // service raises some privacy concerns.
                    "name": "domain-name-servers",
                    "data": "1.1.1.1,9.9.9.9"
                }
            ],

            // Some devices should get a static address. Since the .100 - .199 range is dynamic,
            // let's use the lower address space for this. There are many ways how reservation
            // can be defined, but using MAC address (hw-address) is by far the most popular one.
            // You can use client-id, duid and even custom defined flex-id that may use whatever
            // parts of the packet you want to use as identifiers. Also, there are many more things
            // you can specify in addition to just an IP address: extra options, next-server, hostname,
            // assign device to client classes etc. See the Kea ARM, Section 8.3 for details.
            // The reservations are subnet specific.
            "reservations": [
                {
                    "hw-address": "1a:1b:1c:1d:1e:1f",
                    "ip-address": "192.168.1.10"
                },
                {
                    "client-id": "01:11:22:33:44:55:66",
                    "ip-address": "192.168.1.11"
                }
            ]
        }
    ],

    // Logging configuration starts here.
    "loggers": [
    {
        // This section affects kea-dhcp4, which is the base logger for DHCPv4 component. It tells
        // DHCPv4 server to write all log messages (on severity INFO or higher) to a file. The file
        // will be rotated once it grows to 2MB and up to 4 files will be kept. The debuglevel
        // (range 0 to 99) is used only when logging on DEBUG level.
        "name": "kea-dhcp4",
        "output_options": [
            {
                "output": "/var/log/kea-dhcp4.log",
                "maxsize": 2048000,
                "maxver": 4
            }
        ],
        "severity": "INFO",
        "debuglevel": 0
    }
  ]
}
}

Server2’s Control Agent configuration file:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
// This is an example of a configuration for Control-Agent (CA) listening
// for incoming HTTP traffic. This is necessary for handling API commands,
// in particular lease update commands needed for HA setup.
{
    "Control-agent":
    {
        // We need to specify where the agent should listen to incoming HTTP
        // queries.
        "http-host": "192.168.1.3",

        // This specifies the port CA will listen on.
        "http-port": 8000,

        "control-sockets":
        {
            // This is how the Agent can communicate with the DHCPv4 server.
            "dhcp4":
            {
                "comment": "socket to DHCP4 server",
                "socket-type": "unix",
                "socket-name": "/tmp/kea4-ctrl-socket"
            },

            // Location of the DHCPv6 command channel socket.
            "dhcp6":
            {
                "socket-type": "unix",
                "socket-name": "/tmp/kea6-ctrl-socket"
            },

            // Location of the D2 command channel socket.
            "d2":
            {
                "socket-type": "unix",
                "socket-name": "/tmp/kea-ddns-ctrl-socket",
                "user-context": { "in-use": false }
            }
        },


        // Similar to other Kea components, CA also uses logging.
        "loggers": [
            {
                "name": "kea-ctrl-agent",
                "output_options": [
                    {
                        "output": "/var/log/kea-ctrl-agent.log",

                        // Several additional parameters are possible in addition
                        // to the typical output. Flush determines whether logger
                        // flushes output to a file. Maxsize determines maximum
                        // filesize before the file is being rotated. maxver
                        // specifies the maximum number of rotated files being
                        // kept.
                        "flush": true,
                        "maxsize": 204800,
                        "maxver": 4,
                        // We use pattern to specify custom log message layout
                        "pattern": "%d{%y.%m.%d %H:%M:%S.%q} %-5p [%c/%i] %m\n"
                    }
                ],
                "severity": "INFO",
                "debuglevel": 0 // debug level only applies when severity is set to DEBUG.
            }
        ]
    }
}

Server2’s DHCPv4 configuration file:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
// This is an example configuration of the Kea DHCPv4 server 2:
//
// - uses High Availability hooks library and Lease Commands hooks library
//   to enable High Availability function for the DHCP server. This config
//   file is for the primary (the active) server.
// - uses memfile, which stores lease data in a local CSV file
// - it assumes a single /24 addressing over a link that is directly reachable
//   (no DHCP relays)
// - there is a handful of IP reservations
//
// It is expected to run with a primary (the active) server, which has a very similar
// configuration. The only difference is that "this-server-name" must be set to "server2" on the
// other server. Also, the interface configuration depends on the network settings of the
// particular machine.

{

"Dhcp4": {

    // Add names of your network interfaces to listen on.
    "interfaces-config": {
        // The DHCPv4 server listens on this interface. When changing this to
        // the actual name of your interface, make sure to also update the
        // interface parameter in the subnet definition below.
        "interfaces": [ "enp0s8" ]
    },

    // Control socket is required for communication between the Control
    // Agent and the DHCP server. High Availability requires Control Agent
    // to be running because lease updates are sent over the RESTful
    // API between the HA peers.
    "control-socket": {
        "socket-type": "unix",
        "socket-name": "/tmp/kea4-ctrl-socket"
    },

    // Use Memfile lease database backend to store leases in a CSV file.
    // Depending on how Kea was compiled, it may also support SQL databases
    // (MySQL and/or PostgreSQL) and even Cassandra. Those database backends
    // require more parameters, like name, host and possibly user and password.
    // There are dedicated examples for each backend. See Section 7.2.2 "Lease
    // Storage" for details.
    "lease-database": {
        // Memfile is the simplest and easiest backend to use. It's an in-memory
        // database with data being written to a CSV file. It is very similar to
        // what ISC DHCP does.
        "type": "memfile"
    },

    // Let's configure some global parameters. The home network is not very dynamic
    // and there's no shortage of addresses, so no need to recycle aggressively.
    "valid-lifetime": 43200, // leases will be valid for 12h
    "renew-timer": 21600, // clients should renew every 6h
    "rebind-timer": 32400, // clients should start looking for other servers after 9h

    // Kea will clean up its database of expired leases once per hour. However, it
    // will keep the leases in expired state for 2 days. This greatly increases the
    // chances for returning devices to get the same address again. To guarantee that,
    // use host reservation.
    "expired-leases-processing": {
        "reclaim-timer-wait-time": 3600,
        "hold-reclaimed-time": 172800,
        "max-reclaim-leases": 0,
        "max-reclaim-time": 0
    },

    // HA requires two hooks libraries to be loaded: libdhcp_lease_cmds.so and
    // libdhcp_ha.so. The former handles incoming lease updates from the HA peers.
    // The latter implements high availability feature for Kea. Note the library name
    // should be the same, but the path is OS specific.
    "hooks-libraries": [
        // The lease_cmds library must be loaded because HA makes use of it to
        // deliver lease updates to the server as well as synchronize the
        // lease database after failure.
        {
            "library": "/usr/lib/x86_64-linux-gnu/kea/hooks/libdhcp_lease_cmds.so"
        },

        {
            // The HA hooks library should be loaded.
            "library": "/usr/lib/x86_64-linux-gnu/kea/hooks/libdhcp_ha.so",
            "parameters": {
                // Each server should have the same HA configuration, except for the
                // "this-server-name" parameter.
                "high-availability": [ {
                    // This parameter points to this server instance. The respective
                    // HA peers must have this parameter set to their own names.
                    "this-server-name": "server2",
                    // The HA mode is set to hot-standby. In this mode, the active server handles
                    // all the traffic. The standby takes over if the primary becomes unavailable.
                    "mode": "hot-standby",
                    // Heartbeat is to be sent every 10 seconds if no other control
                    // commands are transmitted.
                    "heartbeat-delay": 10000,
                    // Maximum time for partner's response to a heartbeat, after which
                    // failure detection is started. This is specified in milliseconds.
                    // If we don't hear from the partner in 60 seconds, it's time to
                    // start worrying.
                    "max-response-delay": 60000,
                    // The following parameters control how the server detects the
                    // partner's failure. The ACK delay sets the threshold for the
                    // 'secs' field of the received discovers. This is specified in
                    // milliseconds.
                    "max-ack-delay": 5000,
                    // This specifies the number of clients which send messages to
                    // the partner but appear to not receive any response.
                    "max-unacked-clients": 5,
                    // This specifies the maximum timeout (in milliseconds) for the server
                    // to complete sync. If you have a large deployment (high tens or
                    // hundreds of thousands of clients), you may need to increase it
                    // further. The default value is 60000ms (60 seconds).
                    "sync-timeout": 60000,
                    "peers": [
                        // This is the configuration of this server instance.
                        {
                            "name": "server1",
                            // This specifies the URL of the partner's server instance. The
                            // Control Agent must run along with partner DHCPv4 server
                            // instance and the "http-host" and "http-port" must be
                            // set to the corresponding values.
                            "url": "http://192.168.1.2:8000/",
                            // That server is primary. Our server must be
                            // standby.
                            "role": "primary"
                        },
                        // This is our (server2) configuration.
                        {
                            "name": "server2",
                            // Specifies the URL on which the control agent for this server
                            // can be reached. The Control Agent is required
                            // to run on this machine with "http-host" and
                            // "http-port" values set to the corresponding values.
                            "url": "http://192.168.1.3:8000/",
                            // Our server is standby. The other server is primary.
                            "role": "standby"
                        }
                    ]
                } ]
            }
        }
    ],

    // This example contains a single subnet declaration.
    "subnet4": [
        {
            // Subnet prefix.
            "subnet": "192.168.1.0/24",

            // There are no relays in this network, so we need to tell Kea that this subnet
            // is reachable directly via the ethX interface.
            "interface": "enp0s8",

            // Specify a dynamic address pool.
            "pools": [
                {
                    "pool": "192.168.1.100-192.168.1.199"
                }
            ],

            // These are options that are subnet specific. In most cases, you need to define at
            // least routers option, as without this option your clients will not be able to reach
            // their default gateway and will not have Internet connectivity. If you have many
            // subnets and they share the same options (e.g. DNS servers typically is the same
            // everywhere), you may define options at the global scope, so you don't repeat them
            // for every network.
            "option-data": [
                {
                    // For each IPv4 subnet you typically need to specify at least one router.
                    "name": "routers",
                    "data": "192.168.1.1"
                },
                {
                    // Using cloudflare or Quad9 is a reasonable option. Change this
                    // to your own DNS servers is you have them. Another popular
                    // choice is 8.8.8.8, owned by Google. Using third party DNS
                    // service raises some privacy concerns.
                    "name": "domain-name-servers",
                    "data": "1.1.1.1,9.9.9.9"
                }
            ],

            // Some devices should get a static address. Since the .100 - .199 range is dynamic,
            // let's use the lower address space for this. There are many ways how reservation
            // can be defined, but using MAC address (hw-address) is by far the most popular one.
            // You can use client-id, duid and even custom defined flex-id that may use whatever
            // parts of the packet you want to use as identifiers. Also, there are many more things
            // you can specify in addition to just an IP address: extra options, next-server, hostname,
            // assign device to client classes etc. See the Kea ARM, Section 8.3 for details.
            // The reservations are subnet specific.
            "reservations": [
                {
                    "hw-address": "1a:1b:1c:1d:1e:1f",
                    "ip-address": "192.168.1.10"
                },
                {
                    "client-id": "01:11:22:33:44:55:66",
                    "ip-address": "192.168.1.11"
                }
            ]
        }
    ],

    // Logging configuration starts here.
    "loggers": [
    {
        // This section affects kea-dhcp4, which is the base logger for DHCPv4 component. It tells
        // DHCPv4 server to write all log messages (on severity INFO or higher) to a file. The file
        // will be rotated once it grows to 2MB and up to 4 files will be kept. The debuglevel
        // (range 0 to 99) is used only when logging on DEBUG level.
        "name": "kea-dhcp4",
        "output_options": [
            {
                "output": "/var/log/kea-dhcp4.log",
                "maxsize": 2048000,
                "maxver": 4
            }
        ],
        "severity": "INFO",
        "debuglevel": 0
    }
  ]
}
}