diff --git a/net/freeradius/Makefile b/net/freeradius/Makefile new file mode 100644 index 000000000..a2937ed2c --- /dev/null +++ b/net/freeradius/Makefile @@ -0,0 +1,7 @@ +PLUGIN_NAME= freeradius +PLUGIN_VERSION= 0.3.0 +PLUGIN_COMMENT= RADIUS Authentication, Authorization and Accounting Server +PLUGIN_DEPENDS= freeradius3 +PLUGIN_MAINTAINER= m.muenz@gmail.com + +.include "../../Mk/plugins.mk" diff --git a/net/freeradius/pkg-descr b/net/freeradius/pkg-descr new file mode 100644 index 000000000..cd8e1a5d6 --- /dev/null +++ b/net/freeradius/pkg-descr @@ -0,0 +1,16 @@ +FreeRADIUS includes a RADIUS server, a BSD licensed client library, +a PAM library, and an Apache module. In most cases, +the word FreeRADIUS refers to the RADIUS server. + +FreeRADIUS is the most widely deployed RADIUS server in the world. +It is the basis for multiple commercial offerings. +It supplies the AAA needs of many Fortune-500 +companies and Tier 1 ISPs. + +It is also widely used for Enterprise Wi-Fi and IEEE 802.1X +network security, particularly in the academic community, +including eduroam. + +The server is fast, feature-rich, modular, and scalable. + +WWW: http://www.freeradius.org diff --git a/net/freeradius/src/etc/inc/plugins.inc.d/freeradius.inc b/net/freeradius/src/etc/inc/plugins.inc.d/freeradius.inc new file mode 100644 index 000000000..e05bca519 --- /dev/null +++ b/net/freeradius/src/etc/inc/plugins.inc.d/freeradius.inc @@ -0,0 +1,49 @@ + gettext('FreeRADIUS'), + 'configd' => array( + 'restart' => array('freeradius restart'), + 'start' => array('freeradius start'), + 'stop' => array('freeradius stop'), + ), + 'name' => 'freeradius', + 'pidfile' => '/var/run/radiusd/radiusd.pid' + ); + } + + return $services; +} diff --git a/net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/Api/ClientController.php b/net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/Api/ClientController.php new file mode 100644 index 000000000..ca7705d27 --- /dev/null +++ b/net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/Api/ClientController.php @@ -0,0 +1,204 @@ +request->isGet()) { + $mdlClient = new Client(); + $result['client'] = $mdlClient->getNodes(); + } + return $result; + } + + public function setAction() + { + $result = array("result"=>"failed"); + if ($this->request->isPost()) { + // load model and update with provided data + $mdlClient = new Client(); + $mdlClient->setNodes($this->request->getPost("client")); + // perform validation + $valMsgs = $mdlClient->performValidation(); + foreach ($valMsgs as $field => $msg) { + if (!array_key_exists("validations", $result)) { + $result["validations"] = array(); + } + $result["validations"]["client.".$msg->getField()] = $msg->getMessage(); + } + // serialize model to config and save + if ($valMsgs->count() == 0) { + $mdlClient->serializeToConfig(); + Config::getInstance()->save(); + $result["result"] = "saved"; + } + } + return $result; + } + + public function searchClientAction() + { + $this->sessionClose(); + $mdlClient = $this->getModel(); + $grid = new UIModelGrid($mdlClient->clients->client); + return $grid->fetchBindRequest( + $this->request, + array("enabled", "name", "secret", "ip" ) + ); + } + + public function getClientAction($uuid = null) + { + $mdlClient = $this->getModel(); + if ($uuid != null) { + $node = $mdlClient->getNodeByReference('clients.client.' . $uuid); + if ($node != null) { + // return node + return array("client" => $node->getNodes()); + } + } else { + $node = $mdlClient->clients->client->add(); + return array("client" => $node->getNodes()); + } + return array(); + } + + public function addClientAction() + { + $result = array("result" => "failed"); + if ($this->request->isPost() && $this->request->hasPost("client")) { + $result = array("result" => "failed", "validations" => array()); + $mdlClient = $this->getModel(); + $node = $mdlClient->clients->client->Add(); + $node->setNodes($this->request->getPost("client")); + $valMsgs = $mdlClient->performValidation(); + foreach ($valMsgs as $field => $msg) { + $fieldnm = str_replace($node->__reference, "client", $msg->getField()); + $result["validations"][$fieldnm] = $msg->getMessage(); + } + if (count($result['validations']) == 0) { + unset($result['validations']); + // save config if validated correctly + $mdlClient->serializeToConfig(); + Config::getInstance()->save(); + unset($result['validations']); + $result["result"] = "saved"; + } + } + return $result; + } + + public function delClientAction($uuid) + { + $result = array("result" => "failed"); + if ($this->request->isPost()) { + $mdlClient = $this->getModel(); + if ($uuid != null) { + if ($mdlClient->clients->client->del($uuid)) { + $mdlClient->serializeToConfig(); + Config::getInstance()->save(); + $result['result'] = 'deleted'; + } else { + $result['result'] = 'not found'; + } + } + } + return $result; + } + + public function setClientAction($uuid) + { + if ($this->request->isPost() && $this->request->hasPost("client")) { + $mdlSetting = $this->getModel(); + if ($uuid != null) { + $node = $mdlSetting->getNodeByReference('clients.client.' . $uuid); + if ($node != null) { + $result = array("result" => "failed", "validations" => array()); + $clientInfo = $this->request->getPost("client"); + $node->setNodes($clientInfo); + $valMsgs = $mdlSetting->performValidation(); + foreach ($valMsgs as $field => $msg) { + $fieldnm = str_replace($node->__reference, "client", $msg->getField()); + $result["validations"][$fieldnm] = $msg->getMessage(); + } + if (count($result['validations']) == 0) { + // save config if validated correctly + $mdlSetting->serializeToConfig(); + Config::getInstance()->save(); + $result = array("result" => "saved"); + } + return $result; + } + } + } + return array("result" => "failed"); + } + + public function toggle_handler($uuid, $elements, $element) + { + $result = array("result" => "failed"); + if ($this->request->isPost()) { + $mdlSetting = $this->getModel(); + if ($uuid != null) { + $node = $mdlSetting->getNodeByReference($elements . '.'. $element .'.' . $uuid); + if ($node != null) { + if ($node->enabled->__toString() == "1") { + $result['result'] = "Disabled"; + $node->enabled = "0"; + } else { + $result['result'] = "Enabled"; + $node->enabled = "1"; + } + // if item has toggled, serialize to config and save + $mdlSetting->serializeToConfig(); + Config::getInstance()->save(); + } + } + } + return $result; + } + + public function toggleClientAction($uuid) + { + return $this->toggle_handler($uuid, 'clients', 'client'); + } +} diff --git a/net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/Api/GeneralController.php b/net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/Api/GeneralController.php new file mode 100644 index 000000000..1c9dd417f --- /dev/null +++ b/net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/Api/GeneralController.php @@ -0,0 +1,76 @@ +request->isGet()) { + $mdlGeneral = new General(); + $result['general'] = $mdlGeneral->getNodes(); + } + return $result; + } + + public function setAction() + { + $result = array("result"=>"failed"); + if ($this->request->isPost()) { + // load model and update with provided data + $mdlGeneral = new General(); + $mdlGeneral->setNodes($this->request->getPost("general")); + + // perform validation + $valMsgs = $mdlGeneral->performValidation(); + foreach ($valMsgs as $field => $msg) { + if (!array_key_exists("validations", $result)) { + $result["validations"] = array(); + } + $result["validations"]["general.".$msg->getField()] = $msg->getMessage(); + } + + // serialize model to config and save + if ($valMsgs->count() == 0) { + $mdlGeneral->serializeToConfig(); + Config::getInstance()->save(); + $result["result"] = "saved"; + } + } + return $result; + } +} diff --git a/net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/Api/ServiceController.php b/net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/Api/ServiceController.php new file mode 100644 index 000000000..7b4883e3c --- /dev/null +++ b/net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/Api/ServiceController.php @@ -0,0 +1,147 @@ +request->isPost()) { + $backend = new Backend(); + $response = $backend->configdRun("freeradius start", true); + return array("response" => $response); + } else { + return array("response" => array()); + } + } + + /** + * stop freeradius service + * @return array + */ + public function stopAction() + { + if ($this->request->isPost()) { + $backend = new Backend(); + $response = $backend->configdRun("freeradius stop"); + return array("response" => $response); + } else { + return array("response" => array()); + } + } + + /** + * restart freeradius service + * @return array + */ + public function restartAction() + { + if ($this->request->isPost()) { + $backend = new Backend(); + $response = $backend->configdRun("freeradius restart"); + return array("response" => $response); + } else { + return array("response" => array()); + } + } + + /** + * retrieve status of freeradius + * @return array + * @throws \Exception + */ + public function statusAction() + { + $backend = new Backend(); + $mdlGeneral = new General(); + $response = $backend->configdRun("freeradius status"); + + if (strpos($response, "not running") > 0) { + if ($mdlGeneral->enabled->__toString() == 1) { + $status = "stopped"; + } else { + $status = "disabled"; + } + } elseif (strpos($response, "is running") > 0) { + $status = "running"; + } elseif ($mdlGeneral->enabled->__toString() == 0) { + $status = "disabled"; + } else { + $status = "unkown"; + } + + + return array("status" => $status); + } + + /** + * reconfigure freeradius, generate config and reload + */ + public function reconfigureAction() + { + if ($this->request->isPost()) { + // close session for long running action + $this->sessionClose(); + + $mdlGeneral = new General(); + $backend = new Backend(); + + $runStatus = $this->statusAction(); + + // stop freeradius if it is running or not + $this->stopAction(); + + // generate template + $backend->configdRun('template reload OPNsense/Freeradius'); + + // (res)start daemon + if ($mdlGeneral->enabled->__toString() == 1) { + $this->startAction(); + } + + return array("status" => "ok"); + } else { + return array("status" => "failed"); + } + } +} diff --git a/net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/Api/UserController.php b/net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/Api/UserController.php new file mode 100644 index 000000000..3f56675c3 --- /dev/null +++ b/net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/Api/UserController.php @@ -0,0 +1,205 @@ +request->isGet()) { + $mdlUser = new User(); + $result['user'] = $mdlUser->getNodes(); + } + return $result; + } + + public function setAction() + { + $result = array("result"=>"failed"); + if ($this->request->isPost()) { + // load model and update with provided data + $mdlUser = new User(); + $mdlUser->setNodes($this->request->getPost("user")); + // perform validation + $valMsgs = $mdlUser->performValidation(); + foreach ($valMsgs as $field => $msg) { + if (!array_key_exists("validations", $result)) { + $result["validations"] = array(); + } + $result["validations"]["user.".$msg->getField()] = $msg->getMessage(); + } + // serialize model to config and save + if ($valMsgs->count() == 0) { + $mdlUser->serializeToConfig(); + Config::getInstance()->save(); + $result["result"] = "saved"; + } + } + return $result; + } + + public function searchUserAction() + { + $this->sessionClose(); + $mdlUser = $this->getModel(); + $grid = new UIModelGrid($mdlUser->users->user); + return $grid->fetchBindRequest( + $this->request, + array("enabled", "username", "password", "description", "ip", "subnet", "vlan" ) + ); + } + + public function getUserAction($uuid = null) + { + $mdlUser = $this->getModel(); + if ($uuid != null) { + $node = $mdlUser->getNodeByReference('users.user.' . $uuid); + if ($node != null) { + // return node + return array("user" => $node->getNodes()); + } + } else { + $node = $mdlUser->users->user->add(); + return array("user" => $node->getNodes()); + } + return array(); + } + + public function addUserAction() + { + $result = array("result" => "failed"); + if ($this->request->isPost() && $this->request->hasPost("user")) { + $result = array("result" => "failed", "validations" => array()); + $mdlUser = $this->getModel(); + $node = $mdlUser->users->user->Add(); + $node->setNodes($this->request->getPost("user")); + $valMsgs = $mdlUser->performValidation(); + foreach ($valMsgs as $field => $msg) { + $fieldnm = str_replace($node->__reference, "user", $msg->getField()); + $result["validations"][$fieldnm] = $msg->getMessage(); + } + if (count($result['validations']) == 0) { + unset($result['validations']); + // save config if validated correctly + $mdlUser->serializeToConfig(); + Config::getInstance()->save(); + unset($result['validations']); + $result["result"] = "saved"; + } + } + return $result; + } + + public function delUserAction($uuid) + { + $result = array("result" => "failed"); + if ($this->request->isPost()) { + $mdlUser = $this->getModel(); + if ($uuid != null) { + if ($mdlUser->users->user->del($uuid)) { + $mdlUser->serializeToConfig(); + Config::getInstance()->save(); + $result['result'] = 'deleted'; + } else { + $result['result'] = 'not found'; + } + } + } + return $result; + } + + public function setUserAction($uuid) + { + if ($this->request->isPost() && $this->request->hasPost("user")) { + $mdlSetting = $this->getModel(); + if ($uuid != null) { + $node = $mdlSetting->getNodeByReference('users.user.' . $uuid); + if ($node != null) { + $result = array("result" => "failed", "validations" => array()); + $userInfo = $this->request->getPost("user"); + $node->setNodes($userInfo); + $valMsgs = $mdlSetting->performValidation(); + foreach ($valMsgs as $field => $msg) { + $fieldnm = str_replace($node->__reference, "user", $msg->getField()); + $result["validations"][$fieldnm] = $msg->getMessage(); + } + if (count($result['validations']) == 0) { + // save config if validated correctly + $mdlSetting->serializeToConfig(); + Config::getInstance()->save(); + $result = array("result" => "saved"); + } + return $result; + } + } + } + return array("result" => "failed"); + } + + public function toggle_handler($uuid, $elements, $element) + { + $result = array("result" => "failed"); + if ($this->request->isPost()) { + $mdlSetting = $this->getModel(); + if ($uuid != null) { + $node = $mdlSetting->getNodeByReference($elements . '.'. $element .'.' . $uuid); + if ($node != null) { + if ($node->enabled->__toString() == "1") { + $result['result'] = "Disabled"; + $node->enabled = "0"; + } else { + $result['result'] = "Enabled"; + $node->enabled = "1"; + } + // if item has toggled, serialize to config and save + $mdlSetting->serializeToConfig(); + Config::getInstance()->save(); + } + } + } + return $result; + } + + public function toggleUserAction($uuid) + { + return $this->toggle_handler($uuid, 'users', 'user'); + } +} diff --git a/net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/ClientController.php b/net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/ClientController.php new file mode 100644 index 000000000..91079003c --- /dev/null +++ b/net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/ClientController.php @@ -0,0 +1,34 @@ +view->title = gettext("FreeRADIUS Clients"); + $this->view->formDialogEditFreeRADIUSClient = $this->getForm("dialogEditFreeRADIUSClient"); + $this->view->pick('OPNsense/Freeradius/client'); + } +} diff --git a/net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/GeneralController.php b/net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/GeneralController.php new file mode 100644 index 000000000..d5c8f354d --- /dev/null +++ b/net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/GeneralController.php @@ -0,0 +1,38 @@ +view->title = gettext("FreeRADIUS Settings"); + $this->view->generalForm = $this->getForm("general"); + $this->view->pick('OPNsense/Freeradius/general'); + } +} diff --git a/net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/UserController.php b/net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/UserController.php new file mode 100644 index 000000000..be3450ff6 --- /dev/null +++ b/net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/UserController.php @@ -0,0 +1,34 @@ +view->title = gettext("FreeRADIUS Users"); + $this->view->formDialogEditFreeRADIUSUser = $this->getForm("dialogEditFreeRADIUSUser"); + $this->view->pick('OPNsense/Freeradius/user'); + } +} diff --git a/net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/forms/dialogEditFreeRADIUSClient.xml b/net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/forms/dialogEditFreeRADIUSClient.xml new file mode 100644 index 000000000..5247b87ed --- /dev/null +++ b/net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/forms/dialogEditFreeRADIUSClient.xml @@ -0,0 +1,26 @@ +
+ + client.enabled + + checkbox + This will enable or disable the client config. + + + client.name + + text + Set the "shortname" for the client. + + + client.secret + + text + Set the shared secret for the client. Must match on both sides. + + + client.ip + + text + Set the IP address of the remote client or the complete network like 10.10.10.0/24 + +
diff --git a/net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/forms/dialogEditFreeRADIUSUser.xml b/net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/forms/dialogEditFreeRADIUSUser.xml new file mode 100644 index 000000000..4b6b3b335 --- /dev/null +++ b/net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/forms/dialogEditFreeRADIUSUser.xml @@ -0,0 +1,44 @@ +
+ + user.enabled + + checkbox + This will enable or disable the user account. Allowed characters are 0-9, a-z, A-Z, and ._- + + + user.username + + text + Set the unique username for the user. Allowed characters are 0-9, a-z, A-Z, and ,._-!$%/()+#= with up to 128 characters. + + + user.password + + text + Set the password for the user. + + + user.description + + text + Given name, last name, or anything you need to describe. + + + user.ip + + text + Set the IP address the user should receive. + + + user.subnet + + text + Subnet to receive, e.g. 255.255.255.0 + + + user.vlan + + text + VLAN ID the user receives, e.g. for 802.1X. Leave empty if you don't know what it is. + +
diff --git a/net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/forms/general.xml b/net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/forms/general.xml new file mode 100644 index 000000000..795c7d488 --- /dev/null +++ b/net/freeradius/src/opnsense/mvc/app/controllers/OPNsense/Freeradius/forms/general.xml @@ -0,0 +1,14 @@ +
+ + general.enabled + + checkbox + This will activate the FreeRADIUS service. + + + general.vlanassign + + checkbox + This allows you to dynamically assign VLANs on your physical switch ports. + +
diff --git a/net/freeradius/src/opnsense/mvc/app/models/OPNsense/Freeradius/ACL/ACL.xml b/net/freeradius/src/opnsense/mvc/app/models/OPNsense/Freeradius/ACL/ACL.xml new file mode 100644 index 000000000..7cbb529fb --- /dev/null +++ b/net/freeradius/src/opnsense/mvc/app/models/OPNsense/Freeradius/ACL/ACL.xml @@ -0,0 +1,9 @@ + + + Services: FreeRADIUS + + ui/freeradius/* + api/freeradius/* + + + diff --git a/net/freeradius/src/opnsense/mvc/app/models/OPNsense/Freeradius/Client.php b/net/freeradius/src/opnsense/mvc/app/models/OPNsense/Freeradius/Client.php new file mode 100644 index 000000000..f32baeb5b --- /dev/null +++ b/net/freeradius/src/opnsense/mvc/app/models/OPNsense/Freeradius/Client.php @@ -0,0 +1,30 @@ + + //OPNsense/freeradius/client + FreeRADIUS client configuration + + + + + 1 + Y + + + + Y + + + + Y + + + + N + + + + + diff --git a/net/freeradius/src/opnsense/mvc/app/models/OPNsense/Freeradius/General.php b/net/freeradius/src/opnsense/mvc/app/models/OPNsense/Freeradius/General.php new file mode 100644 index 000000000..e662e6b65 --- /dev/null +++ b/net/freeradius/src/opnsense/mvc/app/models/OPNsense/Freeradius/General.php @@ -0,0 +1,34 @@ + + //OPNsense/freeradius/general + FreeRADIUS configuration + + + 0 + Y + + + 0 + N + + + diff --git a/net/freeradius/src/opnsense/mvc/app/models/OPNsense/Freeradius/Menu/Menu.xml b/net/freeradius/src/opnsense/mvc/app/models/OPNsense/Freeradius/Menu/Menu.xml new file mode 100644 index 000000000..1244a2a1d --- /dev/null +++ b/net/freeradius/src/opnsense/mvc/app/models/OPNsense/Freeradius/Menu/Menu.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/net/freeradius/src/opnsense/mvc/app/models/OPNsense/Freeradius/User.php b/net/freeradius/src/opnsense/mvc/app/models/OPNsense/Freeradius/User.php new file mode 100644 index 000000000..53a1640b7 --- /dev/null +++ b/net/freeradius/src/opnsense/mvc/app/models/OPNsense/Freeradius/User.php @@ -0,0 +1,30 @@ + + //OPNsense/freeradius/user + FreeRADIUS user configuration + + + + + 1 + Y + + + + Y + /^([0-9a-zA-Z._\-]){1,128}$/u + + + + Y + /^([0-9a-zA-Z._\-\!\$\%\/\(\)\+\#\=]){1,128}$/u + + + + N + + + + N + /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/ + + + + N + /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/ + + + + N + 1 + 4096 + + + + + diff --git a/net/freeradius/src/opnsense/mvc/app/views/OPNsense/Freeradius/client.volt b/net/freeradius/src/opnsense/mvc/app/views/OPNsense/Freeradius/client.volt new file mode 100644 index 000000000..e20497981 --- /dev/null +++ b/net/freeradius/src/opnsense/mvc/app/views/OPNsense/Freeradius/client.volt @@ -0,0 +1,115 @@ +{# + +OPNsense® is Copyright © 2014 – 2016 by Deciso B.V. +Copyright (C) 2017 Michael Muenz +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. + +#} + + + + +
+
+ + + + + + + + + + + + + + + + + + + +
{{ lang._('Enabled') }}{{ lang._('Name') }}{{ lang._('Shared secret') }}{{ lang._('IP Address or Network') }}{{ lang._('ID') }}{{ lang._('Commands') }}
+ + +
+
+
+
+ +

+
+
+ +{{ partial("layout_partials/base_dialog",['fields':formDialogEditFreeRADIUSClient,'id':'dialogEditFreeRADIUSClient','label':lang._('Edit Client')])}} diff --git a/net/freeradius/src/opnsense/mvc/app/views/OPNsense/Freeradius/general.volt b/net/freeradius/src/opnsense/mvc/app/views/OPNsense/Freeradius/general.volt new file mode 100644 index 000000000..6d921fae1 --- /dev/null +++ b/net/freeradius/src/opnsense/mvc/app/views/OPNsense/Freeradius/general.volt @@ -0,0 +1,60 @@ +{# + +OPNsense® is Copyright © 2014 – 2017 by Deciso B.V. +This file is Copyright © 2017 by Michael Muenz +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':generalForm,'id':'frm_general_settings'])}} +
+
+ +
+
+ + + diff --git a/net/freeradius/src/opnsense/mvc/app/views/OPNsense/Freeradius/user.volt b/net/freeradius/src/opnsense/mvc/app/views/OPNsense/Freeradius/user.volt new file mode 100644 index 000000000..9c20ad6ee --- /dev/null +++ b/net/freeradius/src/opnsense/mvc/app/views/OPNsense/Freeradius/user.volt @@ -0,0 +1,118 @@ +{# + +OPNsense® is Copyright © 2014 – 2016 by Deciso B.V. +Copyright (C) 2017 Michael Muenz +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. + +#} + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + + +
{{ lang._('Enabled') }}{{ lang._('Username') }}{{ lang._('Password') }}{{ lang._('Description') }}{{ lang._('IP Address') }}{{ lang._('Subnet') }}{{ lang._('VLAN ID') }}{{ lang._('ID') }}{{ lang._('Commands') }}
+ + +
+
+
+
+ +

+
+
+ +{{ partial("layout_partials/base_dialog",['fields':formDialogEditFreeRADIUSUser,'id':'dialogEditFreeRADIUSUser','label':lang._('Edit User')])}} diff --git a/net/freeradius/src/opnsense/scripts/Freeradius/setup.sh b/net/freeradius/src/opnsense/scripts/Freeradius/setup.sh new file mode 100644 index 000000000..0da3ed83d --- /dev/null +++ b/net/freeradius/src/opnsense/scripts/Freeradius/setup.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +user=radiusd +group=radiusd + +mkdir -p /var/run/radiusd +chown $user:$group /var/run/radiusd +chmod 750 /var/run/radiusd + +mkdir -p /usr/local/etc/raddb/ +chown $user:$group /usr/local/etc/raddb/ +chmod 750 /usr/local/etc/raddb/ + +chown -R $user:$group /usr/local/etc/raddb +chown -R $user:$group /var/run/radiusd diff --git a/net/freeradius/src/opnsense/service/conf/actions.d/actions_freeradius.conf b/net/freeradius/src/opnsense/service/conf/actions.d/actions_freeradius.conf new file mode 100644 index 000000000..3b1f58df1 --- /dev/null +++ b/net/freeradius/src/opnsense/service/conf/actions.d/actions_freeradius.conf @@ -0,0 +1,29 @@ +[start] +command:/usr/local/opnsense/scripts/freeradius/setup.sh;/usr/local/etc/rc.d/radiusd start +parameters: +type:script +message:starting FreeRADIUS + +[stop] +command:/usr/local/etc/rc.d/radiusd stop; exit 0 +parameters: +type:script +message:stopping FreeRADIUS + +[restart] +command:/usr/local/opnsense/scripts/freeradius/setup.sh;/usr/local/etc/rc.d/radiusd restart +parameters: +type:script +message:restarting FreeRADIUS + +[reconfigure] +command:/usr/local/opnsense/scripts/freeradius/setup.sh;/usr/local/etc/rc.d/radiusd reload +parameters: +type:script +message:reconfigure FreeRADIUS + +[status] +command:/usr/local/etc/rc.d/radiusd status;exit 0 +parameters: +type:script_output +message:request FreeRADIUS status diff --git a/net/freeradius/src/opnsense/service/templates/OPNsense/Freeradius/+TARGETS b/net/freeradius/src/opnsense/service/templates/OPNsense/Freeradius/+TARGETS new file mode 100644 index 000000000..2896d7d37 --- /dev/null +++ b/net/freeradius/src/opnsense/service/templates/OPNsense/Freeradius/+TARGETS @@ -0,0 +1,7 @@ +clients.conf:/usr/local/etc/raddb/clients.conf +mods-enabled-eap:/usr/local/etc/raddb/mods-enabled/eap +radius.conf:/usr/local/etc/raddb/radius.conf +radiusd:/etc/rc.conf.d/radiusd +sites-enabled-default:/usr/local/etc/raddb/sites-enabled/default +sites-enabled-inner-tunnel:/usr/local/etc/raddb/sites-enabled/inner-tunnel +users:/usr/local/etc/raddb/mods-config/files/authorize diff --git a/net/freeradius/src/opnsense/service/templates/OPNsense/Freeradius/clients.conf b/net/freeradius/src/opnsense/service/templates/OPNsense/Freeradius/clients.conf new file mode 100644 index 000000000..afa7d8f46 --- /dev/null +++ b/net/freeradius/src/opnsense/service/templates/OPNsense/Freeradius/clients.conf @@ -0,0 +1,15 @@ +{% if helpers.exists('OPNsense.freeradius.general.enabled') and OPNsense.freeradius.general.enabled == '1' %} + +{% if helpers.exists('OPNsense.freeradius.client.clients.client') %} +{% for client_list in helpers.toList('OPNsense.freeradius.client.clients.client') %} +{% if client_list.enabled == '1' %} +client {{ client_list.ip }} { + secret = {{ client_list.secret }} + shortname = {{ client_list.name }} +} + +{% endif %} +{% endfor %} +{% endif %} + +{% endif %} diff --git a/net/freeradius/src/opnsense/service/templates/OPNsense/Freeradius/mods-enabled-eap b/net/freeradius/src/opnsense/service/templates/OPNsense/Freeradius/mods-enabled-eap new file mode 100644 index 000000000..421454152 --- /dev/null +++ b/net/freeradius/src/opnsense/service/templates/OPNsense/Freeradius/mods-enabled-eap @@ -0,0 +1,891 @@ +{% if helpers.exists('OPNsense.freeradius.general.enabled') and OPNsense.freeradius.general.enabled == '1' %} + +# -*- text -*- +## +## eap.conf -- Configuration for EAP types (PEAP, TTLS, etc.) +## +## $Id: 427016c66da92b5aa87ac784e74550c4e723c0cd $ + +####################################################################### +# +# Whatever you do, do NOT set 'Auth-Type := EAP'. The server +# is smart enough to figure this out on its own. The most +# common side effect of setting 'Auth-Type := EAP' is that the +# users then cannot use ANY other authentication method. +# +eap { + # Invoke the default supported EAP type when + # EAP-Identity response is received. + # + # The incoming EAP messages DO NOT specify which EAP + # type they will be using, so it MUST be set here. + # + # For now, only one default EAP type may be used at a time. + # + # If the EAP-Type attribute is set by another module, + # then that EAP type takes precedence over the + # default type configured here. + # + default_eap_type = md5 + + # A list is maintained to correlate EAP-Response + # packets with EAP-Request packets. After a + # configurable length of time, entries in the list + # expire, and are deleted. + # + timer_expire = 60 + + # There are many EAP types, but the server has support + # for only a limited subset. If the server receives + # a request for an EAP type it does not support, then + # it normally rejects the request. By setting this + # configuration to "yes", you can tell the server to + # instead keep processing the request. Another module + # MUST then be configured to proxy the request to + # another RADIUS server which supports that EAP type. + # + # If another module is NOT configured to handle the + # request, then the request will still end up being + # rejected. + ignore_unknown_eap_types = no + + # Cisco AP1230B firmware 12.2(13)JA1 has a bug. When given + # a User-Name attribute in an Access-Accept, it copies one + # more byte than it should. + # + # We can work around it by configurably adding an extra + # zero byte. + cisco_accounting_username_bug = no + + # + # Help prevent DoS attacks by limiting the number of + # sessions that the server is tracking. For simplicity, + # this is taken from the "max_requests" directive in + # radiusd.conf. + max_sessions = ${max_requests} + + # Supported EAP-types + + # + # We do NOT recommend using EAP-MD5 authentication + # for wireless connections. It is insecure, and does + # not provide for dynamic WEP keys. + # + md5 { + } + + # + # EAP-pwd -- secure password-based authentication + # +# pwd { +# group = 19 + + # +# server_id = theserver@example.com + + # This has the same meaning as for TLS. +# fragment_size = 1020 + + # The virtual server which determines the + # "known good" password for the user. + # Note that unlike TLS, only the "authorize" + # section is processed. EAP-PWD requests can be + # distinguished by having a User-Name, but + # no User-Password, CHAP-Password, EAP-Message, etc. +# virtual_server = "inner-tunnel" +# } + + # Cisco LEAP + # + # We do not recommend using LEAP in new deployments. See: + # http://www.securiteam.com/tools/5TP012ACKE.html + # + # Cisco LEAP uses the MS-CHAP algorithm (but not + # the MS-CHAP attributes) to perform it's authentication. + # + # As a result, LEAP *requires* access to the plain-text + # User-Password, or the NT-Password attributes. + # 'System' authentication is impossible with LEAP. + # + leap { + } + + # Generic Token Card. + # + # Currently, this is only permitted inside of EAP-TTLS, + # or EAP-PEAP. The module "challenges" the user with + # text, and the response from the user is taken to be + # the User-Password. + # + # Proxying the tunneled EAP-GTC session is a bad idea, + # the users password will go over the wire in plain-text, + # for anyone to see. + # + gtc { + # The default challenge, which many clients + # ignore.. + #challenge = "Password: " + + # The plain-text response which comes back + # is put into a User-Password attribute, + # and passed to another module for + # authentication. This allows the EAP-GTC + # response to be checked against plain-text, + # or crypt'd passwords. + # + # If you say "Local" instead of "PAP", then + # the module will look for a User-Password + # configured for the request, and do the + # authentication itself. + # + auth_type = PAP + } + + ## Common TLS configuration for TLS-based EAP types + # + # See raddb/certs/README for additional comments + # on certificates. + # + # If OpenSSL was not found at the time the server was + # built, the "tls", "ttls", and "peap" sections will + # be ignored. + # + # If you do not currently have certificates signed by + # a trusted CA you may use the 'snakeoil' certificates. + # Included with the server in raddb/certs. + # + # If these certificates have not been auto-generated: + # cd raddb/certs + # make + # + # These test certificates SHOULD NOT be used in a normal + # deployment. They are created only to make it easier + # to install the server, and to perform some simple + # tests with EAP-TLS, TTLS, or PEAP. + # + # See also: + # + # http://www.dslreports.com/forum/remark,9286052~mode=flat + # + # Note that you should NOT use a globally known CA here! + # e.g. using a Verisign cert as a "known CA" means that + # ANYONE who has a certificate signed by them can + # authenticate via EAP-TLS! This is likely not what you want. + tls-config tls-common { + private_key_password = whatever + private_key_file = ${certdir}/server.pem + + # If Private key & Certificate are located in + # the same file, then private_key_file & + # certificate_file must contain the same file + # name. + # + # If ca_file (below) is not used, then the + # certificate_file below MUST include not + # only the server certificate, but ALSO all + # of the CA certificates used to sign the + # server certificate. + certificate_file = ${certdir}/server.pem + + # Trusted Root CA list + # + # ALL of the CA's in this list will be trusted + # to issue client certificates for authentication. + # + # In general, you should use self-signed + # certificates for 802.1x (EAP) authentication. + # In that case, this CA file should contain + # *one* CA certificate. + # + ca_file = ${cadir}/ca.pem + + # OpenSSL will automatically create certificate chains, + # unless we tell it to not do that. The problem is that + # it sometimes gets the chains right from a certificate + # signature view, but wrong from the clients view. + # + # When setting "auto_chain = no", the server certificate + # file MUST include the full certificate chain. + # auto_chain = yes + + # + # If OpenSSL supports TLS-PSK, then we can use + # a PSK identity and (hex) password. When the + # following two configuration items are specified, + # then certificate-based configuration items are + # not allowed. e.g.: + # + # private_key_password + # private_key_file + # certificate_file + # ca_file + # ca_path + # + # For now, the identity is fixed, and must be the + # same on the client. The passphrase must be a hex + # value, and can be up to 256 hex digits. + # + # Future versions of the server may be able to + # look up the shared key (hexphrase) based on the + # identity. + # + # psk_identity = "test" + # psk_hexphrase = "036363823" + + # + # For DH cipher suites to work, you have to + # run OpenSSL to create the DH file first: + # + # openssl dhparam -out certs/dh 2048 + # + dh_file = ${certdir}/dh + + # + # If your system doesn't have /dev/urandom, + # you will need to create this file, and + # periodically change its contents. + # + # For security reasons, FreeRADIUS doesn't + # write to files in its configuration + # directory. + # + # random_file = /dev/urandom + + # + # This can never exceed the size of a RADIUS + # packet (4096 bytes), and is preferably half + # that, to accommodate other attributes in + # RADIUS packet. On most APs the MAX packet + # length is configured between 1500 - 1600 + # In these cases, fragment size should be + # 1024 or less. + # + # fragment_size = 1024 + + # include_length is a flag which is + # by default set to yes If set to + # yes, Total Length of the message is + # included in EVERY packet we send. + # If set to no, Total Length of the + # message is included ONLY in the + # First packet of a fragment series. + # + # include_length = yes + + + # Check the Certificate Revocation List + # + # 1) Copy CA certificates and CRLs to same directory. + # 2) Execute 'c_rehash '. + # 'c_rehash' is OpenSSL's command. + # 3) uncomment the lines below. + # 5) Restart radiusd + # check_crl = yes + + # Check if intermediate CAs have been revoked. + # check_all_crl = yes + + ca_path = ${cadir} + + # + # If check_cert_issuer is set, the value will + # be checked against the DN of the issuer in + # the client certificate. If the values do not + # match, the certificate verification will fail, + # rejecting the user. + # + # In 2.1.10 and later, this check can be done + # more generally by checking the value of the + # TLS-Client-Cert-Issuer attribute. This check + # can be done via any mechanism you choose. + # + # check_cert_issuer = "/C=GB/ST=Berkshire/L=Newbury/O=My Company Ltd" + + # + # If check_cert_cn is set, the value will + # be xlat'ed and checked against the CN + # in the client certificate. If the values + # do not match, the certificate verification + # will fail rejecting the user. + # + # This check is done only if the previous + # "check_cert_issuer" is not set, or if + # the check succeeds. + # + # In 2.1.10 and later, this check can be done + # more generally by checking the value of the + # TLS-Client-Cert-CN attribute. This check + # can be done via any mechanism you choose. + # + # check_cert_cn = %{User-Name} + # + # Set this option to specify the allowed + # TLS cipher suites. The format is listed + # in "man 1 ciphers". + # + # For EAP-FAST, use "ALL:!EXPORT:!eNULL:!SSLv2" + # + cipher_list = "DEFAULT" + + # If enabled, OpenSSL will use server cipher list + # (possibly defined by cipher_list option above) + # for choosing right cipher suite rather than + # using client-specified list which is OpenSSl default + # behavior. Having it set to yes is a current best practice + # for TLS + cipher_server_preference = no + + # Work-arounds for OpenSSL nonsense + # OpenSSL 1.0.1f and 1.0.1g do not calculate + # the EAP keys correctly. The fix is to upgrade + # OpenSSL, or disable TLS 1.2 here. + # + # For EAP-FAST, this MUST be set to "yes". + # +# disable_tlsv1_2 = no + + # + + # + # Elliptical cryptography configuration + # + # Only for OpenSSL >= 0.9.8.f + # + ecdh_curve = "prime256v1" + + # + # Session resumption / fast reauthentication + # cache. + # + # The cache contains the following information: + # + # session Id - unique identifier, managed by SSL + # User-Name - from the Access-Accept + # Stripped-User-Name - from the Access-Request + # Cached-Session-Policy - from the Access-Accept + # + # The "Cached-Session-Policy" is the name of a + # policy which should be applied to the cached + # session. This policy can be used to assign + # VLANs, IP addresses, etc. It serves as a useful + # way to re-apply the policy from the original + # Access-Accept to the subsequent Access-Accept + # for the cached session. + # + # On session resumption, these attributes are + # copied from the cache, and placed into the + # reply list. + # + # You probably also want "use_tunneled_reply = yes" + # when using fast session resumption. + # + cache { + # + # Enable it. The default is "no". Deleting the entire "cache" + # subsection also disables caching. + # + # You can disallow resumption for a particular user by adding the + # following attribute to the control item list: + # + # Allow-Session-Resumption = No + # + # If "enable = no" below, you CANNOT enable resumption for just one + # user by setting the above attribute to "yes". + # + enable = yes + + # + # Lifetime of the cached entries, in hours. The sessions will be + # deleted/invalidated after this time. + # + lifetime = 24 # hours + + # + # The maximum number of entries in the + # cache. Set to "0" for "infinite". + # + # This could be set to the number of users + # who are logged in... which can be a LOT. + # + max_entries = 255 + + # + # Internal "name" of the session cache. Used to + # distinguish which TLS context sessions belong to. + # + # The server will generate a random value if unset. + # This will change across server restart so you MUST + # set the "name" if you want to persist sessions (see + # below). + # + #name = "EAP module" + + # + # Simple directory-based storage of sessions. + # Two files per session will be written, the SSL + # state and the cached VPs. This will persist session + # across server restarts. + # + # The server will need write perms, and the directory + # should be secured from anyone else. You might want + # a script to remove old files from here periodically: + # + # find ${logdir}/tlscache -mtime +2 -exec rm -f {} \; + # + # This feature REQUIRES "name" option be set above. + # + #persist_dir = "${logdir}/tlscache" + } + + # + # As of version 2.1.10, client certificates can be + # validated via an external command. This allows + # dynamic CRLs or OCSP to be used. + # + # This configuration is commented out in the + # default configuration. Uncomment it, and configure + # the correct paths below to enable it. + # + # If OCSP checking is enabled, and the OCSP checks fail, + # the verify section is not run. + # + # If OCSP checking is disabled, the verify section is + # run on successful certificate validation. + # + verify { + # If the OCSP checks succeed, the verify section + # is run to allow additional checks. + # + # If you want to skip verify on OCSP success, + # uncomment this configuration item, and set it + # to "yes". + # skip_if_ocsp_ok = no + + # A temporary directory where the client + # certificates are stored. This directory + # MUST be owned by the UID of the server, + # and MUST not be accessible by any other + # users. When the server starts, it will do + # "chmod go-rwx" on the directory, for + # security reasons. The directory MUST + # exist when the server starts. + # + # You should also delete all of the files + # in the directory when the server starts. + # tmpdir = /tmp/radiusd + + # The command used to verify the client cert. + # We recommend using the OpenSSL command-line + # tool. + # + # The ${..ca_path} text is a reference to + # the ca_path variable defined above. + # + # The %{TLS-Client-Cert-Filename} is the name + # of the temporary file containing the cert + # in PEM format. This file is automatically + # deleted by the server when the command + # returns. + # client = "/path/to/openssl verify -CApath ${..ca_path} %{TLS-Client-Cert-Filename}" + } + + # + # OCSP Configuration + # Certificates can be verified against an OCSP + # Responder. This makes it possible to immediately + # revoke certificates without the distribution of + # new Certificate Revocation Lists (CRLs). + # + ocsp { + # + # Enable it. The default is "no". + # Deleting the entire "ocsp" subsection + # also disables ocsp checking + # + enable = no + + # + # The OCSP Responder URL can be automatically + # extracted from the certificate in question. + # To override the OCSP Responder URL set + # "override_cert_url = yes". + # + override_cert_url = yes + + # + # If the OCSP Responder address is not extracted from + # the certificate, the URL can be defined here. + # + url = "http://127.0.0.1/ocsp/" + + # + # If the OCSP Responder can not cope with nonce + # in the request, then it can be disabled here. + # + # For security reasons, disabling this option + # is not recommended as nonce protects against + # replay attacks. + # + # Note that Microsoft AD Certificate Services OCSP + # Responder does not enable nonce by default. It is + # more secure to enable nonce on the responder than + # to disable it in the query here. + # See http://technet.microsoft.com/en-us/library/cc770413%28WS.10%29.aspx + # + # use_nonce = yes + + # + # Number of seconds before giving up waiting + # for OCSP response. 0 uses system default. + # + # timeout = 0 + + # + # Normally an error in querying the OCSP + # responder (no response from server, server did + # not understand the request, etc) will result in + # a validation failure. + # + # To treat these errors as 'soft' failures and + # still accept the certificate, enable this + # option. + # + # Warning: this may enable clients with revoked + # certificates to connect if the OCSP responder + # is not available. Use with caution. + # + # softfail = no + } + } + + ## EAP-TLS + # + # As of Version 3.0, the TLS configuration for TLS-based + # EAP types is above in the "tls-config" section. + # + tls { + # Point to the common TLS configuration + tls = tls-common + + # + # As part of checking a client certificate, the EAP-TLS + # sets some attributes such as TLS-Client-Cert-CN. This + # virtual server has access to these attributes, and can + # be used to accept or reject the request. + # + # virtual_server = check-eap-tls + } + + + ## EAP-TTLS + # + # The TTLS module implements the EAP-TTLS protocol, + # which can be described as EAP inside of Diameter, + # inside of TLS, inside of EAP, inside of RADIUS... + # + # Surprisingly, it works quite well. + # + ttls { + # Which tls-config section the TLS negotiation parameters + # are in - see EAP-TLS above for an explanation. + # + # In the case that an old configuration from FreeRADIUS + # v2.x is being used, all the options of the tls-config + # section may also appear instead in the 'tls' section + # above. If that is done, the tls= option here (and in + # tls above) MUST be commented out. + # + tls = tls-common + + # The tunneled EAP session needs a default EAP type + # which is separate from the one for the non-tunneled + # EAP module. Inside of the TTLS tunnel, we recommend + # using EAP-MD5. If the request does not contain an + # EAP conversation, then this configuration entry is + # ignored. + # + default_eap_type = md5 + + # The tunneled authentication request does not usually + # contain useful attributes like 'Calling-Station-Id', + # etc. These attributes are outside of the tunnel, + # and normally unavailable to the tunneled + # authentication request. + # + # By setting this configuration entry to 'yes', + # any attribute which is NOT in the tunneled + # authentication request, but which IS available + # outside of the tunnel, is copied to the tunneled + # request. + # + # allowed values: {no, yes} + # + copy_request_to_tunnel = no + + # + # As of version 3.0.5, this configuration item + # is deprecated. Instead, you should use + # + # update outer.session-state { + # ... + # + # } + # + # This will cache attributes for the final Access-Accept. + # + # The reply attributes sent to the NAS are usually + # based on the name of the user 'outside' of the + # tunnel (usually 'anonymous'). If you want to send + # the reply attributes based on the user name inside + # of the tunnel, then set this configuration entry to + # 'yes', and the reply to the NAS will be taken from + # the reply to the tunneled request. + # + # allowed values: {no, yes} + # +{% if helpers.exists('OPNsense.freeradius.general.vlanassign') and OPNsense.freeradius.general.vlanassign == '1' %} + use_tunneled_reply = yes +{% else %} + use_tunneled_reply = no +{% endif %} + # + # The inner tunneled request can be sent + # through a virtual server constructed + # specifically for this purpose. + # + # If this entry is commented out, the inner + # tunneled request will be sent through + # the virtual server that processed the + # outer requests. + # + virtual_server = "inner-tunnel" + + # This has the same meaning, and overwrites, the + # same field in the "tls" configuration, above. + # The default value here is "yes". + # + # include_length = yes + + # + # Unlike EAP-TLS, EAP-TTLS does not require a client + # certificate. However, you can require one by setting the + # following option. You can also override this option by + # setting + # + # EAP-TLS-Require-Client-Cert = Yes + # + # in the control items for a request. + # + # require_client_cert = yes + } + + + ## EAP-PEAP + # + + ################################################## + # + # !!!!! WARNINGS for Windows compatibility !!!!! + # + ################################################## + # + # If you see the server send an Access-Challenge, + # and the client never sends another Access-Request, + # then + # + # STOP! + # + # The server certificate has to have special OID's + # in it, or else the Microsoft clients will silently + # fail. See the "scripts/xpextensions" file for + # details, and the following page: + # + # http://support.microsoft.com/kb/814394/en-us + # + # For additional Windows XP SP2 issues, see: + # + # http://support.microsoft.com/kb/885453/en-us + # + # + # If is still doesn't work, and you're using Samba, + # you may be encountering a Samba bug. See: + # + # https://bugzilla.samba.org/show_bug.cgi?id=6563 + # + # Note that we do not necessarily agree with their + # explanation... but the fix does appear to work. + # + ################################################## + + # + # The tunneled EAP session needs a default EAP type + # which is separate from the one for the non-tunneled + # EAP module. Inside of the TLS/PEAP tunnel, we + # recommend using EAP-MS-CHAPv2. + # + peap { + # Which tls-config section the TLS negotiation parameters + # are in - see EAP-TLS above for an explanation. + # + # In the case that an old configuration from FreeRADIUS + # v2.x is being used, all the options of the tls-config + # section may also appear instead in the 'tls' section + # above. If that is done, the tls= option here (and in + # tls above) MUST be commented out. + # + tls = tls-common + + # The tunneled EAP session needs a default + # EAP type which is separate from the one for + # the non-tunneled EAP module. Inside of the + # PEAP tunnel, we recommend using MS-CHAPv2, + # as that is the default type supported by + # Windows clients. + # + default_eap_type = mschapv2 + + # The PEAP module also has these configuration + # items, which are the same as for TTLS. + # + copy_request_to_tunnel = no + + # + # As of version 3.0.5, this configuration item + # is deprecated. Instead, you should use + # + # update outer.session-state { + # ... + # + # } + # + # This will cache attributes for the final Access-Accept. + # +{% if helpers.exists('OPNsense.freeradius.general.vlanassign') and OPNsense.freeradius.general.vlanassign == '1' %} + use_tunneled_reply = yes +{% else %} + use_tunneled_reply = no +{% endif %} + + # When the tunneled session is proxied, the + # home server may not understand EAP-MSCHAP-V2. + # Set this entry to "no" to proxy the tunneled + # EAP-MSCHAP-V2 as normal MSCHAPv2. + # + # proxy_tunneled_request_as_eap = yes + + # + # The inner tunneled request can be sent + # through a virtual server constructed + # specifically for this purpose. + # + # If this entry is commented out, the inner + # tunneled request will be sent through + # the virtual server that processed the + # outer requests. + # + virtual_server = "inner-tunnel" + + # This option enables support for MS-SoH + # see doc/SoH.txt for more info. + # It is disabled by default. + # + # soh = yes + + # + # The SoH reply will be turned into a request which + # can be sent to a specific virtual server: + # + # soh_virtual_server = "soh-server" + + # + # Unlike EAP-TLS, PEAP does not require a client certificate. + # However, you can require one by setting the following + # option. You can also override this option by setting + # + # EAP-TLS-Require-Client-Cert = Yes + # + # in the control items for a request. + # + # require_client_cert = yes + } + + # + # This takes no configuration. + # + # Note that it is the EAP MS-CHAPv2 sub-module, not + # the main 'mschap' module. + # + # Note also that in order for this sub-module to work, + # the main 'mschap' module MUST ALSO be configured. + # + # This module is the *Microsoft* implementation of MS-CHAPv2 + # in EAP. There is another (incompatible) implementation + # of MS-CHAPv2 in EAP by Cisco, which FreeRADIUS does not + # currently support. + # + mschapv2 { + # Prior to version 2.1.11, the module never + # sent the MS-CHAP-Error message to the + # client. This worked, but it had issues + # when the cached password was wrong. The + # server *should* send "E=691 R=0" to the + # client, which tells it to prompt the user + # for a new password. + # + # The default is to behave as in 2.1.10 and + # earlier, which is known to work. If you + # set "send_error = yes", then the error + # message will be sent back to the client. + # This *may* help some clients work better, + # but *may* also cause other clients to stop + # working. + # +# send_error = no + + # Server identifier to send back in the challenge. + # This should generally be the host name of the + # RADIUS server. Or, some information to uniquely + # identify it. +# identity = "FreeRADIUS" + } + + ## EAP-FAST + # + # The FAST module implements the EAP-FAST protocol + # +# fast { + # Point to the common TLS configuration + # + # cipher_list though must include "ADH" for anonymous provisioning. + # This is not as straight forward as appending "ADH" alongside + # "DEFAULT" as "DEFAULT" contains "!aNULL" so instead it is + # recommended "ALL:!EXPORT:!eNULL:!SSLv2" is used + # +# tls = tls-common + + # PAC lifetime in seconds (default: seven days) + # +# pac_lifetime = 604800 + + # Authority ID of the server + # + # if you are running a cluster of RADIUS servers, you should make + # the value chosen here (and for "pac_opaque_key") the same on all + # your RADIUS servers. This value should be unique to your + # installation. We suggest using a domain name. + # +# authority_identity = "1234" + + # PAC Opaque encryption key (must be exactly 32 bytes in size) + # + # This value MUST be secret, and MUST be generated using + # a secure method, such as via 'openssl rand -hex 32' + # +# pac_opaque_key = "0123456789abcdef0123456789ABCDEF" + + # Same as for TTLS, PEAP, etc. + # +# virtual_server = inner-tunnel +# } +} +{% endif %} diff --git a/net/freeradius/src/opnsense/service/templates/OPNsense/Freeradius/radiusd b/net/freeradius/src/opnsense/service/templates/OPNsense/Freeradius/radiusd new file mode 100644 index 000000000..edc340cf6 --- /dev/null +++ b/net/freeradius/src/opnsense/service/templates/OPNsense/Freeradius/radiusd @@ -0,0 +1 @@ +radiusd_enable="{% if helpers.exists('OPNsense.freeradius.general.enabled') and OPNsense.freeradius.general.enabled == '1' %}YES{% else %}NO{% endif %}" diff --git a/net/freeradius/src/opnsense/service/templates/OPNsense/Freeradius/radiusd.conf b/net/freeradius/src/opnsense/service/templates/OPNsense/Freeradius/radiusd.conf new file mode 100644 index 000000000..60c868988 --- /dev/null +++ b/net/freeradius/src/opnsense/service/templates/OPNsense/Freeradius/radiusd.conf @@ -0,0 +1,830 @@ +{% if helpers.exists('OPNsense.freeradius.general.enabled') and OPNsense.freeradius.general.enabled == '1' %} +{% raw %} +# -*- text -*- +## +## radiusd.conf -- FreeRADIUS server configuration file - 3.0.13 +## +## http://www.freeradius.org/ +## $Id: c62f4ffed53a073a885f243b728129f5c482fad7 $ +## + +###################################################################### +# +# Read "man radiusd" before editing this file. See the section +# titled DEBUGGING. It outlines a method where you can quickly +# obtain the configuration you want, without running into +# trouble. +# +# Run the server in debugging mode, and READ the output. +# +# $ radiusd -X +# +# We cannot emphasize this point strongly enough. The vast +# majority of problems can be solved by carefully reading the +# debugging output, which includes warnings about common issues, +# and suggestions for how they may be fixed. +# +# There may be a lot of output, but look carefully for words like: +# "warning", "error", "reject", or "failure". The messages there +# will usually be enough to guide you to a solution. +# +# If you are going to ask a question on the mailing list, then +# explain what you are trying to do, and include the output from +# debugging mode (radiusd -X). Failure to do so means that all +# of the responses to your question will be people telling you +# to "post the output of radiusd -X". + +###################################################################### +# +# The location of other config files and logfiles are declared +# in this file. +# +# Also general configuration for modules can be done in this +# file, it is exported through the API to modules that ask for +# it. +# +# See "man radiusd.conf" for documentation on the format of this +# file. Note that the individual configuration items are NOT +# documented in that "man" page. They are only documented here, +# in the comments. +# +# The "unlang" policy language can be used to create complex +# if / else policies. See "man unlang" for details. +# + +prefix = /usr/local +exec_prefix = ${prefix} +sysconfdir = ${prefix}/etc +localstatedir = /var +sbindir = ${exec_prefix}/sbin +logdir = /var/log +raddbdir = ${sysconfdir}/raddb +radacctdir = ${logdir}/radacct + +# +# name of the running server. See also the "-n" command-line option. +name = radiusd + +# Location of config and logfiles. +confdir = ${raddbdir} +modconfdir = ${confdir}/mods-config +certdir = ${confdir}/certs +cadir = ${confdir}/certs +run_dir = ${localstatedir}/run/${name} + +# Should likely be ${localstatedir}/lib/radiusd +db_dir = ${raddbdir} + +# +# libdir: Where to find the rlm_* modules. +# +# This should be automatically set at configuration time. +# +# If the server builds and installs, but fails at execution time +# with an 'undefined symbol' error, then you can use the libdir +# directive to work around the problem. +# +# The cause is usually that a library has been installed on your +# system in a place where the dynamic linker CANNOT find it. When +# executing as root (or another user), your personal environment MAY +# be set up to allow the dynamic linker to find the library. When +# executing as a daemon, FreeRADIUS MAY NOT have the same +# personalized configuration. +# +# To work around the problem, find out which library contains that symbol, +# and add the directory containing that library to the end of 'libdir', +# with a colon separating the directory names. NO spaces are allowed. +# +# e.g. libdir = /usr/local/lib:/opt/package/lib +# +# You can also try setting the LD_LIBRARY_PATH environment variable +# in a script which starts the server. +# +# If that does not work, then you can re-configure and re-build the +# server to NOT use shared libraries, via: +# +# ./configure --disable-shared +# make +# make install +# +libdir = /usr/local/lib/freeradius-3.0.13 + +# pidfile: Where to place the PID of the RADIUS server. +# +# The server may be signalled while it's running by using this +# file. +# +# This file is written when ONLY running in daemon mode. +# +# e.g.: kill -HUP `cat /var/run/radiusd/radiusd.pid` +# +pidfile = ${run_dir}/${name}.pid + +# +# correct_escapes: use correct backslash escaping +# +# Prior to version 3.0.5, the handling of backslashes was a little +# awkward, i.e. "wrong". In some cases, to get one backslash into +# a regex, you had to put 4 in the config files. +# +# Version 3.0.5 fixes that. However, for backwards compatibility, +# the new method of escaping is DISABLED BY DEFAULT. This means +# that upgrading to 3.0.5 won't break your configuration. +# +# If you don't have double backslashes (i.e. \\) in your configuration, +# this won't matter to you. If you do have them, fix that to use only +# one backslash, and then set "correct_escapes = true". +# +# You can check for this by doing: +# +# $ grep '\\\\' $(find raddb -type f -print) +# +correct_escapes = true + +# panic_action: Command to execute if the server dies unexpectedly. +# +# FOR PRODUCTION SYSTEMS, ACTIONS SHOULD ALWAYS EXIT. +# AN INTERACTIVE ACTION MEANS THE SERVER IS NOT RESPONDING TO REQUESTS. +# AN INTERACTICE ACTION MEANS THE SERVER WILL NOT RESTART. +# +# THE SERVER MUST NOT BE ALLOWED EXECUTE UNTRUSTED PANIC ACTION CODE +# PATTACH CAN BE USED AS AN ATTACK VECTOR. +# +# The panic action is a command which will be executed if the server +# receives a fatal, non user generated signal, i.e. SIGSEGV, SIGBUS, +# SIGABRT or SIGFPE. +# +# This can be used to start an interactive debugging session so +# that information regarding the current state of the server can +# be acquired. +# +# The following string substitutions are available: +# - %e The currently executing program e.g. /sbin/radiusd +# - %p The PID of the currently executing program e.g. 12345 +# +# Standard ${} substitutions are also allowed. +# +# An example panic action for opening an interactive session in GDB would be: +# +#panic_action = "gdb %e %p" +# +# Again, don't use that on a production system. +# +# An example panic action for opening an automated session in GDB would be: +# +#panic_action = "gdb -silent -x ${raddbdir}/panic.gdb %e %p 2>&1 | tee ${logdir}/gdb-${name}-%p.log" +# +# That command can be used on a production system. +# + +# max_request_time: The maximum time (in seconds) to handle a request. +# +# Requests which take more time than this to process may be killed, and +# a REJECT message is returned. +# +# WARNING: If you notice that requests take a long time to be handled, +# then this MAY INDICATE a bug in the server, in one of the modules +# used to handle a request, OR in your local configuration. +# +# This problem is most often seen when using an SQL database. If it takes +# more than a second or two to receive an answer from the SQL database, +# then it probably means that you haven't indexed the database. See your +# SQL server documentation for more information. +# +# Useful range of values: 5 to 120 +# +max_request_time = 30 + +# cleanup_delay: The time to wait (in seconds) before cleaning up +# a reply which was sent to the NAS. +# +# The RADIUS request is normally cached internally for a short period +# of time, after the reply is sent to the NAS. The reply packet may be +# lost in the network, and the NAS will not see it. The NAS will then +# re-send the request, and the server will respond quickly with the +# cached reply. +# +# If this value is set too low, then duplicate requests from the NAS +# MAY NOT be detected, and will instead be handled as separate requests. +# +# If this value is set too high, then the server will cache too many +# requests, and some new requests may get blocked. (See 'max_requests'.) +# +# Useful range of values: 2 to 10 +# +cleanup_delay = 5 + +# max_requests: The maximum number of requests which the server keeps +# track of. This should be 256 multiplied by the number of clients. +# e.g. With 4 clients, this number should be 1024. +# +# If this number is too low, then when the server becomes busy, +# it will not respond to any new requests, until the 'cleanup_delay' +# time has passed, and it has removed the old requests. +# +# If this number is set too high, then the server will use a bit more +# memory for no real benefit. +# +# If you aren't sure what it should be set to, it's better to set it +# too high than too low. Setting it to 1000 per client is probably +# the highest it should be. +# +# Useful range of values: 256 to infinity +# +max_requests = 16384 + +# hostname_lookups: Log the names of clients or just their IP addresses +# e.g., www.freeradius.org (on) or 206.47.27.232 (off). +# +# The default is 'off' because it would be overall better for the net +# if people had to knowingly turn this feature on, since enabling it +# means that each client request will result in AT LEAST one lookup +# request to the nameserver. Enabling hostname_lookups will also +# mean that your server may stop randomly for 30 seconds from time +# to time, if the DNS requests take too long. +# +# Turning hostname lookups off also means that the server won't block +# for 30 seconds, if it sees an IP address which has no name associated +# with it. +# +# allowed values: {no, yes} +# +hostname_lookups = no + +# +# Logging section. The various "log_*" configuration items +# will eventually be moved here. +# +log { + # + # Destination for log messages. This can be one of: + # + # files - log to "file", as defined below. + # syslog - to syslog (see also the "syslog_facility", below. + # stdout - standard output + # stderr - standard error. + # + # The command-line option "-X" over-rides this option, and forces + # logging to go to stdout. + # + destination = files + + # + # Highlight important messages sent to stderr and stdout. + # + # Option will be ignored (disabled) if output if TERM is not + # an xterm or output is not to a TTY. + # + colourise = yes + + # + # The logging messages for the server are appended to the + # tail of this file if destination == "files" + # + # If the server is running in debugging mode, this file is + # NOT used. + # + file = ${logdir}/radius.log + + # + # If this configuration parameter is set, then log messages for + # a *request* go to this file, rather than to radius.log. + # + # i.e. This is a log file per request, once the server has accepted + # the request as being from a valid client. Messages that are + # not associated with a request still go to radius.log. + # + # Not all log messages in the server core have been updated to use + # this new internal API. As a result, some messages will still + # go to radius.log. Please submit patches to fix this behavior. + # + # The file name is expanded dynamically. You should ONLY user + # server-side attributes for the filename (e.g. things you control). + # Using this feature MAY also slow down the server substantially, + # especially if you do thinks like SQL calls as part of the + # expansion of the filename. + # + # The name of the log file should use attributes that don't change + # over the lifetime of a request, such as User-Name, + # Virtual-Server or Packet-Src-IP-Address. Otherwise, the log + # messages will be distributed over multiple files. + # + # Logging can be enabled for an individual request by a special + # dynamic expansion macro: %{debug: 1}, where the debug level + # for this request is set to '1' (or 2, 3, etc.). e.g. + # + # ... + # update control { + # Tmp-String-0 = "%{debug:1}" + # } + # ... + # + # The attribute that the value is assigned to is unimportant, + # and should be a "throw-away" attribute with no side effects. + # + #requests = ${logdir}/radiusd-%{%{Virtual-Server}:-DEFAULT}-%Y%m%d.log + + # + # Which syslog facility to use, if ${destination} == "syslog" + # + # The exact values permitted here are OS-dependent. You probably + # don't want to change this. + # + syslog_facility = daemon + + # Log the full User-Name attribute, as it was found in the request. + # + # allowed values: {no, yes} + # + stripped_names = no + + # Log authentication requests to the log file. + # + # allowed values: {no, yes} + # + auth = no + + # Log passwords with the authentication requests. + # auth_badpass - logs password if it's rejected + # auth_goodpass - logs password if it's correct + # + # allowed values: {no, yes} + # + auth_badpass = no + auth_goodpass = no + + # Log additional text at the end of the "Login OK" messages. + # for these to work, the "auth" and "auth_goodpass" or "auth_badpass" + # configurations above have to be set to "yes". + # + # The strings below are dynamically expanded, which means that + # you can put anything you want in them. However, note that + # this expansion can be slow, and can negatively impact server + # performance. + # +# msg_goodpass = "" +# msg_badpass = "" + + # The message when the user exceeds the Simultaneous-Use limit. + # + msg_denied = "You are already logged in - access denied" +} + +# The program to execute to do concurrency checks. +checkrad = ${sbindir}/checkrad + +# SECURITY CONFIGURATION +# +# There may be multiple methods of attacking on the server. This +# section holds the configuration items which minimize the impact +# of those attacks +# +security { + # chroot: directory where the server does "chroot". + # + # The chroot is done very early in the process of starting + # the server. After the chroot has been performed it + # switches to the "user" listed below (which MUST be + # specified). If "group" is specified, it switches to that + # group, too. Any other groups listed for the specified + # "user" in "/etc/group" are also added as part of this + # process. + # + # The current working directory (chdir / cd) is left + # *outside* of the chroot until all of the modules have been + # initialized. This allows the "raddb" directory to be left + # outside of the chroot. Once the modules have been + # initialized, it does a "chdir" to ${logdir}. This means + # that it should be impossible to break out of the chroot. + # + # If you are worried about security issues related to this + # use of chdir, then simply ensure that the "raddb" directory + # is inside of the chroot, end be sure to do "cd raddb" + # BEFORE starting the server. + # + # If the server is statically linked, then the only files + # that have to exist in the chroot are ${run_dir} and + # ${logdir}. If you do the "cd raddb" as discussed above, + # then the "raddb" directory has to be inside of the chroot + # directory, too. + # +# chroot = /path/to/chroot/directory + + # user/group: The name (or #number) of the user/group to run radiusd as. + # + # If these are commented out, the server will run as the + # user/group that started it. In order to change to a + # different user/group, you MUST be root ( or have root + # privileges ) to start the server. + # + # We STRONGLY recommend that you run the server with as few + # permissions as possible. That is, if you're not using + # shadow passwords, the user and group items below should be + # set to radius'. + # + # NOTE that some kernels refuse to setgid(group) when the + # value of (unsigned)group is above 60000; don't use group + # "nobody" on these systems! + # + # On systems with shadow passwords, you might have to set + # 'group = shadow' for the server to be able to read the + # shadow password file. If you can authenticate users while + # in debug mode, but not in daemon mode, it may be that the + # debugging mode server is running as a user that can read + # the shadow info, and the user listed below can not. + # + # The server will also try to use "initgroups" to read + # /etc/groups. It will join all groups where "user" is a + # member. This can allow for some finer-grained access + # controls. + # +# user = radius +# group = radius + + # Core dumps are a bad thing. This should only be set to + # 'yes' if you're debugging a problem with the server. + # + # allowed values: {no, yes} + # + allow_core_dumps = no + + # + # max_attributes: The maximum number of attributes + # permitted in a RADIUS packet. Packets which have MORE + # than this number of attributes in them will be dropped. + # + # If this number is set too low, then no RADIUS packets + # will be accepted. + # + # If this number is set too high, then an attacker may be + # able to send a small number of packets which will cause + # the server to use all available memory on the machine. + # + # Setting this number to 0 means "allow any number of attributes" + max_attributes = 200 + + # + # reject_delay: When sending an Access-Reject, it can be + # delayed for a few seconds. This may help slow down a DoS + # attack. It also helps to slow down people trying to brute-force + # crack a users password. + # + # Setting this number to 0 means "send rejects immediately" + # + # If this number is set higher than 'cleanup_delay', then the + # rejects will be sent at 'cleanup_delay' time, when the request + # is deleted from the internal cache of requests. + # + # As of Version 3.0.5, "reject_delay" has sub-second resolution. + # e.g. "reject_delay = 1.4" seconds is possible. + # + # Useful ranges: 1 to 5 + reject_delay = 1 + + # + # status_server: Whether or not the server will respond + # to Status-Server requests. + # + # When sent a Status-Server message, the server responds with + # an Access-Accept or Accounting-Response packet. + # + # This is mainly useful for administrators who want to "ping" + # the server, without adding test users, or creating fake + # accounting packets. + # + # It's also useful when a NAS marks a RADIUS server "dead". + # The NAS can periodically "ping" the server with a Status-Server + # packet. If the server responds, it must be alive, and the + # NAS can start using it for real requests. + # + # See also raddb/sites-available/status + # + status_server = yes + + # + # allow_vulnerable_openssl: Allow the server to start with + # versions of OpenSSL known to have critical vulnerabilities. + # + # This check is based on the version number reported by libssl + # and may not reflect patches applied to libssl by + # distribution maintainers. + # + allow_vulnerable_openssl = no +} + +# PROXY CONFIGURATION +# +# proxy_requests: Turns proxying of RADIUS requests on or off. +# +# The server has proxying turned on by default. If your system is NOT +# set up to proxy requests to another server, then you can turn proxying +# off here. This will save a small amount of resources on the server. +# +# If you have proxying turned off, and your configuration files say +# to proxy a request, then an error message will be logged. +# +# To disable proxying, change the "yes" to "no", and comment the +# $INCLUDE line. +# +# allowed values: {no, yes} +# +proxy_requests = yes +$INCLUDE proxy.conf + + +# CLIENTS CONFIGURATION +# +# Client configuration is defined in "clients.conf". +# + +# The 'clients.conf' file contains all of the information from the old +# 'clients' and 'naslist' configuration files. We recommend that you +# do NOT use 'client's or 'naslist', although they are still +# supported. +# +# Anything listed in 'clients.conf' will take precedence over the +# information from the old-style configuration files. +# +$INCLUDE clients.conf + + +# THREAD POOL CONFIGURATION +# +# The thread pool is a long-lived group of threads which +# take turns (round-robin) handling any incoming requests. +# +# You probably want to have a few spare threads around, +# so that high-load situations can be handled immediately. If you +# don't have any spare threads, then the request handling will +# be delayed while a new thread is created, and added to the pool. +# +# You probably don't want too many spare threads around, +# otherwise they'll be sitting there taking up resources, and +# not doing anything productive. +# +# The numbers given below should be adequate for most situations. +# +thread pool { + # Number of servers to start initially --- should be a reasonable + # ballpark figure. + start_servers = 5 + + # Limit on the total number of servers running. + # + # If this limit is ever reached, clients will be LOCKED OUT, so it + # should NOT BE SET TOO LOW. It is intended mainly as a brake to + # keep a runaway server from taking the system with it as it spirals + # down... + # + # You may find that the server is regularly reaching the + # 'max_servers' number of threads, and that increasing + # 'max_servers' doesn't seem to make much difference. + # + # If this is the case, then the problem is MOST LIKELY that + # your back-end databases are taking too long to respond, and + # are preventing the server from responding in a timely manner. + # + # The solution is NOT do keep increasing the 'max_servers' + # value, but instead to fix the underlying cause of the + # problem: slow database, or 'hostname_lookups=yes'. + # + # For more information, see 'max_request_time', above. + # + max_servers = 32 + + # Server-pool size regulation. Rather than making you guess + # how many servers you need, FreeRADIUS dynamically adapts to + # the load it sees, that is, it tries to maintain enough + # servers to handle the current load, plus a few spare + # servers to handle transient load spikes. + # + # It does this by periodically checking how many servers are + # waiting for a request. If there are fewer than + # min_spare_servers, it creates a new spare. If there are + # more than max_spare_servers, some of the spares die off. + # The default values are probably OK for most sites. + # + min_spare_servers = 3 + max_spare_servers = 10 + + # When the server receives a packet, it places it onto an + # internal queue, where the worker threads (configured above) + # pick it up for processing. The maximum size of that queue + # is given here. + # + # When the queue is full, any new packets will be silently + # discarded. + # + # The most common cause of the queue being full is that the + # server is dependent on a slow database, and it has received + # a large "spike" of traffic. When that happens, there is + # very little you can do other than make sure the server + # receives less traffic, or make sure that the database can + # handle the load. + # +# max_queue_size = 65536 + + # There may be memory leaks or resource allocation problems with + # the server. If so, set this value to 300 or so, so that the + # resources will be cleaned up periodically. + # + # This should only be necessary if there are serious bugs in the + # server which have not yet been fixed. + # + # '0' is a special value meaning 'infinity', or 'the servers never + # exit' + max_requests_per_server = 0 + + # Automatically limit the number of accounting requests. + # This configuration item tracks how many requests per second + # the server can handle. It does this by tracking the + # packets/s received by the server for processing, and + # comparing that to the packets/s handled by the child + # threads. + # + + # If the received PPS is larger than the processed PPS, *and* + # the queue is more than half full, then new accounting + # requests are probabilistically discarded. This lowers the + # number of packets that the server needs to process. Over + # time, the server will "catch up" with the traffic. + # + # Throwing away accounting packets is usually safe and low + # impact. The NAS will retransmit them in a few seconds, or + # even a few minutes. Vendors should read RFC 5080 Section 2.2.1 + # to see how accounting packets should be retransmitted. Using + # any other method is likely to cause network meltdowns. + # + auto_limit_acct = no +} + +###################################################################### +# +# SNMP notifications. Uncomment the following line to enable +# snmptraps. Note that you MUST also configure the full path +# to the "snmptrap" command in the "trigger.conf" file. +# +#$INCLUDE trigger.conf + +# MODULE CONFIGURATION +# +# The names and configuration of each module is located in this section. +# +# After the modules are defined here, they may be referred to by name, +# in other sections of this configuration file. +# +modules { + # + # Each module has a configuration as follows: + # + # name [ instance ] { + # config_item = value + # ... + # } + # + # The 'name' is used to load the 'rlm_name' library + # which implements the functionality of the module. + # + # The 'instance' is optional. To have two different instances + # of a module, it first must be referred to by 'name'. + # The different copies of the module are then created by + # inventing two 'instance' names, e.g. 'instance1' and 'instance2' + # + # The instance names can then be used in later configuration + # INSTEAD of the original 'name'. See the 'radutmp' configuration + # for an example. + # + + # + # As of 3.0, modules are in mods-enabled/. Files matching + # the regex /[a-zA-Z0-9_.]+/ are loaded. The modules are + # initialized ONLY if they are referenced in a processing + # section, such as authorize, authenticate, accounting, + # pre/post-proxy, etc. + # + $INCLUDE mods-enabled/ +} + +# Instantiation +# +# This section orders the loading of the modules. Modules +# listed here will get loaded BEFORE the later sections like +# authorize, authenticate, etc. get examined. +# +# This section is not strictly needed. When a section like +# authorize refers to a module, it's automatically loaded and +# initialized. However, some modules may not be listed in any +# of the following sections, so they can be listed here. +# +# Also, listing modules here ensures that you have control over +# the order in which they are initialized. If one module needs +# something defined by another module, you can list them in order +# here, and ensure that the configuration will be OK. +# +# After the modules listed here have been loaded, all of the modules +# in the "mods-enabled" directory will be loaded. Loading the +# "mods-enabled" directory means that unlike Version 2, you usually +# don't need to list modules here. +# +instantiate { + # + # We list the counter module here so that it registers + # the check_name attribute before any module which sets + # it +# daily + + # subsections here can be thought of as "virtual" modules. + # + # e.g. If you have two redundant SQL servers, and you want to + # use them in the authorize and accounting sections, you could + # place a "redundant" block in each section, containing the + # exact same text. Or, you could uncomment the following + # lines, and list "redundant_sql" in the authorize and + # accounting sections. + # + # The "virtual" module defined here can also be used with + # dynamic expansions, under a few conditions: + # + # * The section is "redundant", or "load-balance", or + # "redundant-load-balance" + # * The section contains modules ONLY, and no sub-sections + # * all modules in the section are using the same rlm_ + # driver, e.g. They are all sql, or all ldap, etc. + # + # When those conditions are satisfied, the server will + # automatically register a dynamic expansion, using the + # name of the "virtual" module. In the example below, + # it will be "redundant_sql". You can then use this expansion + # just like any other: + # + # update reply { + # Filter-Id := "%{redundant_sql: ... }" + # } + # + # In this example, the expansion is done via module "sql1", + # and if that expansion fails, using module "sql2". + # + # For best results, configure the "pool" subsection of the + # module so that "retry_delay" is non-zero. That will allow + # the redundant block to quickly ignore all "down" SQL + # databases. If instead we have "retry_delay = 0", then + # every time the redundant block is used, the server will try + # to open a connection to every "down" database, causing + # problems. + # + #redundant redundant_sql { + # sql1 + # sql2 + #} +} + +###################################################################### +# +# Policies are virtual modules, similar to those defined in the +# "instantiate" section above. +# +# Defining a policy in one of the policy.d files means that it can be +# referenced in multiple places as a *name*, rather than as a series of +# conditions to match, and actions to take. +# +# Policies are something like subroutines in a normal language, but +# they cannot be called recursively. They MUST be defined in order. +# If policy A calls policy B, then B MUST be defined before A. +# +###################################################################### +policy { + $INCLUDE policy.d/ +} + +###################################################################### +# +# Load virtual servers. +# +# This next $INCLUDE line loads files in the directory that +# match the regular expression: /[a-zA-Z0-9_.]+/ +# +# It allows you to define new virtual servers simply by placing +# a file into the raddb/sites-enabled/ directory. +# +$INCLUDE sites-enabled/ + +###################################################################### +# +# All of the other configuration sections like "authorize {}", +# "authenticate {}", "accounting {}", have been moved to the +# the file: +# +# raddb/sites-available/default +# +# This is the "default" virtual server that has the same +# configuration as in version 1.0.x and 1.1.x. The default +# installation enables this virtual server. You should +# edit it to create policies for your local site. +# +# For more documentation on virtual servers, see: +# +# raddb/sites-available/README +# +###################################################################### +{% endraw %} +{% endif %} diff --git a/net/freeradius/src/opnsense/service/templates/OPNsense/Freeradius/sites-enabled-default b/net/freeradius/src/opnsense/service/templates/OPNsense/Freeradius/sites-enabled-default new file mode 100644 index 000000000..7ca270cc2 --- /dev/null +++ b/net/freeradius/src/opnsense/service/templates/OPNsense/Freeradius/sites-enabled-default @@ -0,0 +1,954 @@ +{% if helpers.exists('OPNsense.freeradius.general.enabled') and OPNsense.freeradius.general.enabled == '1' %} +{% raw %} +###################################################################### +# +# As of 2.0.0, FreeRADIUS supports virtual hosts using the +# "server" section, and configuration directives. +# +# Virtual hosts should be put into the "sites-available" +# directory. Soft links should be created in the "sites-enabled" +# directory to these files. This is done in a normal installation. +# +# If you are using 802.1X (EAP) authentication, please see also +# the "inner-tunnel" virtual server. You will likely have to edit +# that, too, for authentication to work. +# +# $Id: 292abcc492c6e21594ed93b2fbbd9ab226e4440d $ +# +###################################################################### +# +# Read "man radiusd" before editing this file. See the section +# titled DEBUGGING. It outlines a method where you can quickly +# obtain the configuration you want, without running into +# trouble. See also "man unlang", which documents the format +# of this file. +# +# This configuration is designed to work in the widest possible +# set of circumstances, with the widest possible number of +# authentication methods. This means that in general, you should +# need to make very few changes to this file. +# +# The best way to configure the server for your local system +# is to CAREFULLY edit this file. Most attempts to make large +# edits to this file will BREAK THE SERVER. Any edits should +# be small, and tested by running the server with "radiusd -X". +# Once the edits have been verified to work, save a copy of these +# configuration files somewhere. (e.g. as a "tar" file). Then, +# make more edits, and test, as above. +# +# There are many "commented out" references to modules such +# as ldap, sql, etc. These references serve as place-holders. +# If you need the functionality of that module, then configure +# it in radiusd.conf, and un-comment the references to it in +# this file. In most cases, those small changes will result +# in the server being able to connect to the DB, and to +# authenticate users. +# +###################################################################### + +server default { +# +# If you want the server to listen on additional addresses, or on +# additional ports, you can use multiple "listen" sections. +# +# Each section make the server listen for only one type of packet, +# therefore authentication and accounting have to be configured in +# different sections. +# +# The server ignore all "listen" section if you are using '-i' and '-p' +# on the command line. +# +listen { + # Type of packets to listen for. + # Allowed values are: + # auth listen for authentication packets + # acct listen for accounting packets + # proxy IP to use for sending proxied packets + # detail Read from the detail file. For examples, see + # raddb/sites-available/copy-acct-to-home-server + # status listen for Status-Server packets. For examples, + # see raddb/sites-available/status + # coa listen for CoA-Request and Disconnect-Request + # packets. For examples, see the file + # raddb/sites-available/coa + # + type = auth + + # Note: "type = proxy" lets you control the source IP used for + # proxying packets, with some limitations: + # + # * A proxy listener CANNOT be used in a virtual server section. + # * You should probably set "port = 0". + # * Any "clients" configuration will be ignored. + # + # See also proxy.conf, and the "src_ipaddr" configuration entry + # in the sample "home_server" section. When you specify the + # source IP address for packets sent to a home server, the + # proxy listeners are automatically created. + + # ipaddr/ipv4addr/ipv6addr - IP address on which to listen. + # If multiple ones are listed, only the first one will + # be used, and the others will be ignored. + # + # The configuration options accept the following syntax: + # + # ipv4addr - IPv4 address (e.g.192.0.2.3) + # - wildcard (i.e. *) + # - hostname (radius.example.com) + # Only the A record for the host name is used. + # If there is no A record, an error is returned, + # and the server fails to start. + # + # ipv6addr - IPv6 address (e.g. 2001:db8::1) + # - wildcard (i.e. *) + # - hostname (radius.example.com) + # Only the AAAA record for the host name is used. + # If there is no AAAA record, an error is returned, + # and the server fails to start. + # + # ipaddr - IPv4 address as above + # - IPv6 address as above + # - wildcard (i.e. *), which means IPv4 wildcard. + # - hostname + # If there is only one A or AAAA record returned + # for the host name, it is used. + # If multiple A or AAAA records are returned + # for the host name, only the first one is used. + # If both A and AAAA records are returned + # for the host name, only the A record is used. + # + # ipv4addr = * + # ipv6addr = * + ipaddr = * + + # Port on which to listen. + # Allowed values are: + # integer port number (1812) + # 0 means "use /etc/services for the proper port" + port = 0 + + # Some systems support binding to an interface, in addition + # to the IP address. This feature isn't strictly necessary, + # but for sites with many IP addresses on one interface, + # it's useful to say "listen on all addresses for eth0". + # + # If your system does not support this feature, you will + # get an error if you try to use it. + # +# interface = eth0 + + # Per-socket lists of clients. This is a very useful feature. + # + # The name here is a reference to a section elsewhere in + # radiusd.conf, or clients.conf. Having the name as + # a reference allows multiple sockets to use the same + # set of clients. + # + # If this configuration is used, then the global list of clients + # is IGNORED for this "listen" section. Take care configuring + # this feature, to ensure you don't accidentally disable a + # client you need. + # + # See clients.conf for the configuration of "per_socket_clients". + # +# clients = per_socket_clients + + # + # Connection limiting for sockets with "proto = tcp". + # + # This section is ignored for other kinds of sockets. + # + limit { + # + # Limit the number of simultaneous TCP connections to the socket + # + # The default is 16. + # Setting this to 0 means "no limit" + max_connections = 16 + + # The per-socket "max_requests" option does not exist. + + # + # The lifetime, in seconds, of a TCP connection. After + # this lifetime, the connection will be closed. + # + # Setting this to 0 means "forever". + lifetime = 0 + + # + # The idle timeout, in seconds, of a TCP connection. + # If no packets have been received over the connection for + # this time, the connection will be closed. + # + # Setting this to 0 means "no timeout". + # + # We STRONGLY RECOMMEND that you set an idle timeout. + # + idle_timeout = 30 + } +} + +# +# This second "listen" section is for listening on the accounting +# port, too. +# +listen { + ipaddr = * +# ipv6addr = :: + port = 0 + type = acct +# interface = eth0 +# clients = per_socket_clients + + limit { + # The number of packets received can be rate limited via the + # "max_pps" configuration item. When it is set, the server + # tracks the total number of packets received in the previous + # second. If the count is greater than "max_pps", then the + # new packet is silently discarded. This helps the server + # deal with overload situations. + # + # The packets/s counter is tracked in a sliding window. This + # means that the pps calculation is done for the second + # before the current packet was received. NOT for the current + # wall-clock second, and NOT for the previous wall-clock second. + # + # Useful values are 0 (no limit), or 100 to 10000. + # Values lower than 100 will likely cause the server to ignore + # normal traffic. Few systems are capable of handling more than + # 10K packets/s. + # + # It is most useful for accounting systems. Set it to 50% + # more than the normal accounting load, and you can be sure that + # the server will never get overloaded + # +# max_pps = 0 + + # Only for "proto = tcp". These are ignored for "udp" sockets. + # +# idle_timeout = 0 +# lifetime = 0 +# max_connections = 0 + } +} + +# IPv6 versions of the above - read their full config to understand options +listen { + type = auth + ipv6addr = :: # any. ::1 == localhost + port = 0 +# interface = eth0 +# clients = per_socket_clients + limit { + max_connections = 16 + lifetime = 0 + idle_timeout = 30 + } +} + +listen { + ipv6addr = :: + port = 0 + type = acct +# interface = eth0 +# clients = per_socket_clients + + limit { +# max_pps = 0 +# idle_timeout = 0 +# lifetime = 0 +# max_connections = 0 + } +} + +# Authorization. First preprocess (hints and huntgroups files), +# then realms, and finally look in the "users" file. +# +# Any changes made here should also be made to the "inner-tunnel" +# virtual server. +# +# The order of the realm modules will determine the order that +# we try to find a matching realm. +# +# Make *sure* that 'preprocess' comes before any realm if you +# need to setup hints for the remote radius server +authorize { + # + # Take a User-Name, and perform some checks on it, for spaces and other + # invalid characters. If the User-Name appears invalid, reject the + # request. + # + # See policy.d/filter for the definition of the filter_username policy. + # + filter_username + + # + # Some broken equipment sends passwords with embedded zeros. + # i.e. the debug output will show + # + # User-Password = "password\000\000" + # + # This policy will fix it to just be "password". + # +# filter_password + + # + # The preprocess module takes care of sanitizing some bizarre + # attributes in the request, and turning them into attributes + # which are more standard. + # + # It takes care of processing the 'raddb/mods-config/preprocess/hints' + # and the 'raddb/mods-config/preprocess/huntgroups' files. + preprocess + + # If you intend to use CUI and you require that the Operator-Name + # be set for CUI generation and you want to generate CUI also + # for your local clients then uncomment the operator-name + # below and set the operator-name for your clients in clients.conf +# operator-name + + # + # If you want to generate CUI for some clients that do not + # send proper CUI requests, then uncomment the + # cui below and set "add_cui = yes" for these clients in clients.conf +# cui + + # + # If you want to have a log of authentication requests, + # un-comment the following line. +# auth_log + + # + # The chap module will set 'Auth-Type := CHAP' if we are + # handling a CHAP request and Auth-Type has not already been set + chap + + # + # If the users are logging in with an MS-CHAP-Challenge + # attribute for authentication, the mschap module will find + # the MS-CHAP-Challenge attribute, and add 'Auth-Type := MS-CHAP' + # to the request, which will cause the server to then use + # the mschap module for authentication. + mschap + + # + # If you have a Cisco SIP server authenticating against + # FreeRADIUS, uncomment the following line, and the 'digest' + # line in the 'authenticate' section. + digest + + # + # The WiMAX specification says that the Calling-Station-Id + # is 6 octets of the MAC. This definition conflicts with + # RFC 3580, and all common RADIUS practices. Un-commenting + # the "wimax" module here means that it will fix the + # Calling-Station-Id attribute to the normal format as + # specified in RFC 3580 Section 3.21 +# wimax + + # + # Look for IPASS style 'realm/', and if not found, look for + # '@realm', and decide whether or not to proxy, based on + # that. +# IPASS + + # + # If you are using multiple kinds of realms, you probably + # want to set "ignore_null = yes" for all of them. + # Otherwise, when the first style of realm doesn't match, + # the other styles won't be checked. + # + suffix +# ntdomain + + # + # This module takes care of EAP-MD5, EAP-TLS, and EAP-LEAP + # authentication. + # + # It also sets the EAP-Type attribute in the request + # attribute list to the EAP type from the packet. + # + # The EAP module returns "ok" or "updated" if it is not yet ready + # to authenticate the user. The configuration below checks for + # "ok", and stops processing the "authorize" section if so. + # + # Any LDAP and/or SQL servers will not be queried for the + # initial set of packets that go back and forth to set up + # TTLS or PEAP. + # + # The "updated" check is commented out for compatibility with + # previous versions of this configuration, but you may wish to + # uncomment it as well; this will further reduce the number of + # LDAP and/or SQL queries for TTLS or PEAP. + # + eap { + ok = return +# updated = return + } + + # + # Pull crypt'd passwords from /etc/passwd or /etc/shadow, + # using the system API's to get the password. If you want + # to read /etc/passwd or /etc/shadow directly, see the + # mods-available/passwd module. + # +# unix + + # + # Read the 'users' file. In v3, this is located in + # raddb/mods-config/files/authorize + files + + # + # Look in an SQL database. The schema of the database + # is meant to mirror the "users" file. + # + # See "Authorization Queries" in mods-available/sql + -sql + + # + # If you are using /etc/smbpasswd, and are also doing + # mschap authentication, the un-comment this line, and + # configure the 'smbpasswd' module. +# smbpasswd + + # + # The ldap module reads passwords from the LDAP database. + -ldap + + # + # Enforce daily limits on time spent logged in. +# daily + + # + expiration + logintime + + # + # If no other module has claimed responsibility for + # authentication, then try to use PAP. This allows the + # other modules listed above to add a "known good" password + # to the request, and to do nothing else. The PAP module + # will then see that password, and use it to do PAP + # authentication. + # + # This module should be listed last, so that the other modules + # get a chance to set Auth-Type for themselves. + # + pap + + # + # If "status_server = yes", then Status-Server messages are passed + # through the following section, and ONLY the following section. + # This permits you to do DB queries, for example. If the modules + # listed here return "fail", then NO response is sent. + # +# Autz-Type Status-Server { +# +# } +} + + +# Authentication. +# +# +# This section lists which modules are available for authentication. +# Note that it does NOT mean 'try each module in order'. It means +# that a module from the 'authorize' section adds a configuration +# attribute 'Auth-Type := FOO'. That authentication type is then +# used to pick the appropriate module from the list below. +# + +# In general, you SHOULD NOT set the Auth-Type attribute. The server +# will figure it out on its own, and will do the right thing. The +# most common side effect of erroneously setting the Auth-Type +# attribute is that one authentication method will work, but the +# others will not. +# +# The common reasons to set the Auth-Type attribute by hand +# is to either forcibly reject the user (Auth-Type := Reject), +# or to or forcibly accept the user (Auth-Type := Accept). +# +# Note that Auth-Type := Accept will NOT work with EAP. +# +# Please do not put "unlang" configurations into the "authenticate" +# section. Put them in the "post-auth" section instead. That's what +# the post-auth section is for. +# +authenticate { + # + # PAP authentication, when a back-end database listed + # in the 'authorize' section supplies a password. The + # password can be clear-text, or encrypted. + Auth-Type PAP { + pap + } + + # + # Most people want CHAP authentication + # A back-end database listed in the 'authorize' section + # MUST supply a CLEAR TEXT password. Encrypted passwords + # won't work. + Auth-Type CHAP { + chap + } + + # + # MSCHAP authentication. + Auth-Type MS-CHAP { + mschap + } + + # + # For old names, too. + # + mschap + + # + # If you have a Cisco SIP server authenticating against + # FreeRADIUS, uncomment the following line, and the 'digest' + # line in the 'authorize' section. + digest + + # + # Pluggable Authentication Modules. +# pam + + # Uncomment it if you want to use ldap for authentication + # + # Note that this means "check plain-text password against + # the ldap database", which means that EAP won't work, + # as it does not supply a plain-text password. + # + # We do NOT recommend using this. LDAP servers are databases. + # They are NOT authentication servers. FreeRADIUS is an + # authentication server, and knows what to do with authentication. + # LDAP servers do not. + # +# Auth-Type LDAP { +# ldap +# } + + # + # Allow EAP authentication. + eap + + # + # The older configurations sent a number of attributes in + # Access-Challenge packets, which wasn't strictly correct. + # If you want to filter out these attributes, uncomment + # the following lines. + # +# Auth-Type eap { +# eap { +# handled = 1 +# } +# if (handled && (Response-Packet-Type == Access-Challenge)) { +# attr_filter.access_challenge.post-auth +# handled # override the "updated" code from attr_filter +# } +# } +} + + +# +# Pre-accounting. Decide which accounting type to use. +# +preacct { + preprocess + + # + # Merge Acct-[Input|Output]-Gigawords and Acct-[Input-Output]-Octets + # into a single 64bit counter Acct-[Input|Output]-Octets64. + # +# acct_counters64 + + # + # Session start times are *implied* in RADIUS. + # The NAS never sends a "start time". Instead, it sends + # a start packet, *possibly* with an Acct-Delay-Time. + # The server is supposed to conclude that the start time + # was "Acct-Delay-Time" seconds in the past. + # + # The code below creates an explicit start time, which can + # then be used in other modules. It will be *mostly* correct. + # Any errors are due to the 1-second resolution of RADIUS, + # and the possibility that the time on the NAS may be off. + # + # The start time is: NOW - delay - session_length + # + +# update request { +# FreeRADIUS-Acct-Session-Start-Time = "%{expr: %l - %{%{Acct-Session-Time}:-0} - %{%{Acct-Delay-Time}:-0}}" +# } + + + # + # Ensure that we have a semi-unique identifier for every + # request, and many NAS boxes are broken. + acct_unique + + # + # Look for IPASS-style 'realm/', and if not found, look for + # '@realm', and decide whether or not to proxy, based on + # that. + # + # Accounting requests are generally proxied to the same + # home server as authentication requests. +# IPASS + suffix +# ntdomain + + # + # Read the 'acct_users' file + files +} + +# +# Accounting. Log the accounting data. +# +accounting { + # Update accounting packet by adding the CUI attribute + # recorded from the corresponding Access-Accept + # use it only if your NAS boxes do not support CUI themselves +# cui + # + # Create a 'detail'ed log of the packets. + # Note that accounting requests which are proxied + # are also logged in the detail file. + detail +# daily + + # Update the wtmp file + # + # If you don't use "radlast", you can delete this line. + unix + + # + # For Simultaneous-Use tracking. + # + # Due to packet losses in the network, the data here + # may be incorrect. There is little we can do about it. +# radutmp +# sradutmp + + # Return an address to the IP Pool when we see a stop record. +# main_pool + + # + # Log traffic to an SQL database. + # + # See "Accounting queries" in mods-available/sql + -sql + + # + # If you receive stop packets with zero session length, + # they will NOT be logged in the database. The SQL module + # will print a message (only in debugging mode), and will + # return "noop". + # + # You can ignore these packets by uncommenting the following + # three lines. Otherwise, the server will not respond to the + # accounting request, and the NAS will retransmit. + # +# if (noop) { +# ok +# } + + # + # Instead of sending the query to the SQL server, + # write it into a log file. + # +# sql_log + + # Cisco VoIP specific bulk accounting +# pgsql-voip + + # For Exec-Program and Exec-Program-Wait + exec + + # Filter attributes from the accounting response. + attr_filter.accounting_response + + # + # See "Autz-Type Status-Server" for how this works. + # +# Acct-Type Status-Server { +# +# } +} + + +# Session database, used for checking Simultaneous-Use. Either the radutmp +# or rlm_sql module can handle this. +# The rlm_sql module is *much* faster +session { +# radutmp + + # + # See "Simultaneous Use Checking Queries" in mods-available/sql +# sql +} + + +# Post-Authentication +# Once we KNOW that the user has been authenticated, there are +# additional steps we can take. +post-auth { + # + # If you need to have a State attribute, you can + # add it here. e.g. for later CoA-Request with + # State, and Service-Type = Authorize-Only. + # +# if (!&reply:State) { +# update reply { +# State := "0x%{randstr:16h}" +# } +# } + + # + # For EAP-TTLS and PEAP, add the cached attributes to the reply. + # The "session-state" attributes are automatically cached when + # an Access-Challenge is sent, and automatically retrieved + # when an Access-Request is received. + # + # The session-state attributes are automatically deleted after + # an Access-Reject or Access-Accept is sent. + # + update { + &reply: += &session-state: + } + + # Get an address from the IP Pool. +# main_pool + + + # Create the CUI value and add the attribute to Access-Accept. + # Uncomment the line below if *returning* the CUI. +# cui + + # + # If you want to have a log of authentication replies, + # un-comment the following line, and enable the + # 'detail reply_log' module. +# reply_log + + # + # After authenticating the user, do another SQL query. + # + # See "Authentication Logging Queries" in mods-available/sql + -sql + + # + # Instead of sending the query to the SQL server, + # write it into a log file. + # +# sql_log + + # + # Un-comment the following if you want to modify the user's object + # in LDAP after a successful login. + # +# ldap + + # For Exec-Program and Exec-Program-Wait + exec + + # + # Calculate the various WiMAX keys. In order for this to work, + # you will need to define the WiMAX NAI, usually via + # + # update request { + # WiMAX-MN-NAI = "%{User-Name}" + # } + # + # If you want various keys to be calculated, you will need to + # update the reply with "template" values. The module will see + # this, and replace the template values with the correct ones + # taken from the cryptographic calculations. e.g. + # + # update reply { + # WiMAX-FA-RK-Key = 0x00 + # WiMAX-MSK = "%{EAP-MSK}" + # } + # + # You may want to delete the MS-MPPE-*-Keys from the reply, + # as some WiMAX clients behave badly when those attributes + # are included. See "raddb/modules/wimax", configuration + # entry "delete_mppe_keys" for more information. + # +# wimax + + + # If there is a client certificate (EAP-TLS, sometimes PEAP + # and TTLS), then some attributes are filled out after the + # certificate verification has been performed. These fields + # MAY be available during the authentication, or they may be + # available only in the "post-auth" section. + # + # The first set of attributes contains information about the + # issuing certificate which is being used. The second + # contains information about the client certificate (if + # available). +# +# update reply { +# Reply-Message += "%{TLS-Cert-Serial}" +# Reply-Message += "%{TLS-Cert-Expiration}" +# Reply-Message += "%{TLS-Cert-Subject}" +# Reply-Message += "%{TLS-Cert-Issuer}" +# Reply-Message += "%{TLS-Cert-Common-Name}" +# Reply-Message += "%{TLS-Cert-Subject-Alt-Name-Email}" +# +# Reply-Message += "%{TLS-Client-Cert-Serial}" +# Reply-Message += "%{TLS-Client-Cert-Expiration}" +# Reply-Message += "%{TLS-Client-Cert-Subject}" +# Reply-Message += "%{TLS-Client-Cert-Issuer}" +# Reply-Message += "%{TLS-Client-Cert-Common-Name}" +# Reply-Message += "%{TLS-Client-Cert-Subject-Alt-Name-Email}" +# } + + # Insert class attribute (with unique value) into response, + # aids matching auth and acct records, and protects against duplicate + # Acct-Session-Id. Note: Only works if the NAS has implemented + # RFC 2865 behaviour for the class attribute, AND if the NAS + # supports long Class attributes. Many older or cheap NASes + # only support 16-octet Class attributes. +# insert_acct_class + + # MacSEC requires the use of EAP-Key-Name. However, we don't + # want to send it for all EAP sessions. Therefore, the EAP + # modules put required data into the EAP-Session-Id attribute. + # This attribute is never put into a request or reply packet. + # + # Uncomment the next few lines to copy the required data into + # the EAP-Key-Name attribute +# if (&reply:EAP-Session-Id) { +# update reply { +# EAP-Key-Name := &reply:EAP-Session-Id +# } +# } + + # Remove reply message if the response contains an EAP-Message + remove_reply_message_if_eap + + # + # Access-Reject packets are sent through the REJECT sub-section of the + # post-auth section. + # + # Add the ldap module name (or instance) if you have set + # 'edir_account_policy_check = yes' in the ldap module configuration + # + # The "session-state" attributes are not available here. + # + Post-Auth-Type REJECT { + # log failed authentications in SQL, too. + -sql + attr_filter.access_reject + + # Insert EAP-Failure message if the request was + # rejected by policy instead of because of an + # authentication failure + eap + + # Remove reply message if the response contains an EAP-Message + remove_reply_message_if_eap + } + + # + # Filter access challenges. + # + Post-Auth-Type Challenge { +# remove_reply_message_if_eap +# attr_filter.access_challenge.post-auth + } + +} + +# +# When the server decides to proxy a request to a home server, +# the proxied request is first passed through the pre-proxy +# stage. This stage can re-write the request, or decide to +# cancel the proxy. +# +# Only a few modules currently have this method. +# +pre-proxy { + # Before proxing the request add an Operator-Name attribute identifying + # if the operator-name is found for this client. + # No need to uncomment this if you have already enabled this in + # the authorize section. +# operator-name + + # The client requests the CUI by sending a CUI attribute + # containing one zero byte. + # Uncomment the line below if *requesting* the CUI. +# cui + + # Uncomment the following line if you want to change attributes + # as defined in the preproxy_users file. +# files + + # Uncomment the following line if you want to filter requests + # sent to remote servers based on the rules defined in the + # 'attrs.pre-proxy' file. +# attr_filter.pre-proxy + + # If you want to have a log of packets proxied to a home + # server, un-comment the following line, and the + # 'detail pre_proxy_log' section, above. +# pre_proxy_log +} + +# +# When the server receives a reply to a request it proxied +# to a home server, the request may be massaged here, in the +# post-proxy stage. +# +post-proxy { + + # If you want to have a log of replies from a home server, + # un-comment the following line, and the 'detail post_proxy_log' + # section, above. +# post_proxy_log + + # Uncomment the following line if you want to filter replies from + # remote proxies based on the rules defined in the 'attrs' file. +# attr_filter.post-proxy + + # + # If you are proxying LEAP, you MUST configure the EAP + # module, and you MUST list it here, in the post-proxy + # stage. + # + # You MUST also use the 'nostrip' option in the 'realm' + # configuration. Otherwise, the User-Name attribute + # in the proxied request will not match the user name + # hidden inside of the EAP packet, and the end server will + # reject the EAP request. + # + eap + + # + # If the server tries to proxy a request and fails, then the + # request is processed through the modules in this section. + # + # The main use of this section is to permit robust proxying + # of accounting packets. The server can be configured to + # proxy accounting packets as part of normal processing. + # Then, if the home server goes down, accounting packets can + # be logged to a local "detail" file, for processing with + # radrelay. When the home server comes back up, radrelay + # will read the detail file, and send the packets to the + # home server. + # + # With this configuration, the server always responds to + # Accounting-Requests from the NAS, but only writes + # accounting packets to disk if the home server is down. + # +# Post-Proxy-Type Fail-Accounting { +# detail +# } +} +} +{% endraw %} +{% endif %} diff --git a/net/freeradius/src/opnsense/service/templates/OPNsense/Freeradius/sites-enabled-inner-tunnel b/net/freeradius/src/opnsense/service/templates/OPNsense/Freeradius/sites-enabled-inner-tunnel new file mode 100644 index 000000000..55f987990 --- /dev/null +++ b/net/freeradius/src/opnsense/service/templates/OPNsense/Freeradius/sites-enabled-inner-tunnel @@ -0,0 +1,434 @@ +{% if helpers.exists('OPNsense.freeradius.general.enabled') and OPNsense.freeradius.general.enabled == '1' %} +# -*- text -*- +###################################################################### +# +# This is a virtual server that handles *only* inner tunnel +# requests for EAP-TTLS and PEAP types. +# +# $Id: 5479352d9f09e5a4f8519805694c724eaf78958f $ +# +###################################################################### + +server inner-tunnel { + +# +# This next section is here to allow testing of the "inner-tunnel" +# authentication methods, independently from the "default" server. +# It is listening on "localhost", so that it can only be used from +# the same machine. +# +# $ radtest USER PASSWORD 127.0.0.1:18120 0 testing123 +# +# If it works, you have configured the inner tunnel correctly. To check +# if PEAP will work, use: +# +# $ radtest -t mschap USER PASSWORD 127.0.0.1:18120 0 testing123 +# +# If that works, PEAP should work. If that command doesn't work, then +# +# FIX THE INNER TUNNEL CONFIGURATION SO THAT IT WORKS. +# +# Do NOT do any PEAP tests. It won't help. Instead, concentrate +# on fixing the inner tunnel configuration. DO NOTHING ELSE. +# +listen { + ipaddr = 127.0.0.1 + port = 18120 + type = auth +} + + +# Authorization. First preprocess (hints and huntgroups files), +# then realms, and finally look in the "users" file. +# +# The order of the realm modules will determine the order that +# we try to find a matching realm. +# +# Make *sure* that 'preprocess' comes before any realm if you +# need to setup hints for the remote radius server +authorize { + # + # Take a User-Name, and perform some checks on it, for spaces and other + # invalid characters. If the User-Name appears invalid, reject the + # request. + # + # See policy.d/filter for the definition of the filter_username policy. + # + filter_username + + # + # Do checks on outer / inner User-Name, so that users + # can't spoof us by using incompatible identities + # +# filter_inner_identity + + # + # The chap module will set 'Auth-Type := CHAP' if we are + # handling a CHAP request and Auth-Type has not already been set + chap + + # + # If the users are logging in with an MS-CHAP-Challenge + # attribute for authentication, the mschap module will find + # the MS-CHAP-Challenge attribute, and add 'Auth-Type := MS-CHAP' + # to the request, which will cause the server to then use + # the mschap module for authentication. + mschap + + # + # Pull crypt'd passwords from /etc/passwd or /etc/shadow, + # using the system API's to get the password. If you want + # to read /etc/passwd or /etc/shadow directly, see the + # passwd module, above. + # +# unix + + # + # Look for IPASS style 'realm/', and if not found, look for + # '@realm', and decide whether or not to proxy, based on + # that. +# IPASS + + # + # If you are using multiple kinds of realms, you probably + # want to set "ignore_null = yes" for all of them. + # Otherwise, when the first style of realm doesn't match, + # the other styles won't be checked. + # + # Note that proxying the inner tunnel authentication means + # that the user MAY use one identity in the outer session + # (e.g. "anonymous", and a different one here + # (e.g. "user@example.com"). The inner session will then be + # proxied elsewhere for authentication. If you are not + # careful, this means that the user can cause you to forward + # the authentication to another RADIUS server, and have the + # accounting logs *not* sent to the other server. This makes + # it difficult to bill people for their network activity. + # + suffix +# ntdomain + + # + # The "suffix" module takes care of stripping the domain + # (e.g. "@example.com") from the User-Name attribute, and the + # next few lines ensure that the request is not proxied. + # + # If you want the inner tunnel request to be proxied, delete + # the next few lines. + # + update control { + &Proxy-To-Realm := LOCAL + } + + # + # This module takes care of EAP-MSCHAPv2 authentication. + # + # It also sets the EAP-Type attribute in the request + # attribute list to the EAP type from the packet. + # + # The example below uses module failover to avoid querying all + # of the following modules if the EAP module returns "ok". + # Therefore, your LDAP and/or SQL servers will not be queried + # for the many packets that go back and forth to set up TTLS + # or PEAP. The load on those servers will therefore be reduced. + # + eap { + ok = return + } + + # + # Read the 'users' file + files + + # + # Look in an SQL database. The schema of the database + # is meant to mirror the "users" file. + # + # See "Authorization Queries" in sql.conf + -sql + + # + # If you are using /etc/smbpasswd, and are also doing + # mschap authentication, the un-comment this line, and + # enable the "smbpasswd" module. +# smbpasswd + + # + # The ldap module reads passwords from the LDAP database. + -ldap + + # + # Enforce daily limits on time spent logged in. +# daily + + expiration + logintime + + # + # If no other module has claimed responsibility for + # authentication, then try to use PAP. This allows the + # other modules listed above to add a "known good" password + # to the request, and to do nothing else. The PAP module + # will then see that password, and use it to do PAP + # authentication. + # + # This module should be listed last, so that the other modules + # get a chance to set Auth-Type for themselves. + # + pap +} + + +# Authentication. +# +# +# This section lists which modules are available for authentication. +# Note that it does NOT mean 'try each module in order'. It means +# that a module from the 'authorize' section adds a configuration +# attribute 'Auth-Type := FOO'. That authentication type is then +# used to pick the appropriate module from the list below. +# + +# In general, you SHOULD NOT set the Auth-Type attribute. The server +# will figure it out on its own, and will do the right thing. The +# most common side effect of erroneously setting the Auth-Type +# attribute is that one authentication method will work, but the +# others will not. +# +# The common reasons to set the Auth-Type attribute by hand +# is to either forcibly reject the user, or forcibly accept him. +# +authenticate { + # + # PAP authentication, when a back-end database listed + # in the 'authorize' section supplies a password. The + # password can be clear-text, or encrypted. + Auth-Type PAP { + pap + } + + # + # Most people want CHAP authentication + # A back-end database listed in the 'authorize' section + # MUST supply a CLEAR TEXT password. Encrypted passwords + # won't work. + Auth-Type CHAP { + chap + } + + # + # MSCHAP authentication. + Auth-Type MS-CHAP { + mschap + } + + # + # For old names, too. + # + mschap + + # + # Pluggable Authentication Modules. +# pam + + # Uncomment it if you want to use ldap for authentication + # + # Note that this means "check plain-text password against + # the ldap database", which means that EAP won't work, + # as it does not supply a plain-text password. + # + # We do NOT recommend using this. LDAP servers are databases. + # They are NOT authentication servers. FreeRADIUS is an + # authentication server, and knows what to do with authentication. + # LDAP servers do not. + # +# Auth-Type LDAP { +# ldap +# } + + # + # Allow EAP authentication. + eap +} + +###################################################################### +# +# There are no accounting requests inside of EAP-TTLS or PEAP +# tunnels. +# +###################################################################### + + +# Session database, used for checking Simultaneous-Use. Either the radutmp +# or rlm_sql module can handle this. +# The rlm_sql module is *much* faster +session { + radutmp + + # + # See "Simultaneous Use Checking Queries" in sql.conf +# sql +} + + +# Post-Authentication +# Once we KNOW that the user has been authenticated, there are +# additional steps we can take. +# +# Note that the last packet of the inner-tunnel authentication +# MAY NOT BE the last packet of the outer session. So updating +# the outer reply MIGHT work, and sometimes MIGHT NOT. The +# exact functionality depends on both the inner and outer +# authentication methods. +# +# If you need to send a reply attribute in the outer session, +# the ONLY safe way is to set "use_tunneled_reply = yes", and +# then update the inner-tunnel reply. +post-auth { + # If you want privacy to remain, see the + # Chargeable-User-Identity attribute from RFC 4372. + # If you want to use it just uncomment the line below. +# cui-inner + + # + # If you want to have a log of authentication replies, + # un-comment the following line, and enable the + # 'detail reply_log' module. +# reply_log + + # + # After authenticating the user, do another SQL query. + # + # See "Authentication Logging Queries" in sql.conf + -sql + + # + # Instead of sending the query to the SQL server, + # write it into a log file. + # +# sql_log + + # + # Un-comment the following if you have set + # 'edir_account_policy_check = yes' in the ldap module sub-section of + # the 'modules' section. + # +# ldap + + + # + # Un-comment the following if you want to generate Moonshot (ABFAB) TargetedIds + # IMPORTANT: This requires the UUID package to be installed! + # +# moonshot_host_tid +# moonshot_realm_tid +# moonshot_coi_tid + + # + # Instead of "use_tunneled_reply", change this "if (0)" to an + # "if (1)". + # + if (0) { + # + # These attributes are for the inner-tunnel only, + # and MUST NOT be copied to the outer reply. + # + update reply { + User-Name !* ANY + Message-Authenticator !* ANY + EAP-Message !* ANY + Proxy-State !* ANY + MS-MPPE-Encryption-Types !* ANY + MS-MPPE-Encryption-Policy !* ANY + MS-MPPE-Send-Key !* ANY + MS-MPPE-Recv-Key !* ANY + } + + # + # Copy the inner reply attributes to the outer + # session-state list. The post-auth policy will take + # care of copying the outer session-state list to the + # outer reply. + # + update { + &outer.session-state: += &reply: + } + } + + # + # Access-Reject packets are sent through the REJECT sub-section of the + # post-auth section. + # + # Add the ldap module name (or instance) if you have set + # 'edir_account_policy_check = yes' in the ldap module configuration + # + Post-Auth-Type REJECT { + # log failed authentications in SQL, too. + -sql + attr_filter.access_reject + + # + # Let the outer session know which module failed, and why. + # + update outer.session-state { + &Module-Failure-Message := &request:Module-Failure-Message + } + } +} + +# +# When the server decides to proxy a request to a home server, +# the proxied request is first passed through the pre-proxy +# stage. This stage can re-write the request, or decide to +# cancel the proxy. +# +# Only a few modules currently have this method. +# +pre-proxy { + # Uncomment the following line if you want to change attributes + # as defined in the preproxy_users file. +# files + + # Uncomment the following line if you want to filter requests + # sent to remote servers based on the rules defined in the + # 'attrs.pre-proxy' file. +# attr_filter.pre-proxy + + # If you want to have a log of packets proxied to a home + # server, un-comment the following line, and the + # 'detail pre_proxy_log' section, above. +# pre_proxy_log +} + +# +# When the server receives a reply to a request it proxied +# to a home server, the request may be massaged here, in the +# post-proxy stage. +# +post-proxy { + + # If you want to have a log of replies from a home server, + # un-comment the following line, and the 'detail post_proxy_log' + # section, above. +# post_proxy_log + + # Uncomment the following line if you want to filter replies from + # remote proxies based on the rules defined in the 'attrs' file. +# attr_filter.post-proxy + + # + # If you are proxying LEAP, you MUST configure the EAP + # module, and you MUST list it here, in the post-proxy + # stage. + # + # You MUST also use the 'nostrip' option in the 'realm' + # configuration. Otherwise, the User-Name attribute + # in the proxied request will not match the user name + # hidden inside of the EAP packet, and the end server will + # reject the EAP request. + # + eap +} + +} # inner-tunnel server block +{% endif %} diff --git a/net/freeradius/src/opnsense/service/templates/OPNsense/Freeradius/users b/net/freeradius/src/opnsense/service/templates/OPNsense/Freeradius/users new file mode 100644 index 000000000..10f38f5cf --- /dev/null +++ b/net/freeradius/src/opnsense/service/templates/OPNsense/Freeradius/users @@ -0,0 +1,31 @@ +{% if helpers.exists('OPNsense.freeradius.general.enabled') and OPNsense.freeradius.general.enabled == '1' %} + +{% if helpers.exists('OPNsense.freeradius.user.users.user') %} +{% for user_list in helpers.toList('OPNsense.freeradius.user.users.user') %} +{% if user_list.enabled == '1' %} +{{ user_list.username }} Cleartext-Password := "{{ user_list.password }}" + Framed-Protocol = PPP{% if user_list.ip is defined %}, + Framed-IP-Address = {{ user_list.ip }}{% endif %}{% if user_list.subnet is defined %}, + Framed-IP-Netmask = {{ user_list.subnet }}{% endif %}{% if user_list.vlan is defined %}, + Tunnel-Type = VLAN, + Tunnel-Medium-Type = IEEE-802, + Tunnel-Private-Group-Id = {{ user_list.vlan }} +{% endif %} + +{% endif %} + +{% endfor %} +{% endif %} + +DEFAULT Framed-Protocol == PPP + Framed-Protocol = PPP, + Framed-Compression = Van-Jacobson-TCP-IP + +DEFAULT Hint == "CSLIP" + Framed-Protocol = SLIP, + Framed-Compression = Van-Jacobson-TCP-IP + +DEFAULT Hint == "SLIP" + Framed-Protocol = SLIP + +{% endif %}