From f90f16fc09a720847e1b6f2908f1e5bba31159eb Mon Sep 17 00:00:00 2001 From: Ad Schellevis Date: Tue, 17 Oct 2023 20:59:58 +0200 Subject: [PATCH] Kea / Dhcp - DHCPv4 replacement, initial minimal for https://github.com/opnsense/core/issues/6971 This commit contains the basic features of our new DHCPv4 server, it certainly needs additional testing as currently we only validated the configuration format is valid. The aim is to keep the json templates as simple as possible. For now we keep the kea-control-agent disabled, we probably need it later, but we don't want to expose a listener without using it. --- plist | 20 +++ src/etc/inc/plugins.inc.d/kea.inc | 50 ++++++ .../OPNsense/Kea/Api/Dhcpv4Controller.php | 100 ++++++++++++ .../OPNsense/Kea/Api/ServiceController.php | 45 ++++++ .../OPNsense/Kea/DhcpController.php | 40 +++++ .../OPNsense/Kea/forms/dialogReservation.xml | 26 ++++ .../OPNsense/Kea/forms/dialogSubnet.xml | 50 ++++++ .../OPNsense/Kea/forms/generalSettings.xml | 20 +++ .../mvc/app/models/OPNsense/Kea/ACL/ACL.xml | 10 ++ .../OPNsense/Kea/FieldTypes/KeaPoolsField.php | 66 ++++++++ .../mvc/app/models/OPNsense/Kea/KeaDhcpv4.php | 37 +++++ .../mvc/app/models/OPNsense/Kea/KeaDhcpv4.xml | 81 ++++++++++ .../mvc/app/models/OPNsense/Kea/Menu/Menu.xml | 8 + .../mvc/app/views/OPNsense/Kea/dhcpv4.volt | 145 ++++++++++++++++++ .../service/conf/actions.d/actions_kea.conf | 24 +++ .../service/templates/OPNsense/Kea/+TARGETS | 4 + .../OPNsense/Kea/kea-ctrl-agent.conf | 105 +++++++++++++ .../templates/OPNsense/Kea/kea-dhcp4.conf | 64 ++++++++ .../templates/OPNsense/Kea/keactrl.conf | 46 ++++++ .../service/templates/OPNsense/Kea/rc.conf.d | 5 + .../templates/OPNsense/Syslog/local/kea.conf | 6 + 21 files changed, 952 insertions(+) create mode 100644 src/etc/inc/plugins.inc.d/kea.inc create mode 100644 src/opnsense/mvc/app/controllers/OPNsense/Kea/Api/Dhcpv4Controller.php create mode 100644 src/opnsense/mvc/app/controllers/OPNsense/Kea/Api/ServiceController.php create mode 100644 src/opnsense/mvc/app/controllers/OPNsense/Kea/DhcpController.php create mode 100644 src/opnsense/mvc/app/controllers/OPNsense/Kea/forms/dialogReservation.xml create mode 100644 src/opnsense/mvc/app/controllers/OPNsense/Kea/forms/dialogSubnet.xml create mode 100644 src/opnsense/mvc/app/controllers/OPNsense/Kea/forms/generalSettings.xml create mode 100644 src/opnsense/mvc/app/models/OPNsense/Kea/ACL/ACL.xml create mode 100644 src/opnsense/mvc/app/models/OPNsense/Kea/FieldTypes/KeaPoolsField.php create mode 100644 src/opnsense/mvc/app/models/OPNsense/Kea/KeaDhcpv4.php create mode 100644 src/opnsense/mvc/app/models/OPNsense/Kea/KeaDhcpv4.xml create mode 100644 src/opnsense/mvc/app/models/OPNsense/Kea/Menu/Menu.xml create mode 100644 src/opnsense/mvc/app/views/OPNsense/Kea/dhcpv4.volt create mode 100644 src/opnsense/service/conf/actions.d/actions_kea.conf create mode 100644 src/opnsense/service/templates/OPNsense/Kea/+TARGETS create mode 100644 src/opnsense/service/templates/OPNsense/Kea/kea-ctrl-agent.conf create mode 100644 src/opnsense/service/templates/OPNsense/Kea/kea-dhcp4.conf create mode 100644 src/opnsense/service/templates/OPNsense/Kea/keactrl.conf create mode 100644 src/opnsense/service/templates/OPNsense/Kea/rc.conf.d create mode 100644 src/opnsense/service/templates/OPNsense/Syslog/local/kea.conf diff --git a/plist b/plist index 417de6b18..21406747e 100644 --- a/plist +++ b/plist @@ -25,6 +25,7 @@ /usr/local/etc/inc/plugins.inc.d/dpinger.inc /usr/local/etc/inc/plugins.inc.d/ipfw.inc /usr/local/etc/inc/plugins.inc.d/ipsec.inc +/usr/local/etc/inc/plugins.inc.d/kea.inc /usr/local/etc/inc/plugins.inc.d/loopback.inc /usr/local/etc/inc/plugins.inc.d/monit.inc /usr/local/etc/inc/plugins.inc.d/netflow.inc @@ -401,6 +402,12 @@ /usr/local/opnsense/mvc/app/controllers/OPNsense/Interfaces/forms/dialogVip.xml /usr/local/opnsense/mvc/app/controllers/OPNsense/Interfaces/forms/dialogVlan.xml /usr/local/opnsense/mvc/app/controllers/OPNsense/Interfaces/forms/dialogVxlan.xml +/usr/local/opnsense/mvc/app/controllers/OPNsense/Kea/Api/Dhcpv4Controller.php +/usr/local/opnsense/mvc/app/controllers/OPNsense/Kea/Api/ServiceController.php +/usr/local/opnsense/mvc/app/controllers/OPNsense/Kea/DhcpController.php +/usr/local/opnsense/mvc/app/controllers/OPNsense/Kea/forms/dialogReservation.xml +/usr/local/opnsense/mvc/app/controllers/OPNsense/Kea/forms/dialogSubnet.xml +/usr/local/opnsense/mvc/app/controllers/OPNsense/Kea/forms/generalSettings.xml /usr/local/opnsense/mvc/app/controllers/OPNsense/Monit/Api/ServiceController.php /usr/local/opnsense/mvc/app/controllers/OPNsense/Monit/Api/SettingsController.php /usr/local/opnsense/mvc/app/controllers/OPNsense/Monit/Api/StatusController.php @@ -699,6 +706,11 @@ /usr/local/opnsense/mvc/app/models/OPNsense/Interfaces/Vlan.xml /usr/local/opnsense/mvc/app/models/OPNsense/Interfaces/VxLan.php /usr/local/opnsense/mvc/app/models/OPNsense/Interfaces/VxLan.xml +/usr/local/opnsense/mvc/app/models/OPNsense/Kea/ACL/ACL.xml +/usr/local/opnsense/mvc/app/models/OPNsense/Kea/FieldTypes/KeaPoolsField.php +/usr/local/opnsense/mvc/app/models/OPNsense/Kea/KeaDhcpv4.php +/usr/local/opnsense/mvc/app/models/OPNsense/Kea/KeaDhcpv4.xml +/usr/local/opnsense/mvc/app/models/OPNsense/Kea/Menu/Menu.xml /usr/local/opnsense/mvc/app/models/OPNsense/Monit/ACL/ACL.xml /usr/local/opnsense/mvc/app/models/OPNsense/Monit/Menu/Menu.xml /usr/local/opnsense/mvc/app/models/OPNsense/Monit/Migrations/M1_0_0.php @@ -813,6 +825,7 @@ /usr/local/opnsense/mvc/app/views/OPNsense/Interface/vip.volt /usr/local/opnsense/mvc/app/views/OPNsense/Interface/vlan.volt /usr/local/opnsense/mvc/app/views/OPNsense/Interface/vxlan.volt +/usr/local/opnsense/mvc/app/views/OPNsense/Kea/dhcpv4.volt /usr/local/opnsense/mvc/app/views/OPNsense/Monit/index.volt /usr/local/opnsense/mvc/app/views/OPNsense/Monit/status.volt /usr/local/opnsense/mvc/app/views/OPNsense/OpenVPN/cso.volt @@ -1139,6 +1152,7 @@ /usr/local/opnsense/service/conf/actions.d/actions_interface.conf /usr/local/opnsense/service/conf/actions.d/actions_ipfw.conf /usr/local/opnsense/service/conf/actions.d/actions_ipsec.conf +/usr/local/opnsense/service/conf/actions.d/actions_kea.conf /usr/local/opnsense/service/conf/actions.d/actions_monit.conf /usr/local/opnsense/service/conf/actions.d/actions_netflow.conf /usr/local/opnsense/service/conf/actions.d/actions_openssh.conf @@ -1204,6 +1218,11 @@ /usr/local/opnsense/service/templates/OPNsense/IPFW/rules.macro /usr/local/opnsense/service/templates/OPNsense/IPsec/+TARGETS /usr/local/opnsense/service/templates/OPNsense/IPsec/reqid_events.conf +/usr/local/opnsense/service/templates/OPNsense/Kea/+TARGETS +/usr/local/opnsense/service/templates/OPNsense/Kea/kea-ctrl-agent.conf +/usr/local/opnsense/service/templates/OPNsense/Kea/kea-dhcp4.conf +/usr/local/opnsense/service/templates/OPNsense/Kea/keactrl.conf +/usr/local/opnsense/service/templates/OPNsense/Kea/rc.conf.d /usr/local/opnsense/service/templates/OPNsense/Macros/interface.macro /usr/local/opnsense/service/templates/OPNsense/Monit/+TARGETS /usr/local/opnsense/service/templates/OPNsense/Monit/monitrc @@ -1250,6 +1269,7 @@ /usr/local/opnsense/service/templates/OPNsense/Syslog/local/firewall.conf /usr/local/opnsense/service/templates/OPNsense/Syslog/local/gateways.conf /usr/local/opnsense/service/templates/OPNsense/Syslog/local/ipsec.conf +/usr/local/opnsense/service/templates/OPNsense/Syslog/local/kea.conf /usr/local/opnsense/service/templates/OPNsense/Syslog/local/lighttpd.conf /usr/local/opnsense/service/templates/OPNsense/Syslog/local/monit.conf /usr/local/opnsense/service/templates/OPNsense/Syslog/local/ntpd.conf diff --git a/src/etc/inc/plugins.inc.d/kea.inc b/src/etc/inc/plugins.inc.d/kea.inc new file mode 100644 index 000000000..349f15100 --- /dev/null +++ b/src/etc/inc/plugins.inc.d/kea.inc @@ -0,0 +1,50 @@ + gettext('KEA DHCPv4 server'), + 'pidfile' => '/var/run/kea/kea-dhcp4.kea-dhcp4.pid', + 'configd' => [ + 'restart' => ['kea restart'], + 'start' => ['kea start'], + 'stop' => ['kea stop'], + ], + 'name' => 'kea-dhcpv4', + ]; + return $services; +} + + +function kea_syslog() +{ + $logfacilities = []; + $logfacilities['kea'] = ['facility' => ['kea-dhcp4', 'kea-dhcp6', 'kea-ctrl-agent']]; + return $logfacilities; +} diff --git a/src/opnsense/mvc/app/controllers/OPNsense/Kea/Api/Dhcpv4Controller.php b/src/opnsense/mvc/app/controllers/OPNsense/Kea/Api/Dhcpv4Controller.php new file mode 100644 index 000000000..47cd2a3ac --- /dev/null +++ b/src/opnsense/mvc/app/controllers/OPNsense/Kea/Api/Dhcpv4Controller.php @@ -0,0 +1,100 @@ + [ + 'general' => $data[self::$internalModelName]['general'] + ] + ]; + } + + public function searchSubnetAction() + { + return $this->searchBase("subnets.subnet4", ['subnet'], "subnet"); + } + + public function setSubnetAction($uuid) + { + return $this->setBase("subnet4", "subnets.subnet4", $uuid); + } + + public function addSubnetAction() + { + return $this->addBase("subnet4", "subnets.subnet4"); + } + + public function getSubnetAction($uuid = null) + { + return $this->getBase("subnet4", "subnets.subnet4", $uuid); + } + + public function delSubnetAction($uuid) + { + return $this->delBase("subnets.subnet4", $uuid); + } + + public function searchReservationAction() + { + return $this->searchBase("reservations.reservation", ['subnet', 'hw_address', 'description'], "hw_address"); + } + + public function setReservationAction($uuid) + { + return $this->setBase("reservation", "reservations.reservation", $uuid); + } + + public function addReservationAction() + { + return $this->addBase("reservation", "reservations.reservation"); + } + + public function getReservationAction($uuid = null) + { + return $this->getBase("reservation", "reservations.reservation", $uuid); + } + + public function delReservationAction($uuid) + { + return $this->delBase("reservations.reservation", $uuid); + } +} diff --git a/src/opnsense/mvc/app/controllers/OPNsense/Kea/Api/ServiceController.php b/src/opnsense/mvc/app/controllers/OPNsense/Kea/Api/ServiceController.php new file mode 100644 index 000000000..65b54de73 --- /dev/null +++ b/src/opnsense/mvc/app/controllers/OPNsense/Kea/Api/ServiceController.php @@ -0,0 +1,45 @@ +view->pick('OPNsense/Kea/dhcpv4'); + $this->view->formGeneralSettings = $this->getForm("generalSettings"); + $this->view->formDialogSubnet = $this->getForm("dialogSubnet"); + $this->view->formDialogReservation = $this->getForm("dialogReservation"); + } +} diff --git a/src/opnsense/mvc/app/controllers/OPNsense/Kea/forms/dialogReservation.xml b/src/opnsense/mvc/app/controllers/OPNsense/Kea/forms/dialogReservation.xml new file mode 100644 index 000000000..2838e612b --- /dev/null +++ b/src/opnsense/mvc/app/controllers/OPNsense/Kea/forms/dialogReservation.xml @@ -0,0 +1,26 @@ +
+ + reservation.subnet + + dropdown + Subnet this reservation belongs to + + + reservation.ip_address + + text + IP address to offer to the client + + + reservation.hw_address + + text + MAC/Ether address of the client in question + + + reservation.description + + text + You may enter a description here for your reference (not parsed). + +
\ No newline at end of file diff --git a/src/opnsense/mvc/app/controllers/OPNsense/Kea/forms/dialogSubnet.xml b/src/opnsense/mvc/app/controllers/OPNsense/Kea/forms/dialogSubnet.xml new file mode 100644 index 000000000..a08b44622 --- /dev/null +++ b/src/opnsense/mvc/app/controllers/OPNsense/Kea/forms/dialogSubnet.xml @@ -0,0 +1,50 @@ +
+ + subnet4.subnet + + text + Subnet to use, should be large enough to hold the specified pools and reservations + + + subnet4.pools + + textbox + List of pools, one per line in range or subnet format (e.g. 192.168.0.100 - 192.168.0.200 , 192.0.2.64/26 + + + subnet4.option_data.routers + + select_multiple + + true + Default gateways to offer to the clients + + + subnet4.option_data.domain_name_servers + + select_multiple + + true + DNS servers to offer to the clients + + + subnet4.option_data.ntp_servers + + select_multiple + + true + NTP servers to offer to the clients + + + subnet4.option_data.tftp_server_name + + text + TFTP server address or fqdn + + + subnet4.option_data.boot_file_name + + text + Boot filename to request + +
\ No newline at end of file diff --git a/src/opnsense/mvc/app/controllers/OPNsense/Kea/forms/generalSettings.xml b/src/opnsense/mvc/app/controllers/OPNsense/Kea/forms/generalSettings.xml new file mode 100644 index 000000000..52ce9e85d --- /dev/null +++ b/src/opnsense/mvc/app/controllers/OPNsense/Kea/forms/generalSettings.xml @@ -0,0 +1,20 @@ +
+ + dhcpv4.general.enabled + + checkbox + Enable DHCPv4 server. + + + dhcpv4.general.interfaces + + select_multiple + Select interfaces to listen on. + + + dhcpv4.general.valid_lifetime + + text + Defines how long the addresses (leases) given out by the server are valid (in seconds) + +
diff --git a/src/opnsense/mvc/app/models/OPNsense/Kea/ACL/ACL.xml b/src/opnsense/mvc/app/models/OPNsense/Kea/ACL/ACL.xml new file mode 100644 index 000000000..5aeadbad9 --- /dev/null +++ b/src/opnsense/mvc/app/models/OPNsense/Kea/ACL/ACL.xml @@ -0,0 +1,10 @@ + + + Services: DHCP: Kea(v4) + Allow access to the KEA dhcp4 server + + ui/kea/dhcp/v4 + api/kea/dhcpv4/* + + + \ No newline at end of file diff --git a/src/opnsense/mvc/app/models/OPNsense/Kea/FieldTypes/KeaPoolsField.php b/src/opnsense/mvc/app/models/OPNsense/Kea/FieldTypes/KeaPoolsField.php new file mode 100644 index 000000000..30dd4ba93 --- /dev/null +++ b/src/opnsense/mvc/app/models/OPNsense/Kea/FieldTypes/KeaPoolsField.php @@ -0,0 +1,66 @@ +internalValue != null) { + $validators[] = new CallbackValidator(["callback" => function ($data) { + $messages = []; + foreach (explode("\n", $data) as $entry) { + $parts = array_map('trim', explode('-', $entry)); + if (empty($entry)) { + continue; + } elseif (Util::isSubnet($entry)) { + continue; + } elseif (count($parts) == 2 && Util::isIpAddress($parts[0]) && Util::isIpAddress($parts[1])) { + continue; + } + $messages[] = sprintf(gettext('Entry "%s" is not a valid range or subnet.'), $entry); + } + return $messages; + } + ]); + } + return $validators; + } +} diff --git a/src/opnsense/mvc/app/models/OPNsense/Kea/KeaDhcpv4.php b/src/opnsense/mvc/app/models/OPNsense/Kea/KeaDhcpv4.php new file mode 100644 index 000000000..e7b2ab45c --- /dev/null +++ b/src/opnsense/mvc/app/models/OPNsense/Kea/KeaDhcpv4.php @@ -0,0 +1,37 @@ + + //OPNsense/Kea/dhcp4 + 0.0.1 + Kea DHCPv4 configuration + + + + 0 + Y + + + Y + + + 4000 + Y + + + + + + Y + ipv4 + Y + + + + N + ipv4 + Y + , + + + N + ipv4 + Y + , + + + N + ipv4 + Y + , + + + /^([0-9a-zA-Z.\:\-,_]){0,1024}$/u + + + /^([0-9a-zA-Z.\:\-,_]){0,1024}$/u + + + + + + + + + + + + OPNsense.Kea.KeaDhcpv4 + subnets.subnet4 + subnet + + + Related subnet not found + Y + + + N + ipv4 + + + Y + + + + + + + diff --git a/src/opnsense/mvc/app/models/OPNsense/Kea/Menu/Menu.xml b/src/opnsense/mvc/app/models/OPNsense/Kea/Menu/Menu.xml new file mode 100644 index 000000000..1cdc54657 --- /dev/null +++ b/src/opnsense/mvc/app/models/OPNsense/Kea/Menu/Menu.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/src/opnsense/mvc/app/views/OPNsense/Kea/dhcpv4.volt b/src/opnsense/mvc/app/views/OPNsense/Kea/dhcpv4.volt new file mode 100644 index 000000000..7eb3b4260 --- /dev/null +++ b/src/opnsense/mvc/app/views/OPNsense/Kea/dhcpv4.volt @@ -0,0 +1,145 @@ +{# + + OPNsense® is Copyright © 2023 by Deciso B.V. + All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + +#} + + + + +
+
+ {{ partial("layout_partials/base_form",['fields':formGeneralSettings,'id':'frm_generalsettings'])}} +
+ +
+ + + + + + + + + + + + + + + + +
{{ lang._('ID') }}{{ lang._('Subnet') }}{{ lang._('Commands') }}
+ +
+
+ +
+ + + + + + + + + + + + + + + + + + +
{{ lang._('ID') }}{{ lang._('Subnet') }}{{ lang._('MAC') }}{{ lang._('Description') }}{{ lang._('Commands') }}
+ +
+
+
+ +
+
+
+
+ +

+
+
+
+ +{{ partial("layout_partials/base_dialog",['fields':formDialogSubnet,'id':'DialogSubnet','label':lang._('Edit Subnet')])}} +{{ partial("layout_partials/base_dialog",['fields':formDialogReservation,'id':'DialogReservation','label':lang._('Edit Reservation')])}} diff --git a/src/opnsense/service/conf/actions.d/actions_kea.conf b/src/opnsense/service/conf/actions.d/actions_kea.conf new file mode 100644 index 000000000..90cebb3e2 --- /dev/null +++ b/src/opnsense/service/conf/actions.d/actions_kea.conf @@ -0,0 +1,24 @@ +[stop] +command:/usr/local/etc/rc.d/kea stop +parameters: +type:script +message:stop kea daemon + +[start] +command:/usr/local/etc/rc.d/kea start +parameters: +type:script +message:start kea daemon + +[restart] +command:/usr/local/etc/rc.d/kea restart +parameters: +type:script +message:restart kea daemon +description:Restart kea daemon + +[status] +command:/usr/local/sbin/pluginctl -s kea-dhcpv4 status +parameters: +type:script_output +message:get kea daemon status diff --git a/src/opnsense/service/templates/OPNsense/Kea/+TARGETS b/src/opnsense/service/templates/OPNsense/Kea/+TARGETS new file mode 100644 index 000000000..a3bf79720 --- /dev/null +++ b/src/opnsense/service/templates/OPNsense/Kea/+TARGETS @@ -0,0 +1,4 @@ +kea-dhcp4.conf:/usr/local/etc/kea/kea-dhcp4.conf +rc.conf.d:/etc/rc.conf.d/kea +keactrl.conf:/usr/local/etc/kea/keactrl.conf +kea-ctrl-agent.conf:/usr/local/etc/kea/kea-ctrl-agent.conf \ No newline at end of file diff --git a/src/opnsense/service/templates/OPNsense/Kea/kea-ctrl-agent.conf b/src/opnsense/service/templates/OPNsense/Kea/kea-ctrl-agent.conf new file mode 100644 index 000000000..e8a88a594 --- /dev/null +++ b/src/opnsense/service/templates/OPNsense/Kea/kea-ctrl-agent.conf @@ -0,0 +1,105 @@ +// This is a basic configuration for the Kea Control Agent. +// +// This is just a very basic configuration. Kea comes with large suite (over 30) +// of configuration examples and extensive Kea User's Guide. Please refer to +// those materials to get better understanding of what this software is able to +// do. Comments in this configuration file sometimes refer to sections for more +// details. These are section numbers in Kea User's Guide. The version matching +// your software should come with your Kea package, but it is also available +// in ISC's Knowledgebase (https://kea.readthedocs.io; the direct link for +// the stable version is https://kea.readthedocs.io/). +// +// This configuration file contains only Control Agent's configuration. +// If configurations for other Kea services are also included in this file they +// are ignored by the Control Agent. +{ + +// This is a basic configuration for the Kea Control Agent. +// RESTful interface to be available at http://127.0.0.1:8000/ +"Control-agent": { + "http-host": "127.0.0.1", + // If enabling HA and multi-threading, the 8000 port is used by the HA + // hook library http listener. When using HA hook library with + // multi-threading to function, make sure the port used by dedicated + // listener is different (e.g. 8001) than the one used by CA. Note + // the commands should still be sent via CA. The dedicated listener + // is specifically for HA updates only. + "http-port": 8000, + + // Specify location of the files to which the Control Agent + // should connect to forward commands to the DHCPv4, DHCPv6 + // and D2 servers via unix domain sockets. + "control-sockets": { + "dhcp4": { + "socket-type": "unix", + "socket-name": "/var/run/kea4-ctrl-socket" + }, + "dhcp6": { + "socket-type": "unix", + "socket-name": "/var/run/kea6-ctrl-socket" + }, + "d2": { + "socket-type": "unix", + "socket-name": "/var/run/kea-ddns-ctrl-socket" + } + }, + + // Specify hooks libraries that are attached to the Control Agent. + // Such hooks libraries should support 'control_command_receive' + // hook point. This is currently commented out because it has to + // point to the existing hooks library. Otherwise the Control + // Agent will fail to start. + "hooks-libraries": [ +// { +// "library": "/usr/local/lib/kea/hooks/control-agent-commands.so", +// "parameters": { +// "param1": "foo" +// } +// } + ], + +// Logging configuration starts here. Kea uses different loggers to log various +// activities. For details (e.g. names of loggers), see Chapter 18. + "loggers": [ + { + // This specifies the logging for Control Agent daemon. + "name": "kea-ctrl-agent", + "output_options": [ + { + // Specifies the output file. There are several special values + // supported: + // - stdout (prints on standard output) + // - stderr (prints on standard error) + // - syslog (logs to syslog) + // - syslog:name (logs to syslog using specified name) + // Any other value is considered a name of the file + "output": "syslog" + + // Shorter log pattern suitable for use with systemd, + // avoids redundant information + // "pattern": "%-5p %m\n" + + // This governs whether the log output is flushed to disk after + // every write. + // "flush": false, + + // This specifies the maximum size of the file before it is + // rotated. + // "maxsize": 1048576, + + // This specifies the maximum number of rotated files to keep. + // "maxver": 8 + } + ], + // This specifies the severity of log messages to keep. Supported values + // are: FATAL, ERROR, WARN, INFO, DEBUG + "severity": "INFO", + + // If DEBUG level is specified, this value is used. 0 is least verbose, + // 99 is most verbose. Be cautious, Kea can generate lots and lots + // of logs if told to do so. + "debuglevel": 0 + } + ] +} +} diff --git a/src/opnsense/service/templates/OPNsense/Kea/kea-dhcp4.conf b/src/opnsense/service/templates/OPNsense/Kea/kea-dhcp4.conf new file mode 100644 index 000000000..f36241dda --- /dev/null +++ b/src/opnsense/service/templates/OPNsense/Kea/kea-dhcp4.conf @@ -0,0 +1,64 @@ +{%- if not helpers.empty('OPNsense.Kea.dhcp4.general.interfaces') and not helpers.empty('OPNsense.Kea.dhcp4.general.enabled') -%} +{%- set reservation_fields = ({ + 'hw-address': 'hw_address', + 'ip-address': 'ip_address' +}) -%} +{%- set general = OPNsense.Kea.dhcp4.general -%} +{ + "Dhcp4": { + "valid-lifetime": {{general.valid_lifetime}}, + "interfaces-config": { + "interfaces": ["{{helpers.physical_interfaces(general.interfaces.split(','))|join('","')}}"] + }, + "lease-database": { + "type": "memfile", + "persist": true + }, + "control-socket": { + "socket-type": "unix", + "socket-name": "/var/run/kea4-ctrl-socket" + }, + "loggers": [ + { + "name": "kea-dhcp4", + "output_options": [ + { + "output": "syslog" + } + ], + "severity": "INFO" + } + ], + "subnet4": [ +{% for subnet in helpers.toList('OPNsense.Kea.dhcp4.subnets.subnet4') %} + { + "id": {{loop.index}}, + "subnet": "{{subnet.subnet}}", + "option-data": [ +{% for od_attr in subnet.option_data if subnet.option_data[od_attr]|length > 1 %} + { + "name": "{{od_attr.replace('_','-')}}", + "data": {{subnet.option_data[od_attr]|tojson}} + }{% if not loop.last %},{% endif +%} +{% endfor %} + ], + "pools": [ +{% for pool in (subnet.pools|default('')).split("\n") if pool|length > 1%} + { "pool": "{{pool}}" }{% if not loop.last %},{% endif +%} +{% endfor %} + ], + "reservations": [ +{% for reservation in helpers.toList('OPNsense.Kea.dhcp4.reservations.reservation') if reservation.subnet == subnet['@uuid'] %} + { +{% for res_key, res_prop in reservation_fields.items() if reservation[res_prop]|length > 1 %} + "{{res_key}}": "{{reservation[res_prop]}}"{% if not loop.last %},{% endif +%} +{% endfor %} + }{% if not loop.last %},{% endif +%} +{% endfor %} + ] + }{% if not loop.last %},{% endif +%} +{% endfor %} + ] + } +} +{%- endif -%} \ No newline at end of file diff --git a/src/opnsense/service/templates/OPNsense/Kea/keactrl.conf b/src/opnsense/service/templates/OPNsense/Kea/keactrl.conf new file mode 100644 index 000000000..7d24e7899 --- /dev/null +++ b/src/opnsense/service/templates/OPNsense/Kea/keactrl.conf @@ -0,0 +1,46 @@ +#!/bin/sh + +# This is a configuration file for keactrl script which controls +# the startup, shutdown, reconfiguration and gathering the status +# of the Kea's processes. + +# Note that control agent must be launched after servers and netconf last. + +# shellcheck disable=SC2034 +# SC2034: ... appears unused. Verify use (or export if used externally). + +# prefix holds the location where the Kea is installed. +prefix="/usr/local" + +# Location of Kea configuration files. +kea_dhcp4_config_file="${prefix}/etc/kea/kea-dhcp4.conf" +kea_dhcp6_config_file="${prefix}/etc/kea/kea-dhcp6.conf" +kea_dhcp_ddns_config_file="${prefix}/etc/kea/kea-dhcp-ddns.conf" +kea_ctrl_agent_config_file="${prefix}/etc/kea/kea-ctrl-agent.conf" +kea_netconf_config_file="${prefix}/etc/kea/kea-netconf.conf" + +# Location of Kea binaries. +exec_prefix="${prefix}" +dhcp4_srv="${exec_prefix}/sbin/kea-dhcp4" +dhcp6_srv="${exec_prefix}/sbin/kea-dhcp6" +dhcp_ddns_srv="${exec_prefix}/sbin/kea-dhcp-ddns" +ctrl_agent_srv="${exec_prefix}/sbin/kea-ctrl-agent" +netconf_srv="${exec_prefix}/sbin/kea-netconf" + +# Start DHCPv4 server? +dhcp4=yes + +# Start DHCPv6 server? +dhcp6=no + +# Start DHCP DDNS server? +dhcp_ddns=no + +# Start Control Agent? +ctrl_agent=no + +# Start Netconf? +netconf=no + +# Be verbose? +kea_verbose=no diff --git a/src/opnsense/service/templates/OPNsense/Kea/rc.conf.d b/src/opnsense/service/templates/OPNsense/Kea/rc.conf.d new file mode 100644 index 000000000..4c0772ea5 --- /dev/null +++ b/src/opnsense/service/templates/OPNsense/Kea/rc.conf.d @@ -0,0 +1,5 @@ +{% if not helpers.empty('OPNsense.Kea.dhcp4.general.interfaces') and not helpers.empty('OPNsense.Kea.dhcp4.general.enabled') %} +kea_enable="YES" +{% else %} +kea_enable="NO" +{% endif %} \ No newline at end of file diff --git a/src/opnsense/service/templates/OPNsense/Syslog/local/kea.conf b/src/opnsense/service/templates/OPNsense/Syslog/local/kea.conf new file mode 100644 index 000000000..9ac906e59 --- /dev/null +++ b/src/opnsense/service/templates/OPNsense/Syslog/local/kea.conf @@ -0,0 +1,6 @@ +################################################################### +# Local syslog-ng configuration filter definition [kea]. +################################################################### +filter f_local_kea { + program("kea-dhcp4") or program("kea-dhcp6") or program("kea-ctrl-agent"); +};