Feature #15321
closedKea DHCP Custom Configuration Support (IPv4 and IPv6)
Added by Alhusein Zawi about 1 year ago. Updated 15 days ago.
100%
Description
adding customs options to KEA DHCP
Files
sample-kea-option-def.json (344 Bytes) sample-kea-option-def.json | Dale Harron, 10/03/2024 07:41 PM | ||
clipboard-202502201540-szemp.png (187 KB) clipboard-202502201540-szemp.png | Christian McDonald, 02/20/2025 08:40 PM | ||
clipboard-202502201555-ivjrc.png (71.1 KB) clipboard-202502201555-ivjrc.png | Christian McDonald, 02/20/2025 08:55 PM |
Related issues
Updated by Lev Prokofev 11 months ago
Below is an example of possible options with the right syntax:
https://github.com/isc-projects/kea/blob/master/doc/examples/kea4/all-options.json
Updated by Jim Pingle 9 months ago
- Subject changed from KEA DHCP custom options to Kea DHCP Custom Options Support (IPv4 and IPv6)
- Parent task set to #15650
Updated by Marcos M 7 months ago
I'm providing a patch here to experiment with custom options for DHCP4; no support will be provided for this. ShowHide
diff --git a/src/etc/inc/services.inc b/src/etc/inc/services.inc index 62cbcd4e40..48c90ee690 100644 --- a/src/etc/inc/services.inc +++ b/src/etc/inc/services.inc @@ -1221,6 +1221,22 @@ function services_kea4_configure() { $dhcpdcfg = config_get_path('dhcpd'); $Iflist = get_configured_interface_list(); + /* custom options */ + $kea_custom_options_set = false; + $kea_custom_options_config = config_get_path('kea/custom_options_patch'); + if (!empty($kea_custom_options_config)) { + $kea_custom_options_config = base64_decode($kea_custom_options_config); + if (is_string($kea_custom_options_config)) { + $kea_custom_options_set = true; + } + } + if ($kea_custom_options_set) { + $kea_custom_options_config = json_decode($kea_custom_options_config, true); + if (empty($kea_custom_options_config) || !is_array($kea_custom_options_config)) { + $kea_custom_options_set = false; + } + } + /* configuration is built as a PHP array and converted to json */ $keaconf = []; $keaconf['Dhcp4'] = [ @@ -1265,6 +1281,13 @@ function services_kea4_configure() { ], ]; + /* custom option definitions */ + if ($kea_custom_options_set) { + foreach ($kea_custom_options_config['option-def'] as $option_def) { + $keaconf['Dhcp4']['option-def'][] = $option_def; + } + } + /* See https://redmine.pfsense.org/issues/15328 */ $keaconf['Dhcp4']['sanity-checks'] = [ 'lease-checks' => 'fix-del' @@ -1504,6 +1527,16 @@ function services_kea4_configure() { $all_pools = array_merge($all_pools, $dhcpifconf['pool']); } + /* custom option data */ + if ($kea_custom_options_set) { + foreach (array_get_path($kea_custom_options_config, "option-data/all", []) as $custom_option_data) { + $keasubnet['option-data'][] = $custom_option_data; + } + foreach (array_get_path($kea_custom_options_config, "option-data/{$dhcpif}", []) as $custom_option_data) { + $keasubnet['option-data'][] = $custom_option_data; + } + } + if ($dhcpifconf['domain']) { $keasubnet['option-data'][] = [ 'name' => 'domain-name', diff --git a/src/usr/local/www/services_dhcp_settings.php b/src/usr/local/www/services_dhcp_settings.php index b219460f5c..aa5f352363 100644 --- a/src/usr/local/www/services_dhcp_settings.php +++ b/src/usr/local/www/services_dhcp_settings.php @@ -61,6 +61,21 @@ if ($_POST['apply']) { } elseif ($_POST['act']) { switch($_POST['act']) { case 'save': + /* custom options config */ + if (!empty($_POST['custom_options_patch'])) { + $temp_data = json_decode($_POST['custom_options_patch'], true); + if (is_array($temp_data) && !empty($temp_data)) { + array_set_path($pconfig, 'custom_options_patch', base64_encode($_POST['custom_options_patch'])); + config_set_path('kea/custom_options_patch', base64_encode($_POST['custom_options_patch'])); + write_config("DHCP Server - added custom options"); + mark_subsystem_dirty('dhcpd'); + } + } elseif (config_get_path('kea/custom_options_patch') !== null) { + array_del_path($pconfig, 'custom_options_patch'); + config_del_path('kea/custom_options_patch'); + write_config("DHCP Server - removed custom options"); + mark_subsystem_dirty('dhcpd'); + } [$input_errors, $pconfig] = dhcp_do_settings_post($subnets); $subnets = kea_build_subnet_list(); /* refresh subnet list */ break; @@ -342,6 +357,15 @@ $section->addInput(new Form_Select( $form->add($section); +/* custom options input */ +$section = new Form_Section(gettext('Custom Options')); +$section->addInput(new Form_Textarea( + 'custom_options_patch', + 'JSON Data', + ((array_get_path($pconfig, 'custom_options_patch') !== null) ? base64_decode($pconfig['custom_options_patch']) : null) +)); +$form->add($section); + $form->addGlobal(new Form_Input( 'act', '',
Apply it with the System Patches package, then go to Services > DHCP Server > Settings
, enter the JSON-formatted custom option data, then Save/Apply.
The custom option needs to be defined once and applied per interface. Here's an example that adds a vendor option (43) to the opt1 interface (get the name from Status > Interfaces
):
ShowHide
{ "option-def": [ { "space": "dhcp4", "name": "custom-option-vendor", "code": 43, "type": "string" } ], "option-data": { "opt1": [ { "name": "custom-option-vendor", "data": "01:04:0a:01:01:01" } ] } }
Updated by Dale Harron 7 months ago
After a lot of experimentation and help from Marcos, I discovered it is important to know if the option is already defined or not. For that go to https://kea.readthedocs.io/en/kea-2.2.0/arm/dhcp4-srv.html#known-rfc-violations.
Look up the option and if it is already defined do not include the option-def portion because it is already defined.
"option-def": [
{
"space": "dhcp4",
"name": "custom-option-vendor",
"code": 43,
"type": "string"
}
],
If you wish to define the same option on multiple interfaces, simply cascade them with a comma, so the JSON sample now becomes (option 114 as an example):
{
"option-data": {
"opt4": [
{
"name": "v4-captive-portal",
"data": “https://sub4.domain.com:8007/rfc8910.php?zone=vlan30”
}
],
"opt5": [
{
"name": "v4-captive-portal",
"data": “https://sub5.domain.com:8009/rfc8910.php?zone=vlan40”
}
]
}
}
Updated by Jim Pingle 7 months ago
- Has duplicate Feature #13422: Add a 'type' field to the DHCPv6 server Additional BOOTP/DHCP Options added
Updated by Gertjan KROEB 5 months ago
I'm test driving this right now.
pfSense 24.11 Release.
With the patch mentioned above.
See also : [[https://forum.netgate.com/topic/190373/feature-15321-shows-how-to-use-option-114-in-kea/4]]
Updated by Dale Harron 2 months ago
This modification to the patch for Plus release 25.03 Beta is working for me:
diff --git a/src/etc/inc/services.inc b/src/etc/inc/services.inc index 62cbcd4e40..48c90ee690 100644 --- a/src/etc/inc/services.inc +++ b/src/etc/inc/services.inc @@ -1221,6 +1221,22 @@ function services_kea4_configure() { $dhcpdcfg = config_get_path('dhcpd'); $Iflist = get_configured_interface_list(); + /* custom options */ + $kea_custom_options_set = false; + $kea_custom_options_config = config_get_path('kea/custom_options_patch'); + if (!empty($kea_custom_options_config)) { + $kea_custom_options_config = base64_decode($kea_custom_options_config); + if (is_string($kea_custom_options_config)) { + $kea_custom_options_set = true; + } + } + if ($kea_custom_options_set) { + $kea_custom_options_config = json_decode($kea_custom_options_config, true); + if (empty($kea_custom_options_config) || !is_array($kea_custom_options_config)) { + $kea_custom_options_set = false; + } + } + /* configuration is built as a PHP array and converted to json */ $keaconf = []; $keaconf['Dhcp4'] = [ @@ -1265,6 +1281,13 @@ function services_kea4_configure() { ], ]; + /* custom option definitions */ + if ($kea_custom_options_set) { + foreach ($kea_custom_options_config['option-def'] as $option_def) { + $keaconf['Dhcp4']['option-def'][] = $option_def; + } + } + /* See https://redmine.pfsense.org/issues/15328 */ $keaconf['Dhcp4']['sanity-checks'] = [ 'lease-checks' => 'fix-del' @@ -1504,6 +1527,16 @@ function services_kea4_configure() { $all_pools = array_merge($all_pools, $dhcpifconf['pool']); } + /* custom option data */ + if ($kea_custom_options_set) { + foreach (array_get_path($kea_custom_options_config, "option-data/all", []) as $custom_option_data) { + $keasubnet['option-data'][] = $custom_option_data; + } + foreach (array_get_path($kea_custom_options_config, "option-data/{$dhcpif}", []) as $custom_option_data) { + $keasubnet['option-data'][] = $custom_option_data; + } + } + if ($dhcpifconf['domain']) { $keasubnet['option-data'][] = [ 'name' => 'domain-name', diff --git a/src/usr/local/www/services_dhcp_settings.php b/src/usr/local/www/services_dhcp_settings.php index b219460f5c..aa5f352363 100644 --- a/src/usr/local/www/services_dhcp_settings.php +++ b/src/usr/local/www/services_dhcp_settings.php @@ -59,6 +59,21 @@ if ($_POST['apply']) { } elseif ($_POST['act']) { switch($_POST['act']) { case 'save': + /* custom options config */ + if (!empty($_POST['custom_options_patch'])) { + $temp_data = json_decode($_POST['custom_options_patch'], true); + if (is_array($temp_data) && !empty($temp_data)) { + array_set_path($pconfig, 'custom_options_patch', base64_encode($_POST['custom_options_patch'])); + config_set_path('kea/custom_options_patch', base64_encode($_POST['custom_options_patch'])); + write_config("DHCP Server - added custom options"); + mark_subsystem_dirty('dhcpd'); + } + } elseif (config_get_path('kea/custom_options_patch') !== null) { + array_del_path($pconfig, 'custom_options_patch'); + config_del_path('kea/custom_options_patch'); + write_config("DHCP Server - removed custom options"); + mark_subsystem_dirty('dhcpd'); + } [$input_errors, $pconfig] = dhcp_do_settings_post(); break; default: @@ -342,6 +357,15 @@ $section->addInput(new Form_Select( $form->add($section); +/* custom options input */ +$section = new Form_Section(gettext('Custom Options')); +$section->addInput(new Form_Textarea( + 'custom_options_patch', + 'JSON Data', + ((array_get_path($pconfig, 'custom_options_patch') !== null) ? base64_decode($pconfig['custom_options_patch']) : null) +)); +$form->add($section); + $form->addGlobal(new Form_Input( 'act', '',
Updated by Christian McDonald 2 months ago
- Status changed from New to In Progress
- Assignee set to Christian McDonald
Updated by Christian McDonald 2 months ago
- Status changed from In Progress to Feedback
- Plus Target Version set to 25.03
Updated by Christian McDonald 2 months ago
- File clipboard-202502201540-szemp.png clipboard-202502201540-szemp.png added
- File clipboard-202502201555-ivjrc.png clipboard-202502201555-ivjrc.png added
- Subject changed from Kea DHCP Custom Options Support (IPv4 and IPv6) to Kea DHCP Custom Configuration Support (IPv4 and IPv6)
The subject of this issue has been reworded to more accurately reflect the current direction we are taking with the final push for Kea feature parity.
Because we can't possibly cover all possible use-cases within the limitations of the legacy, PHP user interface, we have added text areas on each DHCP page where arbitrary Kea JSON config snippets can be inserted.
These snippets are stored in the config.xml (and so are backed up) and merge into the final Kea config after we render the base config. This can be used both to add new bits of config but also to modify the base config if needed.
This will also allow us to more easily test and experiment with more advanced Kea options and tuneables without having to rely on patching system files.
In order to limit the opportunity for footgun, we now lint/test the final config before attempting to start Kea. If this fails, we file a notice alerting the operator and then fallback to start Kea without the custom configuration bits.
Here is an example of defining a custom option and then configuring this option on an interface (or "subnet" in Kea parlance).
Updated by Mike Moore 2 months ago
I can already forsee the numerous support posts. Are we relying on the user to correctly identify the spacing issues that will come up? Is there really no way to offer the dhcp options text boxes and then have pfsense format it correctly in json?
Updated by Christian McDonald 2 months ago
No doubt
But what it does do is provide the flexibility now for people that really need it while we take the next steps in removing DHCPD from the base.
There is a tremendous amount of tech debt and overhead trying to make both DHCPs available as options in pfSense. Once we can shed DHCPD for good, we can more cleanly and clearly do the right thing and give Kea the UI it really wants, and the DHCP UI in pfSense today fundamentally isn't it.
Check out ISC Stork for the reference Kea GUI. It's hot. That's where we want to be. This solution here will help get us there. We've recycled what we can from the old UI but we need a transitional UI to help get us to the next phase.
Updated by Marcos M 2 months ago
I've created a quick-start guide for this on the forum:
https://forum.netgate.com/topic/196513
Updated by Jim Pingle 15 days ago
- Related to Feature #15650: Kea Feature Integration for parity with ISC DHCP added