From 8bc1616baf3aa5b7ba676175fcfa49e6e75f2f69 Mon Sep 17 00:00:00 2001 From: Tobias <5389669+botboe@users.noreply.github.com> Date: Wed, 14 Apr 2021 11:44:03 +0200 Subject: [PATCH] New Plugin "RadSecProxy" (#1894) --- net/radsecproxy/Makefile | 8 + net/radsecproxy/pkg-descr | 5 + .../src/etc/inc/plugins.inc.d/radsecproxy.inc | 73 +++ net/radsecproxy/src/etc/rc.d/os-radsecproxy | 46 ++ .../RadSecProxy/Api/ClientsController.php | 67 +++ .../RadSecProxy/Api/GeneralController.php | 33 ++ .../RadSecProxy/Api/RealmsController.php | 63 +++ .../RadSecProxy/Api/RewritesController.php | 67 +++ .../RadSecProxy/Api/ServersController.php | 67 +++ .../RadSecProxy/Api/ServiceController.php | 40 ++ .../RadSecProxy/Api/TlsController.php | 67 +++ .../RadSecProxy/ClientsController.php | 36 ++ .../RadSecProxy/GeneralController.php | 34 ++ .../OPNsense/RadSecProxy/IndexController.php | 34 ++ .../OPNsense/RadSecProxy/RealmsController.php | 34 ++ .../RadSecProxy/RewritesController.php | 36 ++ .../RadSecProxy/ServersController.php | 34 ++ .../OPNsense/RadSecProxy/TlsController.php | 34 ++ .../RadSecProxy/forms/dialogClient.xml | 96 ++++ .../RadSecProxy/forms/dialogRealm.xml | 71 +++ .../RadSecProxy/forms/dialogRewrite.xml | 101 ++++ .../RadSecProxy/forms/dialogServer.xml | 102 ++++ .../OPNsense/RadSecProxy/forms/dialogTls.xml | 68 +++ .../OPNsense/RadSecProxy/forms/general.xml | 121 +++++ .../models/OPNsense/RadSecProxy/Menu/Menu.xml | 12 + .../OPNsense/RadSecProxy/RadSecProxy.php | 31 ++ .../OPNsense/RadSecProxy/RadSecProxy.xml | 514 ++++++++++++++++++ .../views/OPNsense/RadSecProxy/clients.volt | 56 ++ .../views/OPNsense/RadSecProxy/general.volt | 31 ++ .../views/OPNsense/RadSecProxy/realms.volt | 54 ++ .../views/OPNsense/RadSecProxy/rewrites.volt | 54 ++ .../views/OPNsense/RadSecProxy/servers.volt | 56 ++ .../app/views/OPNsense/RadSecProxy/tls.volt | 55 ++ .../OPNsense/RadSecProxy/generate_certs.php | 105 ++++ .../scripts/OPNsense/RadSecProxy/setup.sh | 18 + .../conf/actions.d/actions_radsecproxy.conf | 35 ++ .../templates/OPNsense/RadSecProxy/+TARGETS | 2 + .../OPNsense/RadSecProxy/radsecproxy.conf | 240 ++++++++ .../templates/OPNsense/RadSecProxy/rc.conf.d | 7 + 39 files changed, 2607 insertions(+) create mode 100644 net/radsecproxy/Makefile create mode 100644 net/radsecproxy/pkg-descr create mode 100644 net/radsecproxy/src/etc/inc/plugins.inc.d/radsecproxy.inc create mode 100755 net/radsecproxy/src/etc/rc.d/os-radsecproxy create mode 100644 net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/Api/ClientsController.php create mode 100644 net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/Api/GeneralController.php create mode 100644 net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/Api/RealmsController.php create mode 100644 net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/Api/RewritesController.php create mode 100644 net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/Api/ServersController.php create mode 100644 net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/Api/ServiceController.php create mode 100644 net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/Api/TlsController.php create mode 100644 net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/ClientsController.php create mode 100644 net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/GeneralController.php create mode 100644 net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/IndexController.php create mode 100644 net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/RealmsController.php create mode 100644 net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/RewritesController.php create mode 100644 net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/ServersController.php create mode 100644 net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/TlsController.php create mode 100644 net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/forms/dialogClient.xml create mode 100644 net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/forms/dialogRealm.xml create mode 100644 net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/forms/dialogRewrite.xml create mode 100644 net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/forms/dialogServer.xml create mode 100644 net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/forms/dialogTls.xml create mode 100644 net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/forms/general.xml create mode 100644 net/radsecproxy/src/opnsense/mvc/app/models/OPNsense/RadSecProxy/Menu/Menu.xml create mode 100644 net/radsecproxy/src/opnsense/mvc/app/models/OPNsense/RadSecProxy/RadSecProxy.php create mode 100644 net/radsecproxy/src/opnsense/mvc/app/models/OPNsense/RadSecProxy/RadSecProxy.xml create mode 100644 net/radsecproxy/src/opnsense/mvc/app/views/OPNsense/RadSecProxy/clients.volt create mode 100644 net/radsecproxy/src/opnsense/mvc/app/views/OPNsense/RadSecProxy/general.volt create mode 100644 net/radsecproxy/src/opnsense/mvc/app/views/OPNsense/RadSecProxy/realms.volt create mode 100644 net/radsecproxy/src/opnsense/mvc/app/views/OPNsense/RadSecProxy/rewrites.volt create mode 100644 net/radsecproxy/src/opnsense/mvc/app/views/OPNsense/RadSecProxy/servers.volt create mode 100644 net/radsecproxy/src/opnsense/mvc/app/views/OPNsense/RadSecProxy/tls.volt create mode 100755 net/radsecproxy/src/opnsense/scripts/OPNsense/RadSecProxy/generate_certs.php create mode 100755 net/radsecproxy/src/opnsense/scripts/OPNsense/RadSecProxy/setup.sh create mode 100644 net/radsecproxy/src/opnsense/service/conf/actions.d/actions_radsecproxy.conf create mode 100644 net/radsecproxy/src/opnsense/service/templates/OPNsense/RadSecProxy/+TARGETS create mode 100644 net/radsecproxy/src/opnsense/service/templates/OPNsense/RadSecProxy/radsecproxy.conf create mode 100644 net/radsecproxy/src/opnsense/service/templates/OPNsense/RadSecProxy/rc.conf.d diff --git a/net/radsecproxy/Makefile b/net/radsecproxy/Makefile new file mode 100644 index 000000000..c27c40120 --- /dev/null +++ b/net/radsecproxy/Makefile @@ -0,0 +1,8 @@ +PLUGIN_NAME= radsecproxy +PLUGIN_VERSION= 0.1 +PLUGIN_COMMENT= RADIUS proxy provides both RADIUS UDP and TCP/TLS (RadSec) transport +PLUGIN_DEPENDS= radsecproxy +PLUGIN_MAINTAINER= tobias@boehnert.dev +PLUGIN_DEVEL= yes + +.include "../../Mk/plugins.mk" diff --git a/net/radsecproxy/pkg-descr b/net/radsecproxy/pkg-descr new file mode 100644 index 000000000..ef872b8a7 --- /dev/null +++ b/net/radsecproxy/pkg-descr @@ -0,0 +1,5 @@ +A generic RADIUS proxy that in addition to usual RADIUS UDP +transport, also supports TLS (RadSec), as well as RADIUS +over TCP and DTLS. The aim is for the proxy to have +sufficient features to be flexible, while at the same time +to be small, efficient and easy to configure. diff --git a/net/radsecproxy/src/etc/inc/plugins.inc.d/radsecproxy.inc b/net/radsecproxy/src/etc/inc/plugins.inc.d/radsecproxy.inc new file mode 100644 index 000000000..57e873477 --- /dev/null +++ b/net/radsecproxy/src/etc/inc/plugins.inc.d/radsecproxy.inc @@ -0,0 +1,73 @@ +general->enabled == '1') { + return true; + } + + return false; +} + +function radsecproxy_syslog() +{ + // $syslogconf = array(); + + // $syslogconf['radsecproxy'] = array( + // 'local' => '/var/log/radsecproxy.log', + // 'facility' => array('radsecproxy'), + // 'remote' => 'relayd', + // ); + + // return $syslogconf; + + $logfacilities = array(); + $logfacilities['radsecproxy'] = array( + 'facility' => array('LOG_DAEMON'), + ); + return $logfacilities; + +} + + +function radsecproxy_services() +{ + $services = array(); + + if (radsecproxy_enabled()) { + $services[] = array( + 'description' => gettext('Radius Secure Proxy'), + 'configd' => array( + 'restart' => array('radsecproxy restart'), + 'start' => array('radsecproxy start'), + 'stop' => array('radsecproxy stop'), + ), + 'name' => 'radsecproxy', + 'pidfile' => '/var/run/radsecproxy/radsecproxy.pid' + ); + } + return $services; +} diff --git a/net/radsecproxy/src/etc/rc.d/os-radsecproxy b/net/radsecproxy/src/etc/rc.d/os-radsecproxy new file mode 100755 index 000000000..4faca1f6b --- /dev/null +++ b/net/radsecproxy/src/etc/rc.d/os-radsecproxy @@ -0,0 +1,46 @@ +#!/bin/sh + +# PROVIDE: radsecproxy +# REQUIRE: LOGIN +# KEYWORD: shutdown + +# Add the following line to /etc/rc.conf.local or /etc/rc.conf +# to enable this service: +# +# radsecproxy_enable (bool): Set to NO by default. +# Set it to YES to enable radsecproxy. + +. /etc/rc.subr + +name="radsecproxy" +rcvar=radsecproxy_enable + +: ${radsecproxy_enable:="NO"} +: ${radsecproxy_user:="root"} +: ${radsecproxy_group:="wheel"} +: ${radsecproxy_pidfile:="/var/run/radsecproxy.pid"} + +user=${radsecproxy_user} +group=${radsecproxy_group} +pidfile=${radsecproxy_pidfile} +required_files=/usr/local/etc/radsecproxy.conf + +command="/usr/local/sbin/${name}" +command_args="-c /usr/local/etc/radsecproxy.conf -i ${pidfile}" + +start_precmd="radsecproxy_prestart" +stop_postcmd="radsecproxy_poststop" + +radsecproxy_prestart() +{ + mkdir -p $(dirname $pidfile) + chown ${user}:${group} $(dirname $pidfile) +} + +radsecproxy_poststop() +{ + rm -f ${pidfile} +} + +load_rc_config $name +run_rc_command "$1" diff --git a/net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/Api/ClientsController.php b/net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/Api/ClientsController.php new file mode 100644 index 000000000..a256a8765 --- /dev/null +++ b/net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/Api/ClientsController.php @@ -0,0 +1,67 @@ +searchBase( + "clients.client", + array('enabled', 'description', 'host', 'identifier', 'type'), + "name" + ); + } + + public function setItemAction($uuid) + { + return $this->setBase("client", "clients.client", $uuid); + } + + public function addItemAction() + { + return $this->addBase("client", "clients.client"); + } + + public function getItemAction($uuid = null) + { + return $this->getBase("client", "clients.client", $uuid); + } + + public function delItemAction($uuid) + { + return $this->delBase("clients.client", $uuid); + } + + public function toggleItemAction($uuid, $enabled = null) + { + return $this->toggleBase("clients.client", $uuid, $enabled); + } +} diff --git a/net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/Api/GeneralController.php b/net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/Api/GeneralController.php new file mode 100644 index 000000000..786df74eb --- /dev/null +++ b/net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/Api/GeneralController.php @@ -0,0 +1,33 @@ +searchBase("realms.realm", array('enabled', 'description', 'realm'), "description"); + } + + public function setItemAction($uuid) + { + return $this->setBase("realm", "realms.realm", $uuid); + } + + public function addItemAction() + { + return $this->addBase("realm", "realms.realm"); + } + + public function getItemAction($uuid = null) + { + return $this->getBase("realm", "realms.realm", $uuid); + } + + public function delItemAction($uuid) + { + return $this->delBase("realms.realm", $uuid); + } + + public function toggleItemAction($uuid, $enabled = null) + { + return $this->toggleBase("realms.realm", $uuid, $enabled); + } +} diff --git a/net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/Api/RewritesController.php b/net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/Api/RewritesController.php new file mode 100644 index 000000000..c1fb95d92 --- /dev/null +++ b/net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/Api/RewritesController.php @@ -0,0 +1,67 @@ +searchBase( + "rewrites.rewrite", + array('enabled', 'name', 'description'), + "name" + ); + } + + public function setItemAction($uuid) + { + return $this->setBase("rewrite", "rewrites.rewrite", $uuid); + } + + public function addItemAction() + { + return $this->addBase("rewrite", "rewrites.rewrite"); + } + + public function getItemAction($uuid = null) + { + return $this->getBase("rewrite", "rewrites.rewrite", $uuid); + } + + public function delItemAction($uuid) + { + return $this->delBase("rewrites.rewrite", $uuid); + } + + public function toggleItemAction($uuid, $enabled = null) + { + return $this->toggleBase("rewrites.rewrite", $uuid, $enabled); + } +} diff --git a/net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/Api/ServersController.php b/net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/Api/ServersController.php new file mode 100644 index 000000000..55394aa5e --- /dev/null +++ b/net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/Api/ServersController.php @@ -0,0 +1,67 @@ +searchBase( + "servers.server", + array('description', 'host', 'type', 'identifier', 'tlsConfig'), + "name" + ); + } + + public function setItemAction($uuid) + { + return $this->setBase("server", "servers.server", $uuid); + } + + public function addItemAction() + { + return $this->addBase("server", "servers.server"); + } + + public function getItemAction($uuid = null) + { + return $this->getBase("server", "servers.server", $uuid); + } + + public function delItemAction($uuid) + { + return $this->delBase("servers.server", $uuid); + } + + public function toggleItemAction($uuid, $enabled = null) + { + return $this->toggleBase("servers.server", $uuid, $enabled); + } +} diff --git a/net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/Api/ServiceController.php b/net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/Api/ServiceController.php new file mode 100644 index 000000000..2aebebd84 --- /dev/null +++ b/net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/Api/ServiceController.php @@ -0,0 +1,40 @@ +searchBase( + "tlsConfigs.tlsConfig", + array('description', 'name', 'caCertificateRefId', 'proxyCertificateRefId'), + "name" + ); + } + + public function setItemAction($uuid) + { + return $this->setBase("tlsConfig", "tlsConfigs.tlsConfig", $uuid); + } + + public function addItemAction() + { + return $this->addBase("tlsConfig", "tlsConfigs.tlsConfig"); + } + + public function getItemAction($uuid = null) + { + return $this->getBase("tlsConfig", "tlsConfigs.tlsConfig", $uuid); + } + + public function delItemAction($uuid) + { + return $this->delBase("tlsConfigs.tlsConfig", $uuid); + } + + public function toggleItemAction($uuid, $enabled = null) + { + return $this->toggleBase("tlsConfigs.tlsConfig", $uuid, $enabled); + } +} diff --git a/net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/ClientsController.php b/net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/ClientsController.php new file mode 100644 index 000000000..91e92ce29 --- /dev/null +++ b/net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/ClientsController.php @@ -0,0 +1,36 @@ +view->generalForm = $this->getForm("clients"); + // pick the template to serve to our users. + $this->view->pick('OPNsense/RadSecProxy/clients'); + $this->view->formDialogClient = $this->getForm("dialogClient"); + } +} diff --git a/net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/GeneralController.php b/net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/GeneralController.php new file mode 100644 index 000000000..5c17d3cd8 --- /dev/null +++ b/net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/GeneralController.php @@ -0,0 +1,34 @@ +view->generalForm = $this->getForm("general"); + $this->view->pick('OPNsense/RadSecProxy/general'); + } +} diff --git a/net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/IndexController.php b/net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/IndexController.php new file mode 100644 index 000000000..3596535ac --- /dev/null +++ b/net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/IndexController.php @@ -0,0 +1,34 @@ +view->basicForm = $this->getForm("basic"); + $this->view->pick('OPNsense/RadSecProxy/index'); + } +} diff --git a/net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/RealmsController.php b/net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/RealmsController.php new file mode 100644 index 000000000..d227bbac1 --- /dev/null +++ b/net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/RealmsController.php @@ -0,0 +1,34 @@ +view->pick('OPNsense/RadSecProxy/realms'); + $this->view->formDialogRealm = $this->getForm("dialogRealm"); + } +} diff --git a/net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/RewritesController.php b/net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/RewritesController.php new file mode 100644 index 000000000..92869405e --- /dev/null +++ b/net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/RewritesController.php @@ -0,0 +1,36 @@ +view->generalForm = $this->getForm("clients"); + // pick the template to serve to our users. + $this->view->pick('OPNsense/RadSecProxy/rewrites'); + $this->view->formDialogRewrite = $this->getForm("dialogRewrite"); + } +} diff --git a/net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/ServersController.php b/net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/ServersController.php new file mode 100644 index 000000000..98186c101 --- /dev/null +++ b/net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/ServersController.php @@ -0,0 +1,34 @@ +view->pick('OPNsense/RadSecProxy/servers'); + $this->view->formDialogServer = $this->getForm("dialogServer"); + } +} diff --git a/net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/TlsController.php b/net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/TlsController.php new file mode 100644 index 000000000..146157e55 --- /dev/null +++ b/net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/TlsController.php @@ -0,0 +1,34 @@ +view->pick('OPNsense/RadSecProxy/tls'); + $this->view->formDialogTls = $this->getForm("dialogTls"); + } +} diff --git a/net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/forms/dialogClient.xml b/net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/forms/dialogClient.xml new file mode 100644 index 000000000..127ff5768 --- /dev/null +++ b/net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/forms/dialogClient.xml @@ -0,0 +1,96 @@ +
+ + + section_title + + + + + client.enabled + + checkbox + Allow connections from this client + + + + client.identifier + + text + Unique identifier for this client + + + + client.description + + text + Short description of this client + + + + client.host + + text + The client's IP or net + + + + client.type + + dropdown + Choose the type of client. Default Radius-clients use UDP. + + + + client.secret + + text + The shared RADIUS key with this client. This option is optional for TLS/DTLS and if omitted will default to "radsec". (Note that using a secret other than "radsec" for TLS is a violation of the standard (RFC 6614) and that the proposed standard for DTLS stipulates that the secret must be "radius/dtls".) + + + + section_title + + true + + + + client.tlsConfig + + true + dropdown + For a TLS/DTLS client you may also specify the tls option. The option value must be the name of a previously defined TLS block. If this option is not specified, the TLS block with the name defaultClient or default will be used if defined (in that order). If the specified TLS block name does not exist, or the option is not specified and none of the defaults exist, the proxy will exit with an error. + + + + client.certificateNameCheck + + true + dropdown + For a TLS/DTLS server, disable the default behaviour of matching CN or SubjectAltName against the specified hostname or IP address. + + + + client.matchCertificateAttribute + + true + text + Perform additional validation of certificate attributes (CN | SubjectAltName:URI | SubjectAltName:DNS). Currently matching of CN and SubjectAltName types URI DNS and IP is supported. + + + + client.rewriteIn + + true + dropdown + RewriteIn is not configured, the rewrite blocks defaultClient or default will be applied if defined. No default blocks are applied for RewriteOut.]]> + + + + client.rewriteOut + + true + dropdown + RewriteIn is not configured, the rewrite blocks defaultClient or default will be applied if defined. No default blocks are applied for RewriteOut.]]> + + +
diff --git a/net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/forms/dialogRealm.xml b/net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/forms/dialogRealm.xml new file mode 100644 index 000000000..6c270fed7 --- /dev/null +++ b/net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/forms/dialogRealm.xml @@ -0,0 +1,71 @@ +
+ + + section_title + + + + + realm.enabled + + checkbox + Enable this realm + + + + realm.realm + + text + * | realm | /regex/ + + + + realm.description + + text + Short description to identify this realm and its target + + + + section_title + + + + + realm.server + + select_multiple + true + + If not configured, the proxy will deny all Access-Requests for this realm. + + + + realm.replyMessage + + text + server is configured.]]> + + + + section_title + + + + + realm.accountingServer + + select_multiple + true + + If not configured, the proxy will silently ignore all Accounting-Requests for this realm. + + + + realm.accountingResponse + + dropdown + accoutingServer is configured.]]> + + +
diff --git a/net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/forms/dialogRewrite.xml b/net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/forms/dialogRewrite.xml new file mode 100644 index 000000000..ca8ef6092 --- /dev/null +++ b/net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/forms/dialogRewrite.xml @@ -0,0 +1,101 @@ +
+ + + rewrite.enabled + + checkbox + Use this rule + + + + rewrite.name + + text + Unique name for this rule + + + + rewrite.description + + text + Short description of this rule + + + + rewrite.addAttributes + + textbox + attribute:value, one per line
Add an attribute to the radius message and set it to value. The attribute must be specified using the numerical attribute id. The value can either be numerical, a string, or a hex value. If the value starts with a number, it is interpreted as a 32bit unsigned integer. Use the ’ character at the start of the value to force string interpretation. When using hex value, it is recommended to also lead with ’ to avoid unintended numeric interpretation. See the CONFIGURATION SYNTAX section for further details.]]>
+
+ + + rewrite.addVendorAttributes + + textbox + vendor:subattribute:value, one per line
Add a vendor attribute to the radius message, specified by vendor and subattribute. Both vendor and subattribute must be specified as numerical values. The format of value is the same as for addAttribute above.]]>
+
+ + + rewrite.supplementAttributes + + textbox + attribute:value, one per line
Add an attribute to the radius message and set it to value, only if the attribute is not yet present on the message. The format of value is the same as for addAttribute above.]]>
+
+ + + rewrite.supplementVendorAttributes + + textbox + vendor:subattribute:value, one per line
Add a vendor attribute to the radius message only if the subattribute of this vendor is not yet present on the message. The format of is the same as for addVendorAttribute above.]]>
+
+ + + rewrite.modifyAttributes + + textbox + attribute:/regex/replace/, one per line
Modify the given attribute using the regex replace pattern. As above, attribute must be specified by a numerical value. Example usage: modifyAttribute 1:/^(.*)@local$/\1@example.com/]]>
+
+ + + rewrite.modifyVendorAttributes + + textbox + vendor:subattribute:/regex/replace/, one per line
Modify the given subattribute of given vendor using the regex replace pattern. Other than the added vendor, the same syntax as for ModifyAttribute applies.]]>
+
+ + + rewrite.removeAttributes + + textbox + attribute, one per line
Remove all attributes with the given id.]]>
+
+ + + rewrite.removeVendorAttributes + + textbox + vendor[:subattribute], one per line
Remove all vendor attributes that match the given vendor and subattribute. If the subattribute is omitted, all attributes with the given vendor id are removed.]]>
+
+ + + rewrite.whitelistMode + + dropdown + WhitelistAttribute or WhitelistVendorAttribute will be removed. While whitelist mode is active, RemoveAttribute and RemoveVendorAttribute statements are ignored.]]> + + + + rewrite.whitelistAttributes + + textbox + attribute, one per line
Do not remove attributes with the given id when WhitelistMode is on. Ignored otherwise.]]>
+
+ + + rewrite.whitelistVendorAttributes + + textbox + vendor[:subattribute], one per line
Do not remove vendor attributes that match the given vendor and subattribute when WhitelistMode is on. Ignored otherwise. If the subattribute is omitted, the complete vendor attribute is whitelisted. Otherwise only the specified subattribute is kept but all other subattributes are removed.]]>
+
+ +
diff --git a/net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/forms/dialogServer.xml b/net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/forms/dialogServer.xml new file mode 100644 index 000000000..ce44adcb9 --- /dev/null +++ b/net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/forms/dialogServer.xml @@ -0,0 +1,102 @@ +
+ + + section_title + + + + + server.identifier + + text + Unique identifier for this server + + + + server.description + + text + Short description to identify this server + + + + server.host + + text + The server's IP or hostname to connect to + + + + server.port + + text + The port (UDP/TCP) to connect to. If omitted, UDP and TCP will default to 1812 while TLS and DTLS will default to 2083. + + + + server.statusServer + + dropdown + off). If statusserver is enabled (on), the proxy will send regular status-server messages to the server to verify that it is alive. Status tracking of the server will solely depend on status-server message and ignore lost requests. This should only be enabled if the server supports it. With the option minimal status-server messages are only sent when regular requests have been lost and no other replies have been received.]]> + + + + server.type + + dropdown + Choose the type of server. Default Radius-clients use UDP. + + + + server.secret + + text + The shared RADIUS key with this server. This option is optional for TLS/DTLS and if omitted will default to "radsec". (Note that using a secret other than "radsec" for TLS is a violation of the standard (RFC 6614) and that the proposed standard for DTLS stipulates that the secret must be "radius/dtls".) + + + + server.tlsConfig + + dropdown + For a TLS/DTLS client you may also specify the tls option. The option value must be the name of a previously defined TLS block. If this option is not specified, the TLS block with the name defaultClient or default will be used if defined (in that order). If the specified TLS block name does not exist, or the option is not specified and none of the defaults exist, the proxy will exit with an error. + + + + section_title + + true + + + + server.certificateNameCheck + + true + dropdown + For a TLS/DTLS server, disable the default behaviour of matching CN or SubjectAltName against the specified hostname or IP address. + + + + server.matchCertificateAttribute + + true + text + Perform additional validation of certificate attributes (CN | SubjectAltName:URI | SubjectAltName:DNS). Currently matching of CN and SubjectAltName types URI DNS and IP is supported. Note that currently this option can only be specified once in a client block. + + + + server.rewriteIn + + true + dropdown + RewriteIn is not configured, the rewrite blocks defaultClient or default will be applied if defined. No default blocks are applied for RewriteOut.]]> + + + + server.rewriteOut + + true + dropdown + RewriteIn is not configured, the rewrite blocks defaultClient or default will be applied if defined. No default blocks are applied for RewriteOut.]]> + + +
diff --git a/net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/forms/dialogTls.xml b/net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/forms/dialogTls.xml new file mode 100644 index 000000000..240d91266 --- /dev/null +++ b/net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/forms/dialogTls.xml @@ -0,0 +1,68 @@ +
+ + + section_title + + + + + tlsConfig.name + + text + This TLS-config's unique name + + + + tlsConfig.description + + text + Short description to identify this TLS-config + + + + tlsConfig.caCertificateRefId + + dropdown + The CA certificate file used to verify the peers certificate. + + + + tlsConfig.proxyCertificateRefId + + dropdown + The server certificate this proxy will use. The file may also contain a certificate chain. + + + + section_title + + true + + + + tlsConfig.policyOids + + true + select_multiple + + true + Require the peers certificate to adhere to the policy specified by this oid / these oids. + + + + tlsConfig.crlCheck + + true + dropdown + fetch-crl.]]> + + + + tlsConfig.cacheExpiry + + true + text + Specify how many seconds the CA and CRL information should be cached. By default, the CA and CRL are loaded at startup and cached indefinetely. This option may be set to zero to disable caching. + + +
diff --git a/net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/forms/general.xml b/net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/forms/general.xml new file mode 100644 index 000000000..eaf9611ed --- /dev/null +++ b/net/radsecproxy/src/opnsense/mvc/app/controllers/OPNsense/RadSecProxy/forms/general.xml @@ -0,0 +1,121 @@ +
+ + + radsecproxy.general.enabled + + checkbox + + + + radsecproxy.general.logLevel + + dropdown + This option specifies the debug level. It must be set to 1, 2, 3, 4 or 5, where 1 logs only serious errors, and 5 logs everything. The default is 2 which logs errors, warnings and a few informational messages. + + + + radsecproxy.general.logFullUsername + + dropdown + This can be set to off to only log the realm in Access-Accept/Reject log messages (for privacy). + + + + radsecproxy.general.logMac + + dropdown + Static, Original, VendorHashed, VendorKeyHashed, FullyHashed or FullyKeyHashed. The default value for LogMAC is Original.]]> + + + + radsecproxy.general.loopPrevention + + dropdown + When this is enabled (on), a request will never be sent to a server named the same as the client it was received from. I.e., the names of the client block and the server block are compared. Note that this only gives limited protection against loops. It can be used as a basic option and inside server blocks where it overrides the basic setting. + + + + section_title + + true + + + + section_title + + true + Listen for the address and port for the respective protocol. Normally the proxy will listen to the standard ports if configured to handle clients with the respective protocol. The default ports are 1812 for UDP and TCP and 2083 for TLS and DTLS. On most systems it will do this for all of the system’s IP addresses (both IPv4 and IPv6). On some systems however, it may respond to only IPv4 or only IPv6. To specify an alternate port you may use a value on the form *:port where port is any valid port number. If you also want to specify a specific address you can do e.g. 192.168.1.1:1812 or [2001:db8::1]:1812. The port may be omitted if you want the default one. Note that you must use brackets around the IPv6 address. These options may be specified multiple times to listen to multiple addresses and/or ports for each protocol. + + + + radsecproxy.general.listenUdp + + text + true + + + + + radsecproxy.general.listenTcp + + text + true + + + + + radsecproxy.general.listenTls + + text + true + + + + + radsecproxy.general.listenDtls + + text + true + + + + + section_title + + true + This can be used to specify source address and/or source port that the proxy will use for connecting to clients to send messages (e.g. Access Request). The same syntax as for Listen... applies. + + + + radsecproxy.general.sourceUdp + + text + true + + + + + radsecproxy.general.sourceTcp + + text + true + + + + + radsecproxy.general.sourceTls + + text + true + + + + + radsecproxy.general.sourceDtls + + text + true + + + +
diff --git a/net/radsecproxy/src/opnsense/mvc/app/models/OPNsense/RadSecProxy/Menu/Menu.xml b/net/radsecproxy/src/opnsense/mvc/app/models/OPNsense/RadSecProxy/Menu/Menu.xml new file mode 100644 index 000000000..65b18340f --- /dev/null +++ b/net/radsecproxy/src/opnsense/mvc/app/models/OPNsense/RadSecProxy/Menu/Menu.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + + diff --git a/net/radsecproxy/src/opnsense/mvc/app/models/OPNsense/RadSecProxy/RadSecProxy.php b/net/radsecproxy/src/opnsense/mvc/app/models/OPNsense/RadSecProxy/RadSecProxy.php new file mode 100644 index 000000000..31e1b506e --- /dev/null +++ b/net/radsecproxy/src/opnsense/mvc/app/models/OPNsense/RadSecProxy/RadSecProxy.php @@ -0,0 +1,31 @@ + + //OPNsense/radsecproxy + + RadSecProxy-Management + + 0.0.1 + + + + + 0 + Y + + + + Y + 2 + + 1 (only serious errors) + 2 (default) + 3 + 4 + 5 (log everything) + + + + + Y + off + + On + Off + + + + + Y + Original + + Static + Original + VendorHashed + VendorKeyHashed + FullyHashed + FullyKeyHashed + + + + + Y + on + + On + Off + + + + + N + + + + N + + + + N + + + + N + + + + N + + + + N + + + + N + + + + N + + + + + + + + + 1 + Y + + + + Y + /^([0-9a-zA-Z_\-]){1,25}$/u + Should be a string between 1 and 25 characters whithout special characters. + + + UniqueConstraint + Identifier already in use + + + + + + N + + + + Y + Y + + + UniqueConstraint + + + + + + Y + udp + + UDP + TCP + TLS + DTLS + + + + + N + + + Must be set for UDP-clients. + SetIfConstraint + type + udp + + + Must be set for TCP-clients. + SetIfConstraint + type + tcp + + + + + + N + + + OPNsense.RadSecProxy.RadSecProxy + tlsConfigs.tlsConfig + name + + + + + + Y + off + + On + Off + + + + + N + + + + N + + + OPNsense.RadSecProxy.RadSecProxy + rewrites.rewrite + name + + + + + + N + + + OPNsense.RadSecProxy.RadSecProxy + rewrites.rewrite + name + + + + + + + + + + + + Y + /^([0-9a-zA-Z_\-]){1,25}$/u + Should be a string between 1 and 25 characters whithout special characters. + + + UniqueConstraint + Identifier already in use + + + + + + N + + + + Y + Y + + + + N + + + + Y + off + + On + Off + Minimal + Auto + + + + + Y + udp + + UDP + TCP + TLS + DTLS + + + + + N + + + Must be set for UDP-servers. + SetIfConstraint + type + udp + + + Must be set for TCP-servers. + SetIfConstraint + type + tcp + + + + + + N + + + OPNsense.RadSecProxy.RadSecProxy + tlsConfigs.tlsConfig + name + + + + + + Y + off + + On + Off + + + + + N + + + + N + + + OPNsense.RadSecProxy.RadSecProxy + rewrites.rewrite + name + + + + + + N + + + OPNsense.RadSecProxy.RadSecProxy + rewrites.rewrite + name + + + + + + + + + + + + Y + /^([0-9a-zA-Z_\-]){1,25}$/u + Should be a string between 1 and 25 characters whithout special characters. + default + + + UniqueConstraint + Name already in use + + + + + + N + + + + Y + Field is required + ca + + + + Y + Field is required + cert + + + + N + Y + + + + Y + off + + On + Off + + + + + N + + + + + + + + + + 1 + Y + + + + N + + + + Y + Must not be empty + + + UniqueConstraint + Must be unique + + + + + + Y + N + Y + + + OPNsense.RadSecProxy.RadSecProxy + servers.server + identifier + + + Related server not found + + + + Y + N + Y + + + OPNsense.RadSecProxy.RadSecProxy + servers.server + identifier + + + Related server not found + + + + Y + off + + On + Off + + + + + N + + + + + + + + + + 1 + Y + + + + Y + /^([0-9a-zA-Z_\-]){1,25}$/u + Should be a string between 1 and 25 characters whithout special characters. + default + + + UniqueConstraint + Name already in use + + + + + + N + + + + N + + + + N + + + + N + + + + N + + + + N + + + + N + + + + N + + + + Y + off + + On + Off + + + + + N + + + + N + + + + + + diff --git a/net/radsecproxy/src/opnsense/mvc/app/views/OPNsense/RadSecProxy/clients.volt b/net/radsecproxy/src/opnsense/mvc/app/views/OPNsense/RadSecProxy/clients.volt new file mode 100644 index 000000000..33e7413f2 --- /dev/null +++ b/net/radsecproxy/src/opnsense/mvc/app/views/OPNsense/RadSecProxy/clients.volt @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + +
{{ lang._('ID') }}{{ lang._('Enabled') }}{{ lang._('Type') }}{{ lang._('Host') }}{{ lang._('Identifier') }}{{ lang._('Description') }}{{ lang._('Commands') }}
+ + +
+ +
+ +
+ +{{ partial("layout_partials/base_dialog",['fields':formDialogClient,'id':'DialogClient','label':lang._('Edit client')])}} diff --git a/net/radsecproxy/src/opnsense/mvc/app/views/OPNsense/RadSecProxy/general.volt b/net/radsecproxy/src/opnsense/mvc/app/views/OPNsense/RadSecProxy/general.volt new file mode 100644 index 000000000..1508a57b5 --- /dev/null +++ b/net/radsecproxy/src/opnsense/mvc/app/views/OPNsense/RadSecProxy/general.volt @@ -0,0 +1,31 @@ + +
+ {{ partial("layout_partials/base_form",['fields':generalForm,'id':'frm_GeneralSettings'])}} + +
+
+ +
+
diff --git a/net/radsecproxy/src/opnsense/mvc/app/views/OPNsense/RadSecProxy/realms.volt b/net/radsecproxy/src/opnsense/mvc/app/views/OPNsense/RadSecProxy/realms.volt new file mode 100644 index 000000000..974842f40 --- /dev/null +++ b/net/radsecproxy/src/opnsense/mvc/app/views/OPNsense/RadSecProxy/realms.volt @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + +
{{ lang._('ID') }}{{ lang._('Enabled') }}{{ lang._('Realm') }}{{ lang._('Description') }}{{ lang._('Commands') }}
+ + +
+ +
+ +
+ +{{ partial("layout_partials/base_dialog",['fields':formDialogRealm,'id':'DialogRealm','label':lang._('Edit realm')])}} diff --git a/net/radsecproxy/src/opnsense/mvc/app/views/OPNsense/RadSecProxy/rewrites.volt b/net/radsecproxy/src/opnsense/mvc/app/views/OPNsense/RadSecProxy/rewrites.volt new file mode 100644 index 000000000..ded628966 --- /dev/null +++ b/net/radsecproxy/src/opnsense/mvc/app/views/OPNsense/RadSecProxy/rewrites.volt @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + +
{{ lang._('ID') }}{{ lang._('Enabled') }}{{ lang._('Type') }}{{ lang._('Description') }}{{ lang._('Commands') }}
+ + +
+ +
+ +
+ +{{ partial("layout_partials/base_dialog",['fields':formDialogRewrite,'id':'DialogRewrite','label':lang._('Edit rewrite-rule')])}} diff --git a/net/radsecproxy/src/opnsense/mvc/app/views/OPNsense/RadSecProxy/servers.volt b/net/radsecproxy/src/opnsense/mvc/app/views/OPNsense/RadSecProxy/servers.volt new file mode 100644 index 000000000..058186999 --- /dev/null +++ b/net/radsecproxy/src/opnsense/mvc/app/views/OPNsense/RadSecProxy/servers.volt @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + +
{{ lang._('ID') }}{{ lang._('Host') }}{{ lang._('Identifier') }}{{ lang._('Description') }}{{ lang._('Type') }}{{ lang._('TLS-Config') }}{{ lang._('Commands') }}
+ + +
+ +
+ +
+ +{{ partial("layout_partials/base_dialog",['fields':formDialogServer,'id':'DialogServer','label':lang._('Edit server')])}} diff --git a/net/radsecproxy/src/opnsense/mvc/app/views/OPNsense/RadSecProxy/tls.volt b/net/radsecproxy/src/opnsense/mvc/app/views/OPNsense/RadSecProxy/tls.volt new file mode 100644 index 000000000..353348605 --- /dev/null +++ b/net/radsecproxy/src/opnsense/mvc/app/views/OPNsense/RadSecProxy/tls.volt @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + +
{{ lang._('ID') }}{{ lang._('Name') }}{{ lang._('Description') }}{{ lang._('CA-certificate') }}{{ lang._('Proxy-certificate') }}{{ lang._('Commands') }}
+ + +
+ +
+ +
+ +{{ partial("layout_partials/base_dialog",['fields':formDialogTls,'id':'DialogTls','label':lang._('Edit TLS-config')])}} diff --git a/net/radsecproxy/src/opnsense/scripts/OPNsense/RadSecProxy/generate_certs.php b/net/radsecproxy/src/opnsense/scripts/OPNsense/RadSecProxy/generate_certs.php new file mode 100755 index 000000000..9414db161 --- /dev/null +++ b/net/radsecproxy/src/opnsense/scripts/OPNsense/RadSecProxy/generate_certs.php @@ -0,0 +1,105 @@ +#!/usr/local/bin/php +object(); + +deleteFilesInFolder($outputFolder); +if (isset($configObj->OPNsense->radsecproxy->tlsConfigs)) { + foreach ($configObj->OPNsense->radsecproxy->tlsConfigs->children() as $tlsConfig) { + echo "parsing TLS-config \"" . $tlsConfig->name . "\"\n"; + + $caCertRefId = (string)$tlsConfig->caCertificateRefId; + $proxyCertRefId = (string)$tlsConfig->proxyCertificateRefId; + + if ($caCertRefId != "") { + echo "looking for CA-cert-file\n"; + foreach ($configObj->ca as $ca) { + if ($caCertRefId == (string)$ca->refid) { + echo "creating CA-cert-files from \"" . $ca->descr . "\"\n"; + writeCertFile($outputFolder . $tlsConfig->name . "_ca-cert.pem", $ca->crt); + } + } + } + + if ($proxyCertRefId != "") { + foreach ($configObj->cert as $cert) { + if ($proxyCertRefId == (string)$cert->refid) { + echo "creating proxy-cert-files from \"" . $cert->descr . "\"\n"; + writeCertFile($outputFolder . $tlsConfig->name . "_proxy-cert.pem", $cert->crt); + writeCertFile($outputFolder . $tlsConfig->name . "_proxy-key.pem", $cert->prv); + } + } + } + } +} else { + echo "no TLS-configs found\n"; +} diff --git a/net/radsecproxy/src/opnsense/scripts/OPNsense/RadSecProxy/setup.sh b/net/radsecproxy/src/opnsense/scripts/OPNsense/RadSecProxy/setup.sh new file mode 100755 index 000000000..cd09c51f9 --- /dev/null +++ b/net/radsecproxy/src/opnsense/scripts/OPNsense/RadSecProxy/setup.sh @@ -0,0 +1,18 @@ +#!/bin/sh + +RADSECPROXY_DIRS="/usr/local/etc/radsecproxy.d /usr/local/etc/radsecproxy.d/certs" + +for directory in ${RADSECPROXY_DIRS}; do + mkdir -p ${directory} + chown -R www:www ${directory} + chmod -R 750 ${directory} +done + + +# export required certs to filesystem +/usr/local/opnsense/scripts/OPNsense/RadSecProxy/generate_certs.php > /dev/null 2>&1 + +# remove logfile - sometimes it will stop radsecproxy from starting +#rm /var/log/radsecproxy.log + +exit 0 diff --git a/net/radsecproxy/src/opnsense/service/conf/actions.d/actions_radsecproxy.conf b/net/radsecproxy/src/opnsense/service/conf/actions.d/actions_radsecproxy.conf new file mode 100644 index 000000000..42dfe2296 --- /dev/null +++ b/net/radsecproxy/src/opnsense/service/conf/actions.d/actions_radsecproxy.conf @@ -0,0 +1,35 @@ +[setup] +command:/usr/local/opnsense/scripts/OPNsense/RadSecProxy/setup.sh; +parameters: +type:script +message:setup radsecproxy service requirements + +[start] +command:/usr/local/opnsense/scripts/OPNsense/RadSecProxy/setup.sh;/usr/local/etc/rc.d/radsecproxy start; +parameters: +type:script +message:starting radsecproxy + +[stop] +command:/usr/local/etc/rc.d/radsecproxy stop; +parameters: +type:script +message:stopping radsecproxy + +[restart] +command:/usr/local/opnsense/scripts/OPNsense/RadSecProxy/setup.sh;/usr/local/etc/rc.d/radsecproxy restart; +parameters: +type:script +message:restarting radsecproxy + +[reload] +command:/usr/local/opnsense/scripts/OPNsense/RadSecProxy/setup.sh;/usr/local/etc/rc.d/radsecproxy restart; +parameters: +type:script +message:reloading radsecproxy + +[status] +command:/usr/local/etc/rc.d/radsecproxy status;exit 0; +parameters: +type:script_output +message:radsecproxy status diff --git a/net/radsecproxy/src/opnsense/service/templates/OPNsense/RadSecProxy/+TARGETS b/net/radsecproxy/src/opnsense/service/templates/OPNsense/RadSecProxy/+TARGETS new file mode 100644 index 000000000..294d4f30d --- /dev/null +++ b/net/radsecproxy/src/opnsense/service/templates/OPNsense/RadSecProxy/+TARGETS @@ -0,0 +1,2 @@ +radsecproxy.conf:/usr/local/etc/radsecproxy.conf +rc.conf.d:/etc/rc.conf.d/radsecproxy diff --git a/net/radsecproxy/src/opnsense/service/templates/OPNsense/RadSecProxy/radsecproxy.conf b/net/radsecproxy/src/opnsense/service/templates/OPNsense/RadSecProxy/radsecproxy.conf new file mode 100644 index 000000000..b0563b335 --- /dev/null +++ b/net/radsecproxy/src/opnsense/service/templates/OPNsense/RadSecProxy/radsecproxy.conf @@ -0,0 +1,240 @@ +{% if helpers.exists('OPNsense.radsecproxy.general') and OPNsense.radsecproxy.general.enabled|default("0") == "1" %} +{% set certDir = '/usr/local/etc/radsecproxy.d/certs/' %} +# auto-generated config-file for radsecproxy +########################################### +# GENERAL +########################################### + +#PidFile /var/run/radsecproxy.pid +#LogDestination file:///var/log/radsecproxy.log +LogDestination x-syslog:///LOG_DAEMON + +{% if OPNsense.radsecproxy.general.logLevel is defined and OPNsense.radsecproxy.general.logLevel != "" %} +LogLevel {{ OPNsense.radsecproxy.general.logLevel }} +{% endif %} +{% if OPNsense.radsecproxy.general.logFullUsername is defined and OPNsense.radsecproxy.general.logFullUsername != "" %} +LogFullUsername {{ OPNsense.radsecproxy.general.logFullUsername }} +{% endif %} +{% if OPNsense.radsecproxy.general.logMac is defined and OPNsense.radsecproxy.general.logMac != "" %} +LogMac {{ OPNsense.radsecproxy.general.logMac }} +{% endif %} +{% if OPNsense.radsecproxy.general.loopPrevention is defined and OPNsense.radsecproxy.general.loopPrevention != "" %} +LoopPrevention {{ OPNsense.radsecproxy.general.loopPrevention }} +{% endif %} +{% if OPNsense.radsecproxy.general.listenUdp is defined and OPNsense.radsecproxy.general.listenUdp != "" %} +ListenUDP {{ OPNsense.radsecproxy.general.listenUdp }} +{% endif %} +{% if OPNsense.radsecproxy.general.listenTcp is defined and OPNsense.radsecproxy.general.listenTcp != "" %} +ListenTCP {{ OPNsense.radsecproxy.general.listenTcp }} +{% endif %} +{% if OPNsense.radsecproxy.general.listenTls is defined and OPNsense.radsecproxy.general.listenTls != "" %} +ListenTLS {{ OPNsense.radsecproxy.general.listenTls }} +{% endif %} +{% if OPNsense.radsecproxy.general.listenDtls is defined and OPNsense.radsecproxy.general.listenDtls != "" %} +ListenDTLS {{ OPNsense.radsecproxy.general.listenDtls }} +{% endif %} +{% if OPNsense.radsecproxy.general.sourceUdp is defined and OPNsense.radsecproxy.general.sourceUdp != "" %} +SourceUDP {{ OPNsense.radsecproxy.general.sourceUdp }} +{% endif %} +{% if OPNsense.radsecproxy.general.sourceTcp is defined and OPNsense.radsecproxy.general.sourceTcp != "" %} +SourceTCP {{ OPNsense.radsecproxy.general.sourceTcp }} +{% endif %} +{% if OPNsense.radsecproxy.general.sourceTls is defined and OPNsense.radsecproxy.general.sourceTls != "" %} +SourceTLS {{ OPNsense.radsecproxy.general.sourceTls }} +{% endif %} +{% if OPNsense.radsecproxy.general.sourceDtls is defined and OPNsense.radsecproxy.general.sourceDtls != "" %} +SourceDTLS {{ OPNsense.radsecproxy.general.sourceDtls }} +{% endif %} + +########################################### +# TLS-CONFIGS +########################################### + +{% for tlsConfig in helpers.toList('OPNsense.radsecproxy.tlsConfigs.tlsConfig') %} +# config for TLS-Config "{{ tlsConfig.description }}" +tls {{ tlsConfig.name }} { +{% if tlsConfig.caCertificateRefId is defined and tlsConfig.caCertificateRefId != "" %} + CACertificateFile {{ certDir}}{{ tlsConfig.name }}_ca-cert.pem +{% endif %} +{% if tlsConfig.proxyCertificateRefId is defined and tlsConfig.proxyCertificateRefId != "" %} + CertificateFile {{ certDir}}{{ tlsConfig.name }}_proxy-cert.pem + CertificateKeyFile {{ certDir}}{{ tlsConfig.name }}_proxy-key.pem +{% endif %} +{% if tlsConfig.policyOids is defined and tlsConfig.policyOids != "" %} +{% for policyOid in tlsConfig.policyOids.split(',') %} + PolicyOID {{ policyOid }} +{% endfor %} +{% endif %} + CRLCheck {{ tlsConfig.crlCheck }} +{% if tlsConfig.cacheExpiry is defined and tlsConfig.cacheExpiry != "" %} + CacheExpiry {{ tlsConfig.cacheExpiry }} +{% endif %} +} + +{% endfor %} + +########################################### +# REWRITE-RULES +########################################### + +{% for rewriteRule in helpers.toList('OPNsense.radsecproxy.rewrites.rewrite') %} +{% if rewriteRule.enabled is defined and rewriteRule.enabled == "1" %} + +rewrite {{ rewriteRule.name }} { +{% if rewriteRule.addAttributes is defined and rewriteRule.addAttributes != "" %} +{% for addAttribute in rewriteRule.addAttributes.split("\n") %} + AddAttribute {{ addAttribute }} +{% endfor %} +{% endif %} +{% if rewriteRule.addVendorAttributes is defined and rewriteRule.addVendorAttributes != "" %} +{% for addVendorAttribute in rewriteRule.addVendorAttributes.split("\n") %} + AddVendorAttribute {{ addVendorAttribute }} +{% endfor %} +{% endif %} +{% if rewriteRule.supplementAttributes is defined and rewriteRule.supplementAttributes != "" %} +{% for supplementAttribute in rewriteRule.supplementAttributes.split("\n") %} + SupplementAttribute {{ supplementAttribute }} +{% endfor %} +{% endif %} +{% if rewriteRule.supplementVendorAttributes is defined and rewriteRule.supplementVendorAttributes != "" %} +{% for supplementVendorAttribute in rewriteRule.supplementVendorAttributes.split("\n") %} + SupplementVendorAttribute {{ supplementVendorAttribute }} +{% endfor %} +{% endif %} +{% if rewriteRule.modifyAttributes is defined and rewriteRule.modifyAttributes != "" %} +{% for modifyAttribute in rewriteRule.modifyAttributes.split("\n") %} + ModifyAttribute {{ modifyAttribute }} +{% endfor %} +{% endif %} +{% if rewriteRule.modifyVendorAttributes is defined and rewriteRule.modifyVendorAttributes != "" %} +{% for modifyVendorAttribute in rewriteRule.modifyVendorAttributes.split("\n") %} + ModifyVendorAttribute {{ modifyVendorAttribute }} +{% endfor %} +{% endif %} +{% if rewriteRule.removeAttributes is defined and rewriteRule.removeAttributes != "" %} +{% for removeAttribute in rewriteRule.removeAttributes.split("\n") %} + RemoveAttribute {{ removeAttribute }} +{% endfor %} +{% endif %} +{% if rewriteRule.removeVendorAttributes is defined and rewriteRule.removeVendorAttributes != "" %} +{% for removeVendorAttribute in rewriteRule.removeVendorAttributes.split("\n") %} + RemoveVendorAttribute {{ removeVendorAttribute }} +{% endfor %} +{% endif %} + WhitelistMode {{ rewriteRule.whitelistMode }} +{% if rewriteRule.whitelistAttributes is defined and rewriteRule.whitelistAttributes != "" %} +{% for whitelistAttribute in rewriteRule.whitelistAttributes.split("\n") %} + WhitelistAttribute {{ whitelistAttribute }} +{% endfor %} +{% endif %} +{% if rewriteRule.whitelistVendorAttributes is defined and rewriteRule.whitelistVendorAttributes != "" %} +{% for whitelistVendorAttribute in rewriteRule.whitelistVendorAttributes.split("\n") %} + WhitelistVendorAttribute {{ whitelistVendorAttribute }} +{% endfor %} +{% endif %} +} +{% endif %} +{% endfor %} + +########################################### +# CLIENTS +########################################### + +{% for client in helpers.toList('OPNsense.radsecproxy.clients.client') %} +{% if client.enabled is defined and client.enabled == "1" %} +# config for client "{{ client.description }}" +client {{ client.identifier }} { + Host {{ client.host }} + Type {{ client.type }} +{% if client.secret is defined and client.secret != "" %} + Secret {{ client.secret }} +{% endif %} +{% if client.tlsConfig is defined and client.tlsConfig != "" %} +{% set tlsConfig = helpers.getUUID(client.tlsConfig) %} + Tls {{ tlsConfig.name }} +{% endif %} + CertificateNameCheck {{ client.certificateNameCheck }} +{% if client.matchCertificateAttribute is defined and client.matchCertificateAttribute != "" %} + matchCertificateAttribute {{ client.matchCertificateAttribute }} +{% endif %} +{% if client.rewriteIn is defined and client.rewriteIn != "" %} +{% set rewriteInRule = helpers.getUUID(client.rewriteIn) %} + RewriteIn {{ rewriteInRule.name }} +{% endif %} +{% if client.rewriteOut is defined and client.rewriteOut != "" %} +{% set rewriteOutRule = helpers.getUUID(client.rewriteOut) %} + RewriteOut {{ rewriteOutRule.name }} +{% endif %} +} + +{% else %} +# config for client "{{ client.description }}" not enabled, skipping!" + +{% endif %} +{% endfor %} + +########################################### +# SERVERS +########################################### + +{% for server in helpers.toList('OPNsense.radsecproxy.servers.server') %} +# config for server "{{ server.description }}" +server {{ server.identifier }} { + Host {{ server.host }} +{% if server.port is defined and server.port != "" %} + Port {{ server.port }} +{% endif %} + Type {{ server.type }} +{% if server.secret is defined and server.secret != "" %} + Secret {{ server.secret }} +{% endif %} +{% if server.tlsConfig is defined and server.tlsConfig != "" %} +{% set tlsConfig = helpers.getUUID(server.tlsConfig) %} + Tls {{ tlsConfig.name }} +{% endif %} + StatusServer {{ server.statusServer }} + CertificateNameCheck {{ server.certificateNameCheck }} +{% if server.matchCertificateAttribute is defined and server.matchCertificateAttribute != "" %} + matchCertificateAttribute {{ server.matchCertificateAttribute }} +{% endif %} +{% if server.rewriteIn is defined and server.rewriteIn != "" %} +{% set rewriteInRule = helpers.getUUID(server.rewriteIn) %} + RewriteIn {{ rewriteInRule.name }} +{% endif %} +{% if server.rewriteOut is defined and server.rewriteOut != "" %} +{% set rewriteOutRule = helpers.getUUID(server.rewriteOut) %} + RewriteOut {{ rewriteOutRule.name }} +{% endif %} +} + +{% endfor %} + +########################################### +# REALMS +########################################### + +{% for realm in helpers.toList('OPNsense.radsecproxy.realms.realm') %} +{% if realm.enabled is defined and realm.enabled == "1" %} +# config for realm "{{ realm.realm }}" +realm {{ realm.realm }} { +{% if realm.server is defined and realm.server != "" %} +{% for serverUuid in realm.server.split(',') %} +{% set server = helpers.getUUID(serverUuid) %} + Server {{ server.identifier }} +{% endfor %} +{% endif %} +{% if realm.replyMessage is defined and realm.replyMessage != "" %} + ReplyMessage "{{ realm.replyMessage }}" +{% endif %} +{% if realm.accountingResponse is defined and realm.accountingResponse != "" %} + AccountingResponse {{ realm.accountingResponse }} +{% endif %} +} + +{% else %} +# config for realm "{{ realm.realm }}" not enabled, skipping!" + +{% endif %} +{% endfor %} +{# END OF TEMPLATE #} +{% endif %} diff --git a/net/radsecproxy/src/opnsense/service/templates/OPNsense/RadSecProxy/rc.conf.d b/net/radsecproxy/src/opnsense/service/templates/OPNsense/RadSecProxy/rc.conf.d new file mode 100644 index 000000000..03409f3a7 --- /dev/null +++ b/net/radsecproxy/src/opnsense/service/templates/OPNsense/RadSecProxy/rc.conf.d @@ -0,0 +1,7 @@ +{% if helpers.exists('OPNsense.radsecproxy.general.enabled') and OPNsense.radsecproxy.general.enabled == '1' %} +radsecproxy_enable="YES" +{% else %} +radsecproxy_enable="NO" +{% endif %} +radsecproxy_user="root" +radsecproxy_group="wheel"