diff --git a/plist b/plist index 010c9c4cd..9695344e7 100644 --- a/plist +++ b/plist @@ -402,13 +402,16 @@ /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/CtrlAgentController.php /usr/local/opnsense/mvc/app/controllers/OPNsense/Kea/Api/Dhcpv4Controller.php /usr/local/opnsense/mvc/app/controllers/OPNsense/Kea/Api/Leases4Controller.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/Kea/forms/agentSettings.xml +/usr/local/opnsense/mvc/app/controllers/OPNsense/Kea/forms/dialogPeer4.xml +/usr/local/opnsense/mvc/app/controllers/OPNsense/Kea/forms/dialogReservation4.xml +/usr/local/opnsense/mvc/app/controllers/OPNsense/Kea/forms/dialogSubnet4.xml +/usr/local/opnsense/mvc/app/controllers/OPNsense/Kea/forms/generalSettings4.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 @@ -712,6 +715,8 @@ /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/KeaCtrlAgent.php +/usr/local/opnsense/mvc/app/models/OPNsense/Kea/KeaCtrlAgent.xml /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 @@ -831,6 +836,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/ctrl_agent.volt /usr/local/opnsense/mvc/app/views/OPNsense/Kea/dhcpv4.volt /usr/local/opnsense/mvc/app/views/OPNsense/Kea/leases4.volt /usr/local/opnsense/mvc/app/views/OPNsense/Monit/index.volt diff --git a/src/opnsense/mvc/app/controllers/OPNsense/Kea/Api/CtrlAgentController.php b/src/opnsense/mvc/app/controllers/OPNsense/Kea/Api/CtrlAgentController.php new file mode 100644 index 000000000..02ee37254 --- /dev/null +++ b/src/opnsense/mvc/app/controllers/OPNsense/Kea/Api/CtrlAgentController.php @@ -0,0 +1,50 @@ + [ + 'general' => $data[self::$internalModelName]['general'] + ] + ]; + } +} diff --git a/src/opnsense/mvc/app/controllers/OPNsense/Kea/Api/Dhcpv4Controller.php b/src/opnsense/mvc/app/controllers/OPNsense/Kea/Api/Dhcpv4Controller.php index a4e95ba4c..18d6b6795 100644 --- a/src/opnsense/mvc/app/controllers/OPNsense/Kea/Api/Dhcpv4Controller.php +++ b/src/opnsense/mvc/app/controllers/OPNsense/Kea/Api/Dhcpv4Controller.php @@ -29,6 +29,7 @@ namespace OPNsense\Kea\Api; use OPNsense\Base\ApiMutableModelControllerBase; +use OPNsense\Core\Config; class Dhcpv4Controller extends ApiMutableModelControllerBase { @@ -43,7 +44,9 @@ class Dhcpv4Controller extends ApiMutableModelControllerBase $data = parent::getAction(); return [ self::$internalModelName => [ - 'general' => $data[self::$internalModelName]['general'] + 'general' => $data[self::$internalModelName]['general'], + 'ha' => $data[self::$internalModelName]['ha'], + 'this_hostname' => (string)Config::getInstance()->object()->system->hostname ] ]; } @@ -101,4 +104,30 @@ class Dhcpv4Controller extends ApiMutableModelControllerBase { return $this->delBase("reservations.reservation", $uuid); } + + public function searchPeerAction() + { + return $this->searchBase("ha_peers.peer", ['name', 'role'], "name"); + } + + public function setPeerAction($uuid) + { + return $this->setBase("peer", "ha_peers.peer", $uuid); + } + + public function addPeerAction() + { + return $this->addBase("peer", "ha_peers.peer"); + } + + public function getPeerAction($uuid = null) + { + return $this->getBase("peer", "ha_peers.peer", $uuid); + } + + public function delPeerAction($uuid) + { + return $this->delBase("ha_peers.peer", $uuid); + } + } diff --git a/src/opnsense/mvc/app/controllers/OPNsense/Kea/DhcpController.php b/src/opnsense/mvc/app/controllers/OPNsense/Kea/DhcpController.php index 8458aa230..c01a11adb 100644 --- a/src/opnsense/mvc/app/controllers/OPNsense/Kea/DhcpController.php +++ b/src/opnsense/mvc/app/controllers/OPNsense/Kea/DhcpController.php @@ -40,12 +40,19 @@ class DhcpController extends \OPNsense\Base\IndexController ]); } + public function ctrlAgentAction() + { + $this->view->pick('OPNsense/Kea/ctrl_agent'); + $this->view->formGeneralSettings = $this->getForm("agentSettings"); + } + public function v4Action() { $this->view->pick('OPNsense/Kea/dhcpv4'); - $this->view->formGeneralSettings = $this->getForm("generalSettings"); - $this->view->formDialogSubnet = $this->getForm("dialogSubnet"); - $this->view->formDialogReservation = $this->getForm("dialogReservation"); + $this->view->formGeneralSettings = $this->getForm("generalSettings4"); + $this->view->formDialogSubnet = $this->getForm("dialogSubnet4"); + $this->view->formDialogReservation = $this->getForm("dialogReservation4"); + $this->view->formDialogPeer = $this->getForm("dialogPeer4"); } public function leases4Action() diff --git a/src/opnsense/mvc/app/controllers/OPNsense/Kea/forms/agentSettings.xml b/src/opnsense/mvc/app/controllers/OPNsense/Kea/forms/agentSettings.xml new file mode 100644 index 000000000..f72910840 --- /dev/null +++ b/src/opnsense/mvc/app/controllers/OPNsense/Kea/forms/agentSettings.xml @@ -0,0 +1,20 @@ +
+ + ctrlagent.general.enabled + + checkbox + Enable control agent. + + + ctrlagent.general.http_host + + text + Address on which the RESTful interface should be available + + + ctrlagent.general.http_port + + text + Portnumber to use for the RESTful interface + +
diff --git a/src/opnsense/mvc/app/controllers/OPNsense/Kea/forms/dialogPeer4.xml b/src/opnsense/mvc/app/controllers/OPNsense/Kea/forms/dialogPeer4.xml new file mode 100644 index 000000000..7c6354100 --- /dev/null +++ b/src/opnsense/mvc/app/controllers/OPNsense/Kea/forms/dialogPeer4.xml @@ -0,0 +1,21 @@ +
+ + peer.name + + text + Peer name, there should be one entry matching this machines "This server name" + + + peer.role + + dropdown + This peers role + + + peer.url + + text + This specifies the URL of our server instance, which should use a different port than the control agent. + For example http://192.0.2.1:8001/ + +
diff --git a/src/opnsense/mvc/app/controllers/OPNsense/Kea/forms/dialogReservation.xml b/src/opnsense/mvc/app/controllers/OPNsense/Kea/forms/dialogReservation4.xml similarity index 100% rename from src/opnsense/mvc/app/controllers/OPNsense/Kea/forms/dialogReservation.xml rename to src/opnsense/mvc/app/controllers/OPNsense/Kea/forms/dialogReservation4.xml diff --git a/src/opnsense/mvc/app/controllers/OPNsense/Kea/forms/dialogSubnet.xml b/src/opnsense/mvc/app/controllers/OPNsense/Kea/forms/dialogSubnet4.xml similarity index 100% rename from src/opnsense/mvc/app/controllers/OPNsense/Kea/forms/dialogSubnet.xml rename to src/opnsense/mvc/app/controllers/OPNsense/Kea/forms/dialogSubnet4.xml diff --git a/src/opnsense/mvc/app/controllers/OPNsense/Kea/forms/generalSettings.xml b/src/opnsense/mvc/app/controllers/OPNsense/Kea/forms/generalSettings.xml deleted file mode 100644 index 52ce9e85d..000000000 --- a/src/opnsense/mvc/app/controllers/OPNsense/Kea/forms/generalSettings.xml +++ /dev/null @@ -1,20 +0,0 @@ -
- - 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/controllers/OPNsense/Kea/forms/generalSettings4.xml b/src/opnsense/mvc/app/controllers/OPNsense/Kea/forms/generalSettings4.xml new file mode 100644 index 000000000..04b4de9e1 --- /dev/null +++ b/src/opnsense/mvc/app/controllers/OPNsense/Kea/forms/generalSettings4.xml @@ -0,0 +1,42 @@ +
+ + header + + + + 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) + + + header + + + + dhcpv4.ha.enabled + + checkbox + Enable High availability hook, requires the Control Agent to be enabled as well. + + + dhcpv4.ha.this_server_name + + text + The name of this server, should match with one of the entries in the HA peers. + Leave empty to use this machines hostname + + +
diff --git a/src/opnsense/mvc/app/models/OPNsense/Kea/KeaCtrlAgent.php b/src/opnsense/mvc/app/models/OPNsense/Kea/KeaCtrlAgent.php new file mode 100644 index 000000000..876a9a4f7 --- /dev/null +++ b/src/opnsense/mvc/app/models/OPNsense/Kea/KeaCtrlAgent.php @@ -0,0 +1,35 @@ + + //OPNsense/Kea/ctrl_agent + 0.0.1 + Kea Control Agent configuration + + + + 0 + Y + + + N + ipv4 + 127.0.0.1 + Y + + + Y + 8000 + + + + diff --git a/src/opnsense/mvc/app/models/OPNsense/Kea/KeaDhcpv4.xml b/src/opnsense/mvc/app/models/OPNsense/Kea/KeaDhcpv4.xml index ef8c54dbb..b36c6c343 100644 --- a/src/opnsense/mvc/app/models/OPNsense/Kea/KeaDhcpv4.xml +++ b/src/opnsense/mvc/app/models/OPNsense/Kea/KeaDhcpv4.xml @@ -16,6 +16,15 @@ Y + + + 0 + Y + + + /^([0-9a-zA-Z.\:\-,_]){0,1024}$/u + + @@ -61,11 +70,11 @@ - + OPNsense.Kea.KeaDhcpv4 subnets.subnet4 subnet - + Related subnet not found Y @@ -83,5 +92,35 @@ + + + + Y + + + Duplicate entry exists + UniqueConstraint + + + + + primary + Y + + primary + standby + + + + Y + + + Duplicate entry exists + UniqueConstraint + + + + + diff --git a/src/opnsense/mvc/app/models/OPNsense/Kea/Menu/Menu.xml b/src/opnsense/mvc/app/models/OPNsense/Kea/Menu/Menu.xml index 3cac48057..a81864350 100644 --- a/src/opnsense/mvc/app/models/OPNsense/Kea/Menu/Menu.xml +++ b/src/opnsense/mvc/app/models/OPNsense/Kea/Menu/Menu.xml @@ -1,7 +1,8 @@ - + + diff --git a/src/opnsense/mvc/app/views/OPNsense/Kea/ctrl_agent.volt b/src/opnsense/mvc/app/views/OPNsense/Kea/ctrl_agent.volt new file mode 100644 index 000000000..4297f1651 --- /dev/null +++ b/src/opnsense/mvc/app/views/OPNsense/Kea/ctrl_agent.volt @@ -0,0 +1,74 @@ +{# + + 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'])}} +
+
+ +
+
+
+
+ +

+
+
+
+ diff --git a/src/opnsense/mvc/app/views/OPNsense/Kea/dhcpv4.volt b/src/opnsense/mvc/app/views/OPNsense/Kea/dhcpv4.volt index f6c2e121d..bedb65a38 100644 --- a/src/opnsense/mvc/app/views/OPNsense/Kea/dhcpv4.volt +++ b/src/opnsense/mvc/app/views/OPNsense/Kea/dhcpv4.volt @@ -29,7 +29,15 @@
+
{{ partial("layout_partials/base_form",['fields':formGeneralSettings,'id':'frm_generalsettings'])}}
- +
@@ -98,7 +117,7 @@
- +
@@ -124,6 +143,30 @@
+ +
+ + + + + + + + + + + + + + + + + +
{{ lang._('ID') }}{{ lang._('Name') }}{{ lang._('Role') }}{{ lang._('Commands') }}
+ +
+
+
@@ -143,3 +186,4 @@ {{ 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')])}} +{{ partial("layout_partials/base_dialog",['fields':formDialogPeer,'id':'DialogPeer','label':lang._('Edit Peer')])}} diff --git a/src/opnsense/service/templates/OPNsense/Kea/kea-ctrl-agent.conf b/src/opnsense/service/templates/OPNsense/Kea/kea-ctrl-agent.conf index e8a88a594..f85b167bd 100644 --- a/src/opnsense/service/templates/OPNsense/Kea/kea-ctrl-agent.conf +++ b/src/opnsense/service/templates/OPNsense/Kea/kea-ctrl-agent.conf @@ -1,34 +1,7 @@ -// 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. + "http-host": "{{ OPNsense.Kea.ctrl_agent.general.http_host|default('127.0.0.1')}}", + "http-port": {{ OPNsense.Kea.ctrl_agent.general.http_port|default('8000')}}, "control-sockets": { "dhcp4": { "socket-type": "unix", @@ -43,61 +16,15 @@ "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 index 7a444b287..41d69aa71 100644 --- a/src/opnsense/service/templates/OPNsense/Kea/kea-dhcp4.conf +++ b/src/opnsense/service/templates/OPNsense/Kea/kea-dhcp4.conf @@ -52,14 +52,47 @@ {% 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 +%} + "{{res_key}}": {{reservation[res_prop]|tojson}}{% if not loop.last %},{% endif +%} {% endfor %} }{% if not loop.last %},{% endif +%} {% endfor %} ] }{% if not loop.last %},{% endif +%} {% endfor %} + ], +{% if not helpers.empty('OPNsense.Kea.ctrl_agent.general.enabled') %} + "hooks-libraries": [ + { + "library": "/usr/local/lib/kea/hooks/libdhcp_lease_cmds.so", + "parameters": { } + }, +{% if not helpers.empty('OPNsense.Kea.dhcp4.ha.enabled') %} + { + "library": "/usr/local/lib/kea/hooks/libdhcp_ha.so", + "parameters": { + "high-availability": [ { + "this-server-name": {{OPNsense.Kea.dhcp4.ha.this_server_name|default(system.hostname)|tojson}}, + "mode": "hot-standby", + "heartbeat-delay": 10000, + "max-response-delay": 60000, + "max-ack-delay": 5000, + "max-unacked-clients": 5, + "sync-timeout": 60000, + "peers": [ +{% for peer in helpers.toList('OPNsense.Kea.dhcp4.ha_peers.peer') %} + { + "name": {{peer.name|tojson}}, + "role": {{peer.role|tojson}}, + "url": {{peer.url|default('')|tojson}} + }{% if not loop.last %},{% endif +%} +{% endfor %} + ] + } ] + } + } +{% endif %} ] +{% endif %} } } {%- endif -%} diff --git a/src/opnsense/service/templates/OPNsense/Kea/keactrl.conf b/src/opnsense/service/templates/OPNsense/Kea/keactrl.conf index 7d24e7899..45f511fe6 100644 --- a/src/opnsense/service/templates/OPNsense/Kea/keactrl.conf +++ b/src/opnsense/service/templates/OPNsense/Kea/keactrl.conf @@ -28,7 +28,7 @@ ctrl_agent_srv="${exec_prefix}/sbin/kea-ctrl-agent" netconf_srv="${exec_prefix}/sbin/kea-netconf" # Start DHCPv4 server? -dhcp4=yes +dhcp4={% if not helpers.empty('OPNsense.Kea.dhcp4.general.enabled') %}yes{% else %}no{% endif %} # Start DHCPv6 server? dhcp6=no @@ -37,7 +37,7 @@ dhcp6=no dhcp_ddns=no # Start Control Agent? -ctrl_agent=no +ctrl_agent={% if not helpers.empty('OPNsense.Kea.ctrl_agent.general.enabled') %}yes{% else %}no{% endif %} # Start Netconf? netconf=no