From 76dc5e9b597195511b779e8c660f6512dd6e12fd Mon Sep 17 00:00:00 2001 From: agh1467 <7823088+agh1467@users.noreply.github.com> Date: Tue, 18 Oct 2022 07:59:15 -0400 Subject: [PATCH] net/sslh: Initial plugin version (#2729) This is to address the discussion about a plugin for sslh and resolves #1630. * Includes setting listen addresses, and protocol targets. * Includes some other advanced settings * Service start/stop/restart control --- net/sslh/CHANGELOG.md | 6 + net/sslh/DEVELOPMENT.md | 171 ++++++++++++++++++ net/sslh/Makefile | 8 + net/sslh/README.md | 69 +++++++ net/sslh/pkg-descr | 19 ++ net/sslh/src/etc/inc/plugins.inc.d/sslh.inc | 69 +++++++ .../OPNsense/Sslh/Api/ServiceController.php | 77 ++++++++ .../OPNsense/Sslh/Api/SettingsController.php | 133 ++++++++++++++ .../OPNsense/Sslh/SettingsController.php | 64 +++++++ .../OPNsense/Sslh/forms/settings.xml | 101 +++++++++++ .../mvc/app/models/OPNsense/Sslh/ACL/ACL.xml | 9 + .../app/models/OPNsense/Sslh/Menu/Menu.xml | 6 + .../mvc/app/models/OPNsense/Sslh/Settings.php | 43 +++++ .../mvc/app/models/OPNsense/Sslh/Settings.xml | 66 +++++++ .../mvc/app/views/OPNsense/Sslh/settings.volt | 76 ++++++++ .../service/conf/actions.d/actions_sslh.conf | 31 ++++ .../service/templates/OPNsense/Sslh/+TARGETS | 2 + .../templates/OPNsense/Sslh/sslh.conf.jinja | 121 +++++++++++++ .../templates/OPNsense/Sslh/sslh.jinja | 11 ++ 19 files changed, 1082 insertions(+) create mode 100644 net/sslh/CHANGELOG.md create mode 100644 net/sslh/DEVELOPMENT.md create mode 100644 net/sslh/Makefile create mode 100644 net/sslh/README.md create mode 100644 net/sslh/pkg-descr create mode 100644 net/sslh/src/etc/inc/plugins.inc.d/sslh.inc create mode 100644 net/sslh/src/opnsense/mvc/app/controllers/OPNsense/Sslh/Api/ServiceController.php create mode 100644 net/sslh/src/opnsense/mvc/app/controllers/OPNsense/Sslh/Api/SettingsController.php create mode 100644 net/sslh/src/opnsense/mvc/app/controllers/OPNsense/Sslh/SettingsController.php create mode 100644 net/sslh/src/opnsense/mvc/app/controllers/OPNsense/Sslh/forms/settings.xml create mode 100644 net/sslh/src/opnsense/mvc/app/models/OPNsense/Sslh/ACL/ACL.xml create mode 100644 net/sslh/src/opnsense/mvc/app/models/OPNsense/Sslh/Menu/Menu.xml create mode 100644 net/sslh/src/opnsense/mvc/app/models/OPNsense/Sslh/Settings.php create mode 100644 net/sslh/src/opnsense/mvc/app/models/OPNsense/Sslh/Settings.xml create mode 100644 net/sslh/src/opnsense/mvc/app/views/OPNsense/Sslh/settings.volt create mode 100644 net/sslh/src/opnsense/service/conf/actions.d/actions_sslh.conf create mode 100644 net/sslh/src/opnsense/service/templates/OPNsense/Sslh/+TARGETS create mode 100644 net/sslh/src/opnsense/service/templates/OPNsense/Sslh/sslh.conf.jinja create mode 100644 net/sslh/src/opnsense/service/templates/OPNsense/Sslh/sslh.jinja diff --git a/net/sslh/CHANGELOG.md b/net/sslh/CHANGELOG.md new file mode 100644 index 000000000..617f3ca4f --- /dev/null +++ b/net/sslh/CHANGELOG.md @@ -0,0 +1,6 @@ +# 1.21c_1 + + * Initial Version + * Includes setting listen addresses, and protocol targets. + * Includes some other advanced settings + * Service start/stop/restart control diff --git a/net/sslh/DEVELOPMENT.md b/net/sslh/DEVELOPMENT.md new file mode 100644 index 000000000..e0c34a2d6 --- /dev/null +++ b/net/sslh/DEVELOPMENT.md @@ -0,0 +1,171 @@ +# Development Notes + +The initial version of this plugin is going to cover only the most basic of settings. A first pass will include primarily the settings which are available through the command line, and included in documentation. + +## Configuration + +For configuration, this plugin utilizes the configuration file to set settings. It has more options, and parity for all settings at the command line that are needed to be used in OPNsense. I didn't want to go as far as manipulating the startup script's command execution to inject command line options. + +Most settings are available through the configuration file. A sample is provided through the FreeBSD ports installation: + +/usr/local/etc/sslh.conf.sample: +``` +# This is a basic configuration file that should provide +# sensible values for "standard" setup. + +verbose: 0; +foreground: false; +inetd: false; +numeric: false; +transparent: false; +timeout: 2; +user: "nobody"; +pidfile: "/var/run/sslh.pid"; +chroot: "/var/empty"; + + +# Change hostname with your external address name. +listen: +( + { host: "thelonious"; port: "443"; } +); + +protocols: +( + { name: "ssh"; service: "ssh"; host: "localhost"; port: "22"; fork: true; }, + { name: "openvpn"; host: "localhost"; port: "1194"; }, + { name: "xmpp"; host: "localhost"; port: "5222"; }, + { name: "http"; host: "localhost"; port: "80"; }, + { name: "tls"; host: "localhost"; port: "443"; log_level: 0; }, + { name: "anyprot"; host: "localhost"; port: "443"; } +); +``` + +Here is a table which maps the configurations to command line options, and includes the model data types, default values, and if a hint is defined. + +| Configuration Key | Command line Option | Model Field Type | Field Default | Hint | +| ------------------ | ------------------- | ---------------- | ------------- | ------------- | +| verbose | -v, --verbose | BooleanField | N/A | | +| foreground | -f, --foreground | N/A | N/A | | +| inetd | -i, --inetd | N/A | N/A | | +| numeric | -n, --numeric | BooleanField | N/A | 2 | +| timeout | -t, --timeout | IntegerField | N/A | | +| user | -u, --user | N/A | N/A | | +| pidfile | -P, --pidfile | N/A | N/A | | +| chroot | -C, --chroot | N/A | N/A | | +| on_timeout | --on-timeout | OptionField | ssh | | +| listen | -p, --listen | CSVListField | localhost:443 | | +| protocols | --ssl, --tls
--ssh
--openvpn
--http
--xmpp
--tinc
--anyprot | TextField | N/A | localhost:443
localhost:22
localhost:1194
localhost:80
localhost:5222
localhost:655 | + +Here are some non-configuration options which have representation in the model: + +| Model Node | Model Field Type | Field Default | Hint | +| ------------------ | ---------------- | ------------- | ------------- | +| mode | OptionField | fork | | + +Most settings have defaults set within the application itself, so setting defaults in the model would be redundant. Hints were provided where this occurred, and it happened that the HTML element supports a hint. The only settings with field defaults are the dropdown `OptionFields` which are set to required because selecting nothing for these would require some additional code in the Jinja template to accommodate a blank value. Since they're required, setting a default is best so the user doesn't have to interact with them. Especially since these fields are advanced and would be hidden. + +The configuration file has some functionality which isn't explained in the main documentation pages, but is included in some example configuration files (see `fork`, and `log_level` in sample above), and some in the source code. These settings are excluded for now, and need to be investigated further to see what OPNsense model data types would be best to use and how to visualize these settings in the UI. + +Some advanced settings can be seen in the test configuration file in the source: + +https://github.com/yrutschle/sslh/blob/master/test.cfg + +There are also more settings for each protocol (maybe individually?), and it's also possible to define multiple entries for some (all?) settings: + +``` +protocols: ( + { name: "tls"; + host: "localhost"; + port: "993"; + sni_hostnames: [ "mail.rutschle.net" ]; + }, + { name: "tls"; + host: "localhost"; + port: "xmpp-client"; + sni_hostnames: [ "im.rutschle.net" ]; + }, + { name: "tls"; + host: "localhost"; + port: "4443"; + sni_hostnames: [ "www.rutschle.net" ]; + } +); +``` + +There is also a more advanced "regex" protocol which can be defined multiple times: +``` +protocols: ( + { name: "regex"; + host: "192.168.0.2"; + port: "80"; + regex_patterns: + ["^(GET|POST|PUT|OPTIONS|DELETE|HEADER) [^ ]* HTTP/[0-9.]*[\r\n]*Host: host_A.acme"] }, + { name: "regex"; + host: "192.168.0.3"; + port: "80"; + regex_patterns: + ["^(GET|POST|PUT|OPTIONS|DELETE|HEADER) [^ ]* HTTP/[0-9.]*[\r\n]*Host: host_B.acme"] } +); +``` + +To support multiple entries, an `ArrayField` type will have to be used, and bootgrids utilized to control the entries within each field. For that it may be best to split out each protocol onto a separate tab, rather than have them displayed on the same tab (may look cluttered). + +The style of the entries here is different than those provided in the sample which would require some additional care in the Jinja template if that style is to be used. + +## Command Line Options + +For reference, here are the command line options: + +Command line options: +``` +sslh + [-Fconfig file] + [-t num] + [--transparent] + [-p listening address [-p listening address ...] + [--ssl target address for SSL] + [--tls target address for TLS] + [--ssh target address for SSH] + [--openvpn target address for OpenVPN] + [--http target address for HTTP] + [--xmpp target address for XMPP] + [--tinc target address for TINC] + [--anyprot default target address] (use this for SSLv2 connections) + [--on-timeout protocol name] + [-u username] + [-C chroot] [-P pidfile] [-v] [-i] [-V] [-f] [-n] +``` + +## Logging + +This application may not have a function to output to a log file. Documentation indicates that `sslh` should be started manually, and run with the `foreground` option to get log messages clearly. Otherwise, logs are sent to the `syslog` facility. There is a configuration setting: `syslog_facility: "auth";` which might be used to change this behavior. + +On OPNsense 22.1 the logging goes to the `audit` facility, and looks something like this: +``` +2021-12-29T23:41:07+00:00 OPNsense.localdomain sslh-fork[62839] 62839 - [meta sequenceId="43"] sslh-fork 1.21c started +``` + +It's a bit noisy with the "meta sequence" part, and the PID being displayed twice. Hopefully that will get cleaned up eventually. It should be possible to utilize the built-in log API to display these log entries, and utilize a hard coded filter to display only messages for `sslh`. + +A more crude option is to set the `foreground` option in the configuration file, start `sslh` via configd, and redirect the output to a file located in `/var/log/`. `configd` might not do well with this since commands that it runs are expected to exit. Maybe the `&` operator can be used to background the process, and maybe `configd` could deal with that better. It would definitely need more testing to confidently use as a solution though. + +## Jinja Templates + +The protocols section can probably be reduced to a single for loop which iterates through each variable, and appends the line to the list. The extra settings described above would have to be taken into consideration if some settings only apply to specific protocols. The alternative multi-line style would also have to be considered to make sure everything looks nice in the file. + +## Protocol Order + +The `anyprot` documentation mentions that `sslh` will try protocols in the order specified (at the command line). This probably also means that it applies for the configuration file as well. Being able to change the order, will eventually be necessary for full functionality. As for a standard order, the `man` page command line reference, the order in which the commands are detailed, and the sample configuration files all use different ordering. + +This could possibly be done with a single `ArrayField` containing all protocol entries. With the protocol name being one of the fields in each entry. That would probably be better than the multi-field approach as described earlier. This would put all of the entries in a single bootgrid which could be displayed on a single page. A number field (`AutoNumberField`?) could be added to indicate the appropriate order. Without a UI function to perform this ordering it could get a bit complicated for new users. It's definitely more complicated than just a list of static boxes. Changing the order is not a function of the bootgrid at the moment. + +There is also the need to consider that some options may only be available/function for specific protocols. There may be the possibility to employ constraints/requirements for field usage if a specific field only works with a specific protocol, but it will have to be investigated further. This would tie in also to the Jinja template because the protocols section could use for loop as described above, but would definitely have to display all of the additional options for each protocol. + +## Service Status + +The fact that this service can run as different binaries means that under specific circumstances, sometimes the service status can return a status of "not running" even when the service is running. The UI won't offer to stop the service because it thinks it's not running. If the service is configured to run with the one variant, and then the configuration is changed to use the another variant without a service restart (though some error occurring), then the service status will be looking for the new variant when looking at the status, and it will say "not running," but the previous variant will still be running. If there are no errors with saving the configuration, and the service API restarts the service successfully after saving the configuration, then it should be relatively rare occurrence. + +## Transparent mode + +This function is available using the command line option "-t, --transparent" or through the configuration file using the "transparent" keyword. The documentation describes this as a "Linux only" feature, and the documentation demonstrates using this feature in conjunction with `iptables`. Since FreeBSD doesn't have `iptables` it's probably that this feature won't work. Since there is no provisions for using this feature on FreeBSD, it's been excluded from the this plugin. diff --git a/net/sslh/Makefile b/net/sslh/Makefile new file mode 100644 index 000000000..d1761cbc5 --- /dev/null +++ b/net/sslh/Makefile @@ -0,0 +1,8 @@ +PLUGIN_NAME= sslh +PLUGIN_VERSION= 0.1 +PLUGIN_DEVEL= yes +PLUGIN_COMMENT= sslh configuration front-end +PLUGIN_DEPENDS= sslh +PLUGIN_MAINTAINER= agh1467@protonmail.com + +.include "../../Mk/plugins.mk" diff --git a/net/sslh/README.md b/net/sslh/README.md new file mode 100644 index 000000000..45c65582e --- /dev/null +++ b/net/sslh/README.md @@ -0,0 +1,69 @@ +# sslh plugin for OPNsense + +## Introduction + +This is a plugin for OPNsense firewall which provides a front-end UI for managing `SSLH`. + +This plugin is designed for v`1.21c`, but may function with later versions. + +Here are some resources for `SSLH` + +[SSLH Project Home Page](https://www.rutschle.net/tech/sslh/README.html) + +[SSLH Project Source Repository](https://github.com/yrutschle/sslh) + +[SSLH FAQ](https://www.rutschle.net/tech/sslh/doc/FAQ.html) + +## Features + +This plugin, currently support only basic features like: + +* Setting multiple listen addresses +* Setting protocol targets +* Controlling some advanced settings + +## Operation + +The plugin can be managed from Services -> SSLH in the OPNsense UI. + +To begin, enable SSLH, define at least one listen address, and define a desired target protocol. + +### Settings + +Most settings for `SSLH` are included here in the UI, but some were left out due to the advanced nature, or the need to investigate further to understand the best approach to bring them into the UI. Help for each setting is included in the UI, select the "i" button to the left of each setting to show the help text. + +#### Listen Addresses + +This is a list of ADDRESS:PORT combinations. The list is comma delimited, and supports both IPv4, and IPv6 addresses. + +#### Protocol Targets + +The protocol targets each support one ADDRESS:PORT combination. + +### Advanced Settings + +Several settings are hidden by default, select the "advanced mode" button in the top left to access these settings. + +#### Mode + +This is also called the sslh "variant", and makes the start up script execute a separate binary, `sslh-fork` or `sslh-select` depending on selection. Each behaves differently, and has different performance. + +#### Timeout + +This is a global timeout, and has a default value of 2 seconds. + +#### On Timeout + +This defines the protocol to which connections will be sent after the timeout period. The default is SSH. + +#### Verbose + +This will increase the verbosity of the log messages in `SSLH`. + +#### Numeric + +This will force no DNS lookup, and make the logs contain IP addresses instead of hostnames. + +### License + +[![License](https://img.shields.io/badge/License-BSD%202--Clause-orange.svg)](https://opensource.org/licenses/BSD-2-Clause) diff --git a/net/sslh/pkg-descr b/net/sslh/pkg-descr new file mode 100644 index 000000000..f818aa3d4 --- /dev/null +++ b/net/sslh/pkg-descr @@ -0,0 +1,19 @@ +Manage SSLH, the SSL/SHH multiplexer via the OPNsense web UI. + +SSLH is a service which accepts HTTPS, SSH, OpenVPN, tinc and XMPP connections on the same port. +This makes it possible to connect to any of these servers on port 443 while +still serving HTTPS on that port. + +SSLH Project Home Page: https://www.rutschle.net/tech/sslh +SSLH FAQ: https://www.rutschle.net/tech/sslh/doc/FAQ.html + +Changelog + +================ + +0.1 + + * Initial Version + * Includes setting listen addresses, and protocol targets. + * Includes some other advanced settings + * Service start/stop/restart control diff --git a/net/sslh/src/etc/inc/plugins.inc.d/sslh.inc b/net/sslh/src/etc/inc/plugins.inc.d/sslh.inc new file mode 100644 index 000000000..d916fc9b6 --- /dev/null +++ b/net/sslh/src/etc/inc/plugins.inc.d/sslh.inc @@ -0,0 +1,69 @@ + + 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. +*/ + +/** + * Function to register the plugin's service with OPNsense. + * + * This adds the service to the System: Diagnostics: Services page at + * http:///status_services.php + * + * The suffix "_services" allows this function to be picked up by + * etc/inc/plugins.inc:plugins_services() and be included in the + * $services array to be processed by status_services.php. + * + * @return array the array of attributes for this service +*/ +function sslh_services() +{ + + // Create an array to be processed by www/status_services.php + $service = array(); + + // Load in our settings to get the enabled state of the plugin. + $settings = new \OPNsense\Sslh\Settings(); + + // Only show the plugin if it's enabled. + if (! ((string) $settings->enabled == '1')) { + // return empty array if not enabled + return $services; + } + + $configd_name = 'sslh'; + $service[] = array( + 'name' => 'sslh', // Service column + 'description' => gettext('SSLH'), // Description column + 'configd' => array( // Status column + 'restart' => array($configd_name . ' restart'), + 'start' => array($configd_name . ' start'), + 'stop' => array($configd_name . ' stop'), + ), + 'pidfile' => '/var/run/sslh.pid' + ); + + return $service; +} diff --git a/net/sslh/src/opnsense/mvc/app/controllers/OPNsense/Sslh/Api/ServiceController.php b/net/sslh/src/opnsense/mvc/app/controllers/OPNsense/Sslh/Api/ServiceController.php new file mode 100644 index 000000000..eb4400f85 --- /dev/null +++ b/net/sslh/src/opnsense/mvc/app/controllers/OPNsense/Sslh/Api/ServiceController.php @@ -0,0 +1,77 @@ + that is defined for this + * Class by Phalcon. That is to say the model XML that has the same name as + * this controller's name, "Settings". + * In this case, it is the model XML file: + * + * `model/OPNsense/Sslh/Settings.xml` + * + * The model name is then used as the name of the array returned by setBase() + * and getBase(). In the form XMLs, the prefix used on the field IDs must + * match this name as API actions use the same name in their transactions. + * For example, the key_name in an API JSON response, will be this model + * name. This name is also used as the API endpoint for this Controller. + * + * `/api/sslh/settings` + * + * This locks activies of this Class to this specific model, so it won't + * save to other models, even within the same plugin. + * + * @var string $internalModelName + */ + protected static $internalModelName = 'settings'; + + /** + * Base model class to reference. + * + * This variable defines which class to call for getMode(). It is used in a + * ReflectionClass call to establish the model object. This class is defined + * in the models directory alongside the model XML, and has the same name + * as this Controller. This class extends BaseModel which reads the model + * XML that has the same name as the class. + * + * In this case, these are the model XML file, and class definition file: + * + * `model/OPNsense/Sslh/Settings.xml` + * + * `model/OPNsense/Sslh/Settings.php` + * + * These together will establish several API endpoints on this Controller's + * endpoint including: + * + * `/api/sslh/settings/get` + * + * `/api/sslh/settings/set` + * + * These are both defined in the ApiMutableModelControllerBase Class: + * + * `function getAction()` + * + * `function setAction()` + * + * @var string $internalModelClass + */ + protected static $internalModelClass = 'OPNsense\Sslh\Settings'; + + /** + * An API endpoint to call when no parameters are + * provided for the API. Can be used to test the API is working. + + * API endpoint: + * + * `/api/sslh/settings` + * + * Usage: + * + * `/api/sslh/settings` + * + * Returns an array which gets converted to json in the POST response. + * + * @return array includes status, saying everything is A-OK + */ + public function indexAction() + { + return array('status' => 'ok'); + } +} diff --git a/net/sslh/src/opnsense/mvc/app/controllers/OPNsense/Sslh/SettingsController.php b/net/sslh/src/opnsense/mvc/app/controllers/OPNsense/Sslh/SettingsController.php new file mode 100644 index 000000000..376a76e70 --- /dev/null +++ b/net/sslh/src/opnsense/mvc/app/controllers/OPNsense/Sslh/SettingsController.php @@ -0,0 +1,64 @@ +view->setVars( + [ + 'plugin_name' => 'sslh', + 'api_name' => 'sslh', + 'this_form' => $this->getForm('settings'), + // controllers/OPNsense/Sslh/forms/settings.xml + ] + ); + + // pick the template as the next view to render + $this->view->pick('OPNsense/Sslh/settings'); + // views/OPNsense/Sslh/settings.volt + } +} diff --git a/net/sslh/src/opnsense/mvc/app/controllers/OPNsense/Sslh/forms/settings.xml b/net/sslh/src/opnsense/mvc/app/controllers/OPNsense/Sslh/forms/settings.xml new file mode 100644 index 000000000..c3247f88a --- /dev/null +++ b/net/sslh/src/opnsense/mvc/app/controllers/OPNsense/Sslh/forms/settings.xml @@ -0,0 +1,101 @@ +
+ + settings.enabled + + checkbox + This will enable the SSLH service. + + + settings.listen_addresses + + Hostname (or IP address) and port combination on which to listen, e.g. localhost:443, 10.5.0.1:443 (typically these resolve to-, or specify, a WAN IP address). This can be defined multiple times to bind sslh to several addresses. + + true + select_multiple + + + settings.mode + + Select the mode in which to run sslh: fork - stable but slow performance | select - new but high performance + dropdown + true + + + settings.timeout + + Timeout in seconds before forwarding the connection to the timeout protocol (which should usually be SSH). Default: 2 + 2 + text + true + + + settings.on_timeout + + Name of the protocol to connect to after the timeout period is over. Default is to forward to the first specified protocol. It usually makes sense to specify 'ssh' as the timeout protocol, as the SSH specification does not tell who is supposed to speak first and a large number of SSH clients wait for the server to send its banner. Default: ssh + dropdown + true + + + settings.ssh_target + + Interface and port on which to forward SSH connections, typically localhost:22. + localhost:22 + text + + + settings.tls_target + + Interface and port on which to forward SSL connection, typically localhost:443. Note that you can set sslh to listen on ext_ip:443 and httpd to listen on localhost:443: this allows clients inside your network to just connect directly to httpd. Also, sslh probes for SSLv3 (or TLSv1) handshake and will reject connections from clients requesting SSLv2. This is compliant with RFC6176 which prohibits the usage of SSLv2. If you wish to accept SSLv2, use --anyprot instead. + localhost:443 + text + + + settings.openvpn_target + + Interface and port on which to forward OpenVPN connections, typically localhost:1194. + localhost:1194 + text + + + settings.http_target + + Interface and port on which to forward HTTP connections, typically localhost:80. + localhost:80 + text + + + settings.xmpp_target + + Interface and port on which to forward XMPP connections, typically localhost:5222. + localhost:5222 + text + + + settings.tinc_target + + Interface and port on which to forward Tinc connections, typically localhost:655. + localhost:655 + text + + + settings.anyprot_target + + + Interface and port on which to forward if no other protocol has been found. Because sslh tries protocols in the order specified on the command line, this should be specified last. If no default is specified, sslh will forward unknown protocols to the first protocol specified. + text + + + settings.verbose + + Increase logging verboseness. + true + checkbox + + + settings.numeric + + Do not attempt to resolve hostnames: logs will contain IP addresses. This is mostly useful if the system's DNS is slow and running the sslh-select variant, as DNS requests will hang all connections. Default: false + checkbox + true + +
diff --git a/net/sslh/src/opnsense/mvc/app/models/OPNsense/Sslh/ACL/ACL.xml b/net/sslh/src/opnsense/mvc/app/models/OPNsense/Sslh/ACL/ACL.xml new file mode 100644 index 000000000..1cb7f2f77 --- /dev/null +++ b/net/sslh/src/opnsense/mvc/app/models/OPNsense/Sslh/ACL/ACL.xml @@ -0,0 +1,9 @@ + + + Services: SSLH + + ui/sslh/* + api/sslh/* + + + diff --git a/net/sslh/src/opnsense/mvc/app/models/OPNsense/Sslh/Menu/Menu.xml b/net/sslh/src/opnsense/mvc/app/models/OPNsense/Sslh/Menu/Menu.xml new file mode 100644 index 000000000..5cf29b5d1 --- /dev/null +++ b/net/sslh/src/opnsense/mvc/app/models/OPNsense/Sslh/Menu/Menu.xml @@ -0,0 +1,6 @@ + + + + + + diff --git a/net/sslh/src/opnsense/mvc/app/models/OPNsense/Sslh/Settings.php b/net/sslh/src/opnsense/mvc/app/models/OPNsense/Sslh/Settings.php new file mode 100644 index 000000000..7c24334bc --- /dev/null +++ b/net/sslh/src/opnsense/mvc/app/models/OPNsense/Sslh/Settings.php @@ -0,0 +1,43 @@ + + //OPNsense/sslh + 0.0.1 + + + Y + + + Y + localhost:443 + Please enter at least one hostname/IP:port combination. + + + Y + fork + N + + + + + + + N + + + N + + + N + + + N + + + N + + + N + + + N + + + N + + + Y + ssh + N + + + + + + + + + + + N + + + N + + + diff --git a/net/sslh/src/opnsense/mvc/app/views/OPNsense/Sslh/settings.volt b/net/sslh/src/opnsense/mvc/app/views/OPNsense/Sslh/settings.volt new file mode 100644 index 000000000..6ea142ded --- /dev/null +++ b/net/sslh/src/opnsense/mvc/app/views/OPNsense/Sslh/settings.volt @@ -0,0 +1,76 @@ +{## + # + # OPNsense® is Copyright © 2014 – 2018 by Deciso B.V. + # This file is Copyright © 2022 agh1467@protonmail.com + # 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. +#} + +{## + # This is the template for the settings page. + # + # This is the main page for this plugin. + # + # Variables sent in by the controller: + # plugin_name string name of this plugin, used for API calls + # this_form array the form XML in an array + #} + +
+
+
+ {{ partial("layout_partials/base_form",['fields':this_form,'id':'frm_settings'])}} +
+
+ +
+
+
+
+ + + diff --git a/net/sslh/src/opnsense/service/conf/actions.d/actions_sslh.conf b/net/sslh/src/opnsense/service/conf/actions.d/actions_sslh.conf new file mode 100644 index 000000000..2e401ddb3 --- /dev/null +++ b/net/sslh/src/opnsense/service/conf/actions.d/actions_sslh.conf @@ -0,0 +1,31 @@ +################################################################################ +# Service Actions # +################################################################################ + +[status] +command:/usr/local/etc/rc.d/sslh status || exit 0 +parameters: +type:script_output +message: sslh: requesting status +description: + +[start] +command:/usr/local/etc/rc.d/sslh start +parameters: +type:script +message: sslh: starting +description: sslh: Start service + +[stop] +command:/usr/local/etc/rc.d/sslh stop +parameters: +type:script +message: sslh: stopping +description: sslh: Stop service + +[restart] +command:/usr/local/etc/rc.d/sslh restart +parameters: +type:script +message: sslh: restarting +description: sslh: Restart service diff --git a/net/sslh/src/opnsense/service/templates/OPNsense/Sslh/+TARGETS b/net/sslh/src/opnsense/service/templates/OPNsense/Sslh/+TARGETS new file mode 100644 index 000000000..14554864c --- /dev/null +++ b/net/sslh/src/opnsense/service/templates/OPNsense/Sslh/+TARGETS @@ -0,0 +1,2 @@ +sslh.jinja:/etc/rc.conf.d/sslh +sslh.conf.jinja:/usr/local/etc/sslh.conf diff --git a/net/sslh/src/opnsense/service/templates/OPNsense/Sslh/sslh.conf.jinja b/net/sslh/src/opnsense/service/templates/OPNsense/Sslh/sslh.conf.jinja new file mode 100644 index 000000000..1cbae9b6b --- /dev/null +++ b/net/sslh/src/opnsense/service/templates/OPNsense/Sslh/sslh.conf.jinja @@ -0,0 +1,121 @@ +{## + # + # OPNsense® is Copyright © 2014 – 2018 by Deciso B.V. + # This file is Copyright © 2022 agh1467@protonmail.com + # 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. +#} + +{#- /usr/local/etc/sslh.conf -#} +{% set plugin_name = 'sslh' %} +{# Prevent configd reload from erroring out if node doesn't exist #} +{% if OPNsense[plugin_name] is defined %} +{% set cfg = OPNsense[plugin_name] %} +################################################################################ +# # +# sslh configuration file for v1.21c # +# # +################################################################################ + +{# ------------ Static options, should remain unchanged by the user. -------- #} +{# standard location for pid files #} +pidfile:"/var/run/sslh.pid"; +{# Run as nobody for security reasons. #} +user: "nobody"; + +{# ------------ Dynamic options, user configurable. -------------------------- #} +{% if cfg['verbose'] is defined %} +verbose:{{ '1' if (cfg['verbose'] == '1') else '0' }}; +{% endif -%} + +{% if cfg['numeric'] is defined %} +numeric:{{ 'true' if (cfg['numeric'] == '1') else 'false' }}; +{% endif -%} + +{% if cfg['timeout'] is defined %} +timeout:{{ cfg['timeout'] }}; +{% endif -%} + +{% if cfg['on_timeout'] is defined %} +on_timeout:"{{ cfg['on_timeout'] }}"; +{% endif -%} + +{% if cfg['listen_addresses'] is defined %} +{% set listen_list = [] %} +{# # listen_addresses is comma delimited string, split() to iterate through. #} +{% for for_listen in cfg['listen_addresses'].split(',') %} +{# # Need to further split the listen address by hostname:port #} +{% set listen_hostname, separator, listen_port = for_listen.rpartition(':') %} +{% if listen_hostname != '' and listen_port != '' %} +{% do listen_list.append(' { host: "'~listen_hostname~'"; port: "'~listen_port~'" }') %} +{% endif %} +{% endfor %} +{% if listen_list != [] -%}{# Don't put this setting unless we have listen addreses to put. #} +listen: +( +{{ listen_list|join(",\n") }} +); +{% endif %} +{% endif %} + +{# All of the protocols #} +protocols: +( +{% if cfg['ssh_target'] is defined %} +{% set hostname, separator, port = cfg['ssh_target'].rpartition(':') %} +{% if hostname != '' and port != '' %} + { name: "ssh"; service: "ssh"; host: "{{ hostname }}"; port: "{{ port }}"; }, +{% endif %} +{% endif %} +{% if cfg['openvpn_target'] is defined %} +{% set hostname, separator, port = cfg['openvpn_target'].rpartition(':') %} +{% if hostname != '' and port != '' %} + { name: "openvpn"; host: "{{ hostname }}"; port: "{{ port }}"; }, +{% endif %} +{% endif %} +{% if cfg['xmpp_target'] is defined %} +{% set hostname, separator, port = cfg['xmpp_target'].rpartition(':') %} +{% if hostname != '' and port != '' %} + { name: "xmpp"; host: "{{ hostname }}"; port: "{{ port }}"; }, +{% endif %} +{% endif %} +{% if cfg['http_target'] is defined %} +{% set hostname, separator, port = cfg['http_target'].rpartition(':') %} +{% if hostname != '' and port != '' %} + { name: "http"; host: "{{ hostname }}"; port: "{{ port }}"; }, +{% endif %} +{% endif %} +{% if cfg['tls_target'] is defined %} +{% set hostname, separator, port = cfg['tls_target'].rpartition(':') %} +{% if hostname != '' and port != '' %} + { name: "tls"; host: "{{ hostname }}"; port: "{{ port }}"; }, +{% endif %} +{% endif %} +{% if cfg['anyprot_target'] is defined %} +{% set hostname, separator, port = cfg['anyprot_target'].rpartition(':') %} +{% if hostname != '' and port != '' %} + { name: "anyprot"; host: "{{ hostname }}"; port: "{{ port }}"; }, +{% endif %} +{% endif %} +); +{% endif %} diff --git a/net/sslh/src/opnsense/service/templates/OPNsense/Sslh/sslh.jinja b/net/sslh/src/opnsense/service/templates/OPNsense/Sslh/sslh.jinja new file mode 100644 index 000000000..cc858aab1 --- /dev/null +++ b/net/sslh/src/opnsense/service/templates/OPNsense/Sslh/sslh.jinja @@ -0,0 +1,11 @@ +{# /usr/local/etc/rc.conf.d/sslh #} +{% set plugin_name = 'sslh' %} +{% if OPNsense[plugin_name] is defined %}{# Prevent configd reload from erroring out if node doesn't exist #} +{% set cfg = OPNsense[plugin_name] %} +{% if cfg['enabled'] is defined %} +sslh_enable={{ '"YES"' if (cfg['enabled'] == '1') else '"NO"' }} +{% endif %} +{% if cfg['mode'] is defined %} +sslh_mode={{ '"fork"' if (cfg['mode'] == 'fork') else '"select"' }} +{% endif %} +{% endif %}