From 428d6b6822731acc42549ac5b5bb4752b5182bfa Mon Sep 17 00:00:00 2001 From: Frank Wall Date: Wed, 22 Jan 2025 12:09:25 +0100 Subject: [PATCH] new plugin: net/turnserver, closes #4473 based on devel/helloworld plugin --- net/turnserver/Makefile | 7 + net/turnserver/pkg-descr | 4 + .../src/etc/inc/plugins.inc.d/turnserver.inc | 71 ++++++++++ .../Turnserver/Api/ServiceController.php | 42 ++++++ .../Turnserver/Api/SettingsController.php | 44 ++++++ .../OPNsense/Turnserver/IndexController.php | 47 +++++++ .../OPNsense/Turnserver/forms/settings.xml | 127 ++++++++++++++++++ .../models/OPNsense/Turnserver/ACL/ACL.xml | 9 ++ .../models/OPNsense/Turnserver/Menu/Menu.xml | 5 + .../models/OPNsense/Turnserver/Turnserver.php | 53 ++++++++ .../models/OPNsense/Turnserver/Turnserver.xml | 97 +++++++++++++ .../app/views/OPNsense/Turnserver/index.volt | 57 ++++++++ .../OPNsense/Turnserver/export_certs.php | 61 +++++++++ .../scripts/OPNsense/Turnserver/setup.sh | 3 + .../conf/actions.d/actions_turnserver.conf | 26 ++++ .../templates/OPNsense/Turnserver/+TARGETS | 2 + .../templates/OPNsense/Turnserver/rc.conf.d | 5 + .../OPNsense/Turnserver/turnserver.conf | 60 +++++++++ 18 files changed, 720 insertions(+) create mode 100644 net/turnserver/Makefile create mode 100644 net/turnserver/pkg-descr create mode 100644 net/turnserver/src/etc/inc/plugins.inc.d/turnserver.inc create mode 100644 net/turnserver/src/opnsense/mvc/app/controllers/OPNsense/Turnserver/Api/ServiceController.php create mode 100644 net/turnserver/src/opnsense/mvc/app/controllers/OPNsense/Turnserver/Api/SettingsController.php create mode 100644 net/turnserver/src/opnsense/mvc/app/controllers/OPNsense/Turnserver/IndexController.php create mode 100644 net/turnserver/src/opnsense/mvc/app/controllers/OPNsense/Turnserver/forms/settings.xml create mode 100644 net/turnserver/src/opnsense/mvc/app/models/OPNsense/Turnserver/ACL/ACL.xml create mode 100644 net/turnserver/src/opnsense/mvc/app/models/OPNsense/Turnserver/Menu/Menu.xml create mode 100644 net/turnserver/src/opnsense/mvc/app/models/OPNsense/Turnserver/Turnserver.php create mode 100644 net/turnserver/src/opnsense/mvc/app/models/OPNsense/Turnserver/Turnserver.xml create mode 100644 net/turnserver/src/opnsense/mvc/app/views/OPNsense/Turnserver/index.volt create mode 100755 net/turnserver/src/opnsense/scripts/OPNsense/Turnserver/export_certs.php create mode 100755 net/turnserver/src/opnsense/scripts/OPNsense/Turnserver/setup.sh create mode 100644 net/turnserver/src/opnsense/service/conf/actions.d/actions_turnserver.conf create mode 100644 net/turnserver/src/opnsense/service/templates/OPNsense/Turnserver/+TARGETS create mode 100644 net/turnserver/src/opnsense/service/templates/OPNsense/Turnserver/rc.conf.d create mode 100644 net/turnserver/src/opnsense/service/templates/OPNsense/Turnserver/turnserver.conf diff --git a/net/turnserver/Makefile b/net/turnserver/Makefile new file mode 100644 index 0000000000..dfe3b1ce6e --- /dev/null +++ b/net/turnserver/Makefile @@ -0,0 +1,7 @@ +PLUGIN_NAME= turnserver +PLUGIN_VERSION= 1.0 +PLUGIN_COMMENT= The coturn STUN/TURN Server +PLUGIN_DEPENDS= turnserver +PLUGIN_MAINTAINER= opnsense@moov.de + +.include "../../Mk/plugins.mk" diff --git a/net/turnserver/pkg-descr b/net/turnserver/pkg-descr new file mode 100644 index 0000000000..f801217423 --- /dev/null +++ b/net/turnserver/pkg-descr @@ -0,0 +1,4 @@ +Coturn is a free open source implementation of TURN and STUN Server. +The TURN Server is a VoIP media traffic NAT traversal server and gateway. + +WWW: https://github.com/coturn/coturn diff --git a/net/turnserver/src/etc/inc/plugins.inc.d/turnserver.inc b/net/turnserver/src/etc/inc/plugins.inc.d/turnserver.inc new file mode 100644 index 0000000000..26757713ba --- /dev/null +++ b/net/turnserver/src/etc/inc/plugins.inc.d/turnserver.inc @@ -0,0 +1,71 @@ + gettext('coturn STUN/TURN Server'), + 'pidfile' => '/var/run/turnserver.pid', + 'configd' => array( + 'restart' => array('turnserver restart'), + 'start' => array('turnserver start'), + 'stop' => array('turnserver stop'), + ), + 'name' => 'turnserver', + ); + + return $services; +} + +function turnserver_xmlrpc_sync() +{ + $result = array(); + $result['id'] = 'turnserver'; + $result['section'] = 'OPNsense.turnserver'; + $result['description'] = gettext('coturn STUN/TURN Server'); + $result['services'] = ['turnserver']; + return array($result); +} diff --git a/net/turnserver/src/opnsense/mvc/app/controllers/OPNsense/Turnserver/Api/ServiceController.php b/net/turnserver/src/opnsense/mvc/app/controllers/OPNsense/Turnserver/Api/ServiceController.php new file mode 100644 index 0000000000..3973ff2e60 --- /dev/null +++ b/net/turnserver/src/opnsense/mvc/app/controllers/OPNsense/Turnserver/Api/ServiceController.php @@ -0,0 +1,42 @@ +view->pick('OPNsense/Turnserver/index'); + // fetch form data + $this->view->settingsForm = $this->getForm("settings"); + } +} diff --git a/net/turnserver/src/opnsense/mvc/app/controllers/OPNsense/Turnserver/forms/settings.xml b/net/turnserver/src/opnsense/mvc/app/controllers/OPNsense/Turnserver/forms/settings.xml new file mode 100644 index 0000000000..37f6633cb3 --- /dev/null +++ b/net/turnserver/src/opnsense/mvc/app/controllers/OPNsense/Turnserver/forms/settings.xml @@ -0,0 +1,127 @@ +
+ + + header + + + turnserver.settings.Enabled + + checkbox + Enable the Turnserver service + + + turnserver.settings.ListenIP + + + select_multiple + true + + + + turnserver.settings.ListenPort + + text + TURN listener port for UDP and TCP (Default: 3478). NOTE: Do NOT set this to 80 or 443 when listening on all IPs, this may block access to the OPNsense WebUI. + + + turnserver.settings.MinPort + + text + Lower bound of the UDP relay endpoints (Default: 49152). + + + turnserver.settings.MaxPort + + text + Upper bound of the UDP relay endpoints (Default: 65535). + + + + header + + + turnserver.settings.TlsEnabled + + checkbox + Enable TLS/DTLS support. This requires a valid TLS certificate. + + + turnserver.settings.TlsCertificate + + dropdown + + Select a valid TLS certificate. + + + turnserver.settings.TlsPort + + text + TURN listener port for TLS (Default: 5349). NOTE: Do NOT set this to 80 or 443 when listening on all IPs, this may block access to the OPNsense WebUI. + + + + header + + + turnserver.settings.UseAuthSecret + + checkbox + This sets a special authorization option that is based upon authentication secret. Enables TURN REST API. + + + turnserver.settings.StaticAuthSecret + + password + The authentication secret value for TURN REST API. It is recommended to use a long random string, at least 32 characters long. + + + + header + + + turnserver.settings.Realm + + text + The default realm to be used for the users. Must be used with TURN REST API. A good choice may be the domain name of the company. + + + turnserver.settings.FingerprintsEnabled + + checkbox + Use fingerprints in the TURN messages. + + + + header + + + turnserver.settings.UserQuota + + text + Per-user allocation quota. Default value is 0 (no quota, unlimited number of sessions per user). + + + turnserver.settings.TotalQuota + + text + Total allocation quota. Default value is 0 (no quota). + + + turnserver.settings.StaleNonce + + text + Limit the nonce lifetime (in seconds) for extra security. Default value is 600 secs (10 minutes). + + + turnserver.settings.ChannelLifetime + + text + The lifetime for the channel (in seconds). Default value is 600 secs (10 minutes). + + + turnserver.settings.PermissionLifetime + + text + The permission lifetime (in seconds). Default value is 300 secs (5 minutes). + +
diff --git a/net/turnserver/src/opnsense/mvc/app/models/OPNsense/Turnserver/ACL/ACL.xml b/net/turnserver/src/opnsense/mvc/app/models/OPNsense/Turnserver/ACL/ACL.xml new file mode 100644 index 0000000000..2fa8a37a6d --- /dev/null +++ b/net/turnserver/src/opnsense/mvc/app/models/OPNsense/Turnserver/ACL/ACL.xml @@ -0,0 +1,9 @@ + + + Services: Turnserver + + ui/turnserver/* + api/turnserver/* + + + diff --git a/net/turnserver/src/opnsense/mvc/app/models/OPNsense/Turnserver/Menu/Menu.xml b/net/turnserver/src/opnsense/mvc/app/models/OPNsense/Turnserver/Menu/Menu.xml new file mode 100644 index 0000000000..8b40dc89a1 --- /dev/null +++ b/net/turnserver/src/opnsense/mvc/app/models/OPNsense/Turnserver/Menu/Menu.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/net/turnserver/src/opnsense/mvc/app/models/OPNsense/Turnserver/Turnserver.php b/net/turnserver/src/opnsense/mvc/app/models/OPNsense/Turnserver/Turnserver.php new file mode 100644 index 0000000000..3d004cb77d --- /dev/null +++ b/net/turnserver/src/opnsense/mvc/app/models/OPNsense/Turnserver/Turnserver.php @@ -0,0 +1,53 @@ +settings->enabled === "1") { + return true; + } + return false; + } +} diff --git a/net/turnserver/src/opnsense/mvc/app/models/OPNsense/Turnserver/Turnserver.xml b/net/turnserver/src/opnsense/mvc/app/models/OPNsense/Turnserver/Turnserver.xml new file mode 100644 index 0000000000..1acae266f7 --- /dev/null +++ b/net/turnserver/src/opnsense/mvc/app/models/OPNsense/Turnserver/Turnserver.xml @@ -0,0 +1,97 @@ + + //OPNsense/turnserver + 1.0.0 + The coturn STUN/TURN Server + + + + 0 + Y + + + 127.0.0.1 + , + Y + Y + + + 3478 + Y + + + 49152 + Y + + + 65535 + Y + + + 0 + Y + + + N + N + Please select a valid certificate from the list. + + + 5349 + Y + + + 1 + Y + + + N + /^.{16,128}$/u + Should be a string between 16 and 128 characters. + + + N + /^.{1,128}$/u + Should be a string between 1 and 128 characters. + + + 1 + Y + + + 0 + 0 + 1000000000 + Please specify a value between 0 and 1000000000. + Y + + + 0 + 0 + 1000000000 + Please specify a value between 0 and 1000000000. + Y + + + 600 + 1 + 1000000000 + Please specify a value between 1 and 1000000000. + Y + + + 600 + 1 + 1000000000 + Please specify a value between 1 and 1000000000. + Y + + + 300 + 1 + 1000000000 + Please specify a value between 1 and 1000000000. + Y + + + + diff --git a/net/turnserver/src/opnsense/mvc/app/views/OPNsense/Turnserver/index.volt b/net/turnserver/src/opnsense/mvc/app/views/OPNsense/Turnserver/index.volt new file mode 100644 index 0000000000..950b9d7685 --- /dev/null +++ b/net/turnserver/src/opnsense/mvc/app/views/OPNsense/Turnserver/index.volt @@ -0,0 +1,57 @@ +{# + +Copyright (C) 2025 Frank Wall +OPNsense® is Copyright © 2014 – 2015 by Deciso B.V. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, +this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, +this list of conditions and the following disclaimer in the documentation +and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES, +INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, +OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. + +#} + + + + + +
+ {{ partial("layout_partials/base_form",['fields':settingsForm,'id':'frm_Settings'])}} +
+ +
+ +
diff --git a/net/turnserver/src/opnsense/scripts/OPNsense/Turnserver/export_certs.php b/net/turnserver/src/opnsense/scripts/OPNsense/Turnserver/export_certs.php new file mode 100755 index 0000000000..247d301fee --- /dev/null +++ b/net/turnserver/src/opnsense/scripts/OPNsense/Turnserver/export_certs.php @@ -0,0 +1,61 @@ +#!/usr/local/bin/php +object(); +if (isset($configObj->OPNsense->turnserver->settings->TlsCertificate) and !empty((string)$configObj->OPNsense->turnserver->settings->TlsCertificate)) { + $cert_refid = (string)$configObj->OPNsense->turnserver->settings->TlsCertificate; + foreach ((new Cert())->cert->iterateItems() as $cert) { + $refid = (string)$cert->refid; + + if ($cert_refid == $refid) { + $cert_content = str_replace("\n\n", "\n", str_replace("\r", "", base64_decode((string)$cert->crt))); + $pkey_content = str_replace("\n\n", "\n", str_replace("\r", "", base64_decode((string)$cert->prv))); + + if (!empty((string)$cert->caref)) { + $ca = CertStore::getCaChain((string)$cert->caref); + if ($ca) { + $cert_content .= "\n" . $ca; + } + } + + file_put_contents($cert_filename, $cert_content); + file_put_contents($pkey_filename, $pkey_content); + chmod($pkey_filename, 0600); + } + } +} diff --git a/net/turnserver/src/opnsense/scripts/OPNsense/Turnserver/setup.sh b/net/turnserver/src/opnsense/scripts/OPNsense/Turnserver/setup.sh new file mode 100755 index 0000000000..137843af5f --- /dev/null +++ b/net/turnserver/src/opnsense/scripts/OPNsense/Turnserver/setup.sh @@ -0,0 +1,3 @@ +#!/bin/sh +/usr/local/opnsense/scripts/OPNsense/Turnserver/export_certs.php > /dev/null 2>&1 +exit 0 diff --git a/net/turnserver/src/opnsense/service/conf/actions.d/actions_turnserver.conf b/net/turnserver/src/opnsense/service/conf/actions.d/actions_turnserver.conf new file mode 100644 index 0000000000..372e02aa3b --- /dev/null +++ b/net/turnserver/src/opnsense/service/conf/actions.d/actions_turnserver.conf @@ -0,0 +1,26 @@ +[start] +command:/usr/local/opnsense/scripts/OPNsense/Turnserver/setup.sh; /usr/local/etc/rc.d/turnserver start +parameters: +type:script +description:Start Turnserver +message:starting turnserver + +[stop] +command:/usr/local/etc/rc.d/turnserver onestop +parameters: +type:script +description:Stop Turnserver +message:stopping turnserver + +[restart] +command:/usr/local/opnsense/scripts/OPNsense/Turnserver/setup.sh; /usr/local/etc/rc.d/turnserver restart +parameters: +type:script +description:Restart Turnserver +message:restarting turnserver + +[status] +command:/usr/local/etc/rc.d/turnserver status || exit 0 +parameters: +type:script_output +message:requesting turnserver status diff --git a/net/turnserver/src/opnsense/service/templates/OPNsense/Turnserver/+TARGETS b/net/turnserver/src/opnsense/service/templates/OPNsense/Turnserver/+TARGETS new file mode 100644 index 0000000000..52ca689507 --- /dev/null +++ b/net/turnserver/src/opnsense/service/templates/OPNsense/Turnserver/+TARGETS @@ -0,0 +1,2 @@ +turnserver.conf:/usr/local/etc/turnserver.conf +rc.conf.d:/etc/rc.conf.d/turnserver diff --git a/net/turnserver/src/opnsense/service/templates/OPNsense/Turnserver/rc.conf.d b/net/turnserver/src/opnsense/service/templates/OPNsense/Turnserver/rc.conf.d new file mode 100644 index 0000000000..f292a04861 --- /dev/null +++ b/net/turnserver/src/opnsense/service/templates/OPNsense/Turnserver/rc.conf.d @@ -0,0 +1,5 @@ +{% if helpers.exists('OPNsense.turnserver.settings.Enabled') and OPNsense.turnserver.settings.Enabled|default("0") == "1" %} +turnserver_enable=YES +{% else %} +turnserver_enable=NO +{% endif %} diff --git a/net/turnserver/src/opnsense/service/templates/OPNsense/Turnserver/turnserver.conf b/net/turnserver/src/opnsense/service/templates/OPNsense/Turnserver/turnserver.conf new file mode 100644 index 0000000000..67c96cbabb --- /dev/null +++ b/net/turnserver/src/opnsense/service/templates/OPNsense/Turnserver/turnserver.conf @@ -0,0 +1,60 @@ +# General +{% if helpers.exists('OPNsense.turnserver.settings.ListenIP') and OPNsense.turnserver.settings.ListenIP|default("") != "" %} +{% for listenip in OPNsense.turnserver.settings.ListenIP.split(",") %} +listening-ip={{ listenip }} +{% endfor %} +{% endif %} +listening-port={{ OPNsense.turnserver.settings.ListenPort }} +min-port={{ OPNsense.turnserver.settings.MinPort }} +max-port={{ OPNsense.turnserver.settings.MaxPort }} + +# TLS +{% if helpers.exists('OPNsense.turnserver.settings.TlsEnabled') and OPNsense.turnserver.settings.TlsEnabled|default("") == "1" %} +{% if OPNsense.turnserver.settings.TlsCertificate|default("") != "" %} +tls-listening-port={{ OPNsense.turnserver.settings.TlsPort }} +cert=/usr/local/etc/turnserver_cert.pem +pkey=/usr/local/etc/turnserver_pkey.pem +{% else %} +# ERROR: Required TLS certificate was not specified. TLS support will be disabled. +no-tls +no-dtls +{% endif %} +{% else %} +no-tls +no-dtls +{% endif %} + +# Security +{% if helpers.exists('OPNsense.turnserver.settings.UseAuthSecret') and OPNsense.turnserver.settings.UseAuthSecret|default("") == "1" %} +{% if OPNsense.turnserver.settings.StaticAuthSecret|default("") != "" %} +use-auth-secret +static-auth-secret={{ OPNsense.turnserver.settings.StaticAuthSecret }} +{% else %} +# ERROR: Required Auth Secret was not specified; this feature will be disabled. +{% endif %} +{% endif %} + +# Features +{% if OPNsense.turnserver.settings.Realm|default("") != "" %} +realm={{ OPNsense.turnserver.settings.Realm }} +{% endif %} +{% if OPNsense.turnserver.settings.FingerprintsEnabled|default("") == "1" %} +fingerprint +{% endif %} + +# Tuning +user-quota={{ OPNsense.turnserver.settings.UserQuota }} +total-quota={{ OPNsense.turnserver.settings.TotalQuota }} +stale-nonce={{ OPNsense.turnserver.settings.StaleNonce }} +channel-lifetime={{ OPNsense.turnserver.settings.ChannelLifetime }} +permission-lifetime={{ OPNsense.turnserver.settings.PermissionLifetime }} + +# Defaults +no-cli +no-software-attribute +no-multicast-peers +no-tlsv1 +no-tlsv1_1 +no-rfc5780 +no-stun-backward-compatibility +response-origin-only-with-rfc5780