diff --git a/README.md b/README.md index 6322c89..626cef7 100644 --- a/README.md +++ b/README.md @@ -73,7 +73,7 @@ The Linux-side package builder validates the FreeBSD package payload before publ ## OPNsense UI -The OPNsense page **Services -> RustProxy** exposes enable/disable plus HTTP, HTTPS/TLS and administration listener settings. RustProxy runs as the unprivileged `rustproxy` user. +The OPNsense page **Services -> RustProxy** exposes enable/disable plus separate bind-address and port settings for HTTP, HTTPS/TLS and administration. On OPNsense/FreeBSD RustProxy runs as `root`. ## Validation @@ -87,12 +87,12 @@ See `docs/FIRST_RUN.md` for Debian setup. The OPNsense page **Services -> RustProxy** exposes the runtime listeners used by the rc.d service: -- HTTP listen: `0.0.0.0:8080` -- HTTPS/TLS listen: `0.0.0.0:8181` (toggleable) -- Admin listen: `0.0.0.0:9090` +- HTTP bind address + port: `0.0.0.0` / `8080` +- HTTPS/TLS bind address + port: `0.0.0.0` / `8181` (toggleable) +- Admin bind address + port: `0.0.0.0` / `9090` - Allow remote admin: on by default so the RustProxy panel can be reached from other hosts; OPNsense firewall rules still decide which networks can connect -The service runs as the unprivileged `rustproxy` user and keeps `/var/db/rustproxy` mode `0700`, as required by RustProxy. Package installation restarts `configd` so `configctl rustproxy ...` actions are immediately available even after direct `pkg add`. +On OPNsense/FreeBSD the service runs as `root` and keeps `/var/db/rustproxy` mode `0700`. This avoids startup/access failures seen after privilege dropping with `daemon -u rustproxy`. Package installation restarts `configd` so `configctl rustproxy ...` actions are immediately available even after direct `pkg add`. ## FreeBSD/OPNsense-only RustProxy patches @@ -108,4 +108,8 @@ Set `APPLY_FREEBSD_PATCHES=0` in `/etc/rustproxy-opnsense-builder.env` only when ### Runtime PID directory -The OPNsense rc.d service creates `/var/run/rustproxy` as `rustproxy:rustproxy` (0750) on every start. Both supervisor and child PID files live there so `daemon -u rustproxy` can run without root-owned PID-file errors. +The OPNsense rc.d service creates `/var/run/rustproxy` as `root:wheel` (0750) on every start. Both supervisor and child PID files live there. The runtime is kept as root on OPNsense/FreeBSD because privilege dropping caused real-world startup and data/certificate access failures. + +### Listener compatibility note + +Plugin model 1.3 stores bind addresses and ports separately. This prevents malformed rendered arguments such as `--tls-listen 0.0.0.0:`. Existing 1.2.x combined `proxyListen`, `tlsListen` and `adminListen` values remain accepted by rc.d during upgrades. If a legacy value is malformed, rc.d falls back to the documented default instead of passing an invalid listener to RustProxy. diff --git a/docs/FIRST_RUN.md b/docs/FIRST_RUN.md index cb7ddec..a3debbf 100644 --- a/docs/FIRST_RUN.md +++ b/docs/FIRST_RUN.md @@ -143,17 +143,17 @@ Leave both empty for manual deployment. After installation open **Services -> RustProxy**. Defaults are: -- HTTP listen: `0.0.0.0:8080` +- HTTP bind address / port: `0.0.0.0` / `8080` - HTTPS/TLS enabled: yes -- HTTPS/TLS listen: `0.0.0.0:8181` -- Admin listen: `0.0.0.0:9090` +- HTTPS/TLS bind address / port: `0.0.0.0` / `8181` +- Admin bind address / port: `0.0.0.0` / `9090` - Allow remote admin: yes -The RustProxy administration UI is reachable from other hosts by default on port `9090`, subject to OPNsense firewall rules. Use **Open RustProxy Admin** after Apply to open the panel in a new browser tab. If `Admin listen` is `0.0.0.0:9090`, the button uses the hostname or IP address through which you opened OPNsense. +The RustProxy administration UI is reachable from other hosts by default on port `9090`, subject to OPNsense firewall rules. Use **Open RustProxy Admin** after Apply to open the panel in a new browser tab. If the admin bind address is `0.0.0.0`, the button uses the hostname or IP address through which you opened OPNsense. Direct `pkg add` is supported: the package post-install script restarts OPNsense `configd`, flushes the plugin cache and renders `/usr/local/etc/rustproxy/opnsense.conf` so `configctl rustproxy status/start/stop` is available immediately. -RustProxy requires its data directory to be private. The plugin enforces owner `rustproxy:rustproxy` and mode `0700` on `/var/db/rustproxy` before every start. +RustProxy requires its data directory to be private. On OPNsense/FreeBSD the plugin runs the service as `root` and enforces owner `root:wheel` with mode `0700` on `/var/db/rustproxy` before every start. ## FreeBSD patch set @@ -185,4 +185,4 @@ Applying FreeBSD/OPNsense patch set for RustProxy 0.20.0 to isolated build sourc ## Runtime directory -`/var/run/rustproxy` is created automatically as `rustproxy:rustproxy` with mode 0750 during package installation and before each service start. PID files are `daemon.pid` and `rustproxy.pid` inside that directory. +`/var/run/rustproxy` is created automatically as `root:wheel` with mode 0750 during package installation and before each service start. PID files are `daemon.pid` and `rustproxy.pid` inside that directory. diff --git a/opnsense-plugin/www/rustproxy/+POST_INSTALL.pre b/opnsense-plugin/www/rustproxy/+POST_INSTALL.pre index 1b6509d..a19b863 100755 --- a/opnsense-plugin/www/rustproxy/+POST_INSTALL.pre +++ b/opnsense-plugin/www/rustproxy/+POST_INSTALL.pre @@ -1,5 +1,7 @@ #!/bin/sh +# Keep the historical service account so package downgrades remain possible, +# but current OPNsense runtime executes RustProxy as root (see rc.d script). if ! /usr/sbin/pw groupshow rustproxy >/dev/null 2>&1; then /usr/sbin/pw groupadd rustproxy fi @@ -8,11 +10,11 @@ if ! /usr/sbin/pw usershow rustproxy >/dev/null 2>&1; then /usr/sbin/pw useradd rustproxy -g rustproxy -c "RustProxy daemon" -d /var/db/rustproxy -s /usr/sbin/nologin fi -/usr/bin/install -d -o rustproxy -g rustproxy -m 0700 /var/db/rustproxy -/usr/sbin/chown rustproxy:rustproxy /var/db/rustproxy +/usr/bin/install -d -o root -g wheel -m 0700 /var/db/rustproxy +/usr/sbin/chown -R root:wheel /var/db/rustproxy /bin/chmod 0700 /var/db/rustproxy -/usr/bin/install -d -o rustproxy -g rustproxy -m 0750 /var/log/rustproxy -/usr/bin/install -d -o rustproxy -g rustproxy -m 0750 /var/run/rustproxy +/usr/bin/install -d -o root -g wheel -m 0750 /var/log/rustproxy +/usr/bin/install -d -o root -g wheel -m 0750 /var/run/rustproxy /usr/bin/install -d -o root -g wheel -m 0755 /usr/local/etc/rustproxy # configd discovers actions only on startup/reload. A direct `pkg add` must diff --git a/opnsense-plugin/www/rustproxy/Makefile b/opnsense-plugin/www/rustproxy/Makefile index d45cdfa..546dce8 100644 --- a/opnsense-plugin/www/rustproxy/Makefile +++ b/opnsense-plugin/www/rustproxy/Makefile @@ -1,5 +1,5 @@ PLUGIN_NAME= rustproxy -PLUGIN_VERSION?= 0.20.0 +PLUGIN_VERSION?= 0.23.3 PLUGIN_REVISION?= 0 PLUGIN_COMMENT= RustProxy reverse proxy service PLUGIN_MAINTAINER?= local@localhost diff --git a/opnsense-plugin/www/rustproxy/pkg-descr b/opnsense-plugin/www/rustproxy/pkg-descr index 5b5fc36..f41d8c3 100644 --- a/opnsense-plugin/www/rustproxy/pkg-descr +++ b/opnsense-plugin/www/rustproxy/pkg-descr @@ -1,4 +1,4 @@ RustProxy packaged as an OPNsense service plugin. -The OPNsense UI exposes service enable/disable, HTTP and HTTPS/TLS listener -addresses, the administration listener and the remote-admin opt-in. +The OPNsense UI exposes service enable/disable, separate bind-address and +port fields for HTTP, HTTPS/TLS and administration, plus remote-admin opt-in. diff --git a/opnsense-plugin/www/rustproxy/src/etc/rc.d/rustproxy b/opnsense-plugin/www/rustproxy/src/etc/rc.d/rustproxy index 8f70e06..6907b0c 100755 --- a/opnsense-plugin/www/rustproxy/src/etc/rc.d/rustproxy +++ b/opnsense-plugin/www/rustproxy/src/etc/rc.d/rustproxy @@ -12,20 +12,38 @@ rcvar="${name}_enable" load_rc_config "$name" : ${rustproxy_enable:="NO"} -: ${rustproxy_user:="rustproxy"} -: ${rustproxy_group:="rustproxy"} +# RustProxy on OPNsense/FreeBSD runs as root. In practice the application +# needs access to its complete data/certificate state and service startup was +# unreliable after daemon(8) dropped privileges to the dedicated account. +: ${rustproxy_user:="root"} +: ${rustproxy_group:="wheel"} : ${rustproxy_data_dir:="/var/db/rustproxy"} : ${rustproxy_log_dir:="/var/log/rustproxy"} : ${rustproxy_log_file:="${rustproxy_log_dir}/rustproxy.log"} : ${rustproxy_run_dir:="/var/run/rustproxy"} : ${rustproxy_command:="/usr/local/sbin/rust-proxy"} : ${rustproxy_restart_delay:="5"} -: ${rustproxy_proxy_listen:="0.0.0.0:8080"} -: ${rustproxy_tls_enabled:="1"} -: ${rustproxy_tls_listen:="0.0.0.0:8181"} -: ${rustproxy_admin_listen:="0.0.0.0:9090"} : ${rustproxy_allow_remote_admin:="1"} +# Split listener settings written by the current OPNsense model. +: ${rustproxy_proxy_address:=""} +: ${rustproxy_proxy_port:=""} +: ${rustproxy_tls_enabled:="1"} +: ${rustproxy_tls_address:=""} +: ${rustproxy_tls_port:=""} +: ${rustproxy_admin_address:=""} +: ${rustproxy_admin_port:=""} + +# Combined listener settings used by plugin model 1.2.x and earlier. +: ${rustproxy_proxy_listen_legacy:=""} +: ${rustproxy_tls_listen_legacy:=""} +: ${rustproxy_admin_listen_legacy:=""} + +# Old rc.conf-style variable names are also accepted for hand-written configs. +: ${rustproxy_proxy_listen:=""} +: ${rustproxy_tls_listen:=""} +: ${rustproxy_admin_listen:=""} + enabled="0" config_file="/usr/local/etc/rustproxy/opnsense.conf" if [ -r "$config_file" ]; then @@ -38,9 +56,94 @@ else rustproxy_enable="NO" fi -rustproxy_runtime_args="--data-dir ${rustproxy_data_dir} --admin-listen ${rustproxy_admin_listen} --update-check-interval-secs 0 serve --proxy-listen ${rustproxy_proxy_listen}" +rustproxy_valid_port() +{ + case "$1" in + ''|*[!0-9]*) return 1 ;; + esac + [ "$1" -ge 1 ] 2>/dev/null && [ "$1" -le 65535 ] 2>/dev/null +} + +rustproxy_valid_listener() +{ + _rp_listener="$1" + case "$_rp_listener" in + \[*\]:*) _rp_port="${_rp_listener##*:}" ;; + *:*) _rp_port="${_rp_listener##*:}" ;; + *) return 1 ;; + esac + rustproxy_valid_port "$_rp_port" +} + +rustproxy_format_listener() +{ + _rp_address="$1" + _rp_port="$2" + case "$_rp_address" in + \[*\]) printf '%s:%s\n' "$_rp_address" "$_rp_port" ;; + *:*) printf '[%s]:%s\n' "$_rp_address" "$_rp_port" ;; + *) printf '%s:%s\n' "$_rp_address" "$_rp_port" ;; + esac +} + +rustproxy_resolve_listener() +{ + _rp_address="$1" + _rp_port="$2" + _rp_legacy="$3" + _rp_old_rc="$4" + _rp_default_address="$5" + _rp_default_port="$6" + _rp_name="$7" + + # New split settings are authoritative as soon as either half is set. + if [ -n "$_rp_address" ] || [ -n "$_rp_port" ]; then + [ -n "$_rp_address" ] || _rp_address="$_rp_default_address" + [ -n "$_rp_port" ] || _rp_port="$_rp_default_port" + if ! rustproxy_valid_port "$_rp_port"; then + echo "Invalid RustProxy ${_rp_name} port: ${_rp_port}" >&2 + return 1 + fi + rustproxy_format_listener "$_rp_address" "$_rp_port" + return 0 + fi + + # Preserve a valid listener from plugin 1.2.x during upgrade. + if [ -n "$_rp_legacy" ] && rustproxy_valid_listener "$_rp_legacy"; then + printf '%s\n' "$_rp_legacy" + return 0 + fi + + # Preserve hand-written rc.conf settings as another compatibility path. + if [ -n "$_rp_old_rc" ] && rustproxy_valid_listener "$_rp_old_rc"; then + printf '%s\n' "$_rp_old_rc" + return 0 + fi + + # Malformed legacy values such as "0.0.0.0:" must never reach RustProxy. + # Fall back to a known-good listener and let the user set the separate port + # field in Services -> RustProxy. + rustproxy_format_listener "$_rp_default_address" "$_rp_default_port" +} + +rustproxy_proxy_listen_resolved="$(rustproxy_resolve_listener \ + "$rustproxy_proxy_address" "$rustproxy_proxy_port" \ + "$rustproxy_proxy_listen_legacy" "$rustproxy_proxy_listen" \ + "0.0.0.0" "8080" "HTTP")" || exit 1 + +rustproxy_tls_listen_resolved="$(rustproxy_resolve_listener \ + "$rustproxy_tls_address" "$rustproxy_tls_port" \ + "$rustproxy_tls_listen_legacy" "$rustproxy_tls_listen" \ + "0.0.0.0" "8181" "HTTPS/TLS")" || exit 1 + +rustproxy_admin_listen_resolved="$(rustproxy_resolve_listener \ + "$rustproxy_admin_address" "$rustproxy_admin_port" \ + "$rustproxy_admin_listen_legacy" "$rustproxy_admin_listen" \ + "0.0.0.0" "9090" "admin")" || exit 1 + +rustproxy_runtime_args="--data-dir ${rustproxy_data_dir} --admin-listen ${rustproxy_admin_listen_resolved} --update-check-interval-secs 0 serve --proxy-listen ${rustproxy_proxy_listen_resolved}" if [ "$rustproxy_tls_enabled" = "1" ]; then - rustproxy_runtime_args="${rustproxy_runtime_args} --tls-listen ${rustproxy_tls_listen}" + rustproxy_runtime_args="${rustproxy_runtime_args} --tls-listen ${rustproxy_tls_listen_resolved}" fi if [ "$rustproxy_allow_remote_admin" = "1" ]; then rustproxy_runtime_args="${rustproxy_runtime_args} --allow-remote-admin" @@ -49,16 +152,19 @@ fi pidfile="${rustproxy_run_dir}/daemon.pid" child_pidfile="${rustproxy_run_dir}/rustproxy.pid" command="/usr/sbin/daemon" -command_args="-r -R ${rustproxy_restart_delay} -P ${pidfile} -p ${child_pidfile} -u ${rustproxy_user} -o ${rustproxy_log_file} ${rustproxy_command} ${rustproxy_runtime_args}" + +rustproxy_daemon_user_arg="" +if [ "$rustproxy_user" != "root" ]; then + rustproxy_daemon_user_arg="-u ${rustproxy_user}" +fi +command_args="-r -R ${rustproxy_restart_delay} -P ${pidfile} -p ${child_pidfile} ${rustproxy_daemon_user_arg} -o ${rustproxy_log_file} ${rustproxy_command} ${rustproxy_runtime_args}" required_files="${rustproxy_command}" start_precmd="rustproxy_prestart" stop_postcmd="rustproxy_poststop" rustproxy_prestart() { - # /var/run is ephemeral and recreated on boot. daemon(8) writes the - # child pidfile after dropping privileges to rustproxy, so the runtime - # directory must be writable by the service account. + # /var/run is ephemeral and recreated on boot. /usr/bin/install -d -o "${rustproxy_user}" -g "${rustproxy_group}" -m 0750 "${rustproxy_run_dir}" /usr/sbin/chown "${rustproxy_user}:${rustproxy_group}" "${rustproxy_run_dir}" /bin/chmod 0750 "${rustproxy_run_dir}" @@ -71,6 +177,8 @@ rustproxy_prestart() /usr/bin/touch "${rustproxy_log_file}" /usr/sbin/chown "${rustproxy_user}:${rustproxy_group}" "${rustproxy_log_file}" /bin/chmod 0640 "${rustproxy_log_file}" + + echo "RustProxy listeners: HTTP=${rustproxy_proxy_listen_resolved} TLS=${rustproxy_tls_listen_resolved} ADMIN=${rustproxy_admin_listen_resolved}" } rustproxy_poststop() diff --git a/opnsense-plugin/www/rustproxy/src/opnsense/mvc/app/controllers/OPNsense/RustProxy/forms/general.xml b/opnsense-plugin/www/rustproxy/src/opnsense/mvc/app/controllers/OPNsense/RustProxy/forms/general.xml index 291db73..7d599f6 100644 --- a/opnsense-plugin/www/rustproxy/src/opnsense/mvc/app/controllers/OPNsense/RustProxy/forms/general.xml +++ b/opnsense-plugin/www/rustproxy/src/opnsense/mvc/app/controllers/OPNsense/RustProxy/forms/general.xml @@ -10,16 +10,29 @@ checkbox Start RustProxy and keep it enabled after OPNsense restarts. + - + header true - rustproxy.general.proxyListen - + rustproxy.general.proxyAddress + text - HTTP listener passed as --proxy-listen. Default: 0.0.0.0:8080. + HTTP bind address. Leave empty for 0.0.0.0 or to keep the legacy combined listener after an upgrade. + + + rustproxy.general.proxyPort + + text + HTTP port passed as --proxy-listen. Leave empty for 8080 or to keep the legacy combined listener after an upgrade. + + + + + header + true rustproxy.general.tlsEnabled @@ -28,21 +41,34 @@ When enabled, pass --tls-listen to RustProxy. - rustproxy.general.tlsListen - + rustproxy.general.tlsAddress + text - HTTPS/TLS listener passed as --tls-listen. Default: 0.0.0.0:8181. + HTTPS/TLS bind address. Leave empty for 0.0.0.0 or to keep the legacy combined listener after an upgrade. + + rustproxy.general.tlsPort + + text + HTTPS/TLS port passed as --tls-listen. Leave empty for 8181 or to keep the legacy combined listener after an upgrade. + + header true - rustproxy.general.adminListen - + rustproxy.general.adminAddress + text - RustProxy administration listener passed as --admin-listen. Default: 0.0.0.0:9090 so the panel can be reached from other hosts. OPNsense firewall rules still control who can connect. + Administration bind address. Leave empty for 0.0.0.0 or to keep the legacy combined listener after an upgrade. + + + rustproxy.general.adminPort + + text + Administration port passed as --admin-listen. Leave empty for 9090 or to keep the legacy combined listener after an upgrade. rustproxy.general.allowRemoteAdmin diff --git a/opnsense-plugin/www/rustproxy/src/opnsense/mvc/app/models/OPNsense/RustProxy/RustProxy.xml b/opnsense-plugin/www/rustproxy/src/opnsense/mvc/app/models/OPNsense/RustProxy/RustProxy.xml index bf3053d..1e56de7 100644 --- a/opnsense-plugin/www/rustproxy/src/opnsense/mvc/app/models/OPNsense/RustProxy/RustProxy.xml +++ b/opnsense-plugin/www/rustproxy/src/opnsense/mvc/app/models/OPNsense/RustProxy/RustProxy.xml @@ -1,6 +1,6 @@ //OPNsense/rustproxy - 1.2.0 + 1.3.0 RustProxy service settings @@ -8,29 +8,48 @@ 0 Y - - 0.0.0.0:8080 - Y - Enter a valid HTTP listen address and port, for example 0.0.0.0:8080. - + + + + N + Enter a valid HTTP bind address, for example 0.0.0.0. + + + Enter a valid HTTP port between 1 and 65535. + 1 Y - - 0.0.0.0:8181 - Y - Enter a valid HTTPS/TLS listen address and port, for example 0.0.0.0:8181. - - - 0.0.0.0:9090 - Y - Enter a valid administration listen address and port, for example 0.0.0.0:9090. - + + N + Enter a valid HTTPS/TLS bind address, for example 0.0.0.0. + + + Enter a valid HTTPS/TLS port between 1 and 65535. + + + N + Enter a valid administration bind address, for example 0.0.0.0. + + + Enter a valid administration port between 1 and 65535. + 1 Y + + + + + diff --git a/opnsense-plugin/www/rustproxy/src/opnsense/mvc/app/views/OPNsense/RustProxy/index.volt b/opnsense-plugin/www/rustproxy/src/opnsense/mvc/app/views/OPNsense/RustProxy/index.volt index 2f4b957..bc7ce11 100644 --- a/opnsense-plugin/www/rustproxy/src/opnsense/mvc/app/views/OPNsense/RustProxy/index.volt +++ b/opnsense-plugin/www/rustproxy/src/opnsense/mvc/app/views/OPNsense/RustProxy/index.volt @@ -38,7 +38,18 @@ $(document).ready(function() { const general = data && data.rustproxy && data.rustproxy.general ? data.rustproxy.general : {}; - const listen = parseAdminListen(general.adminListen || '0.0.0.0:9090'); + let listen = null; + const adminAddress = String(general.adminAddress || '').trim(); + const adminPort = String(general.adminPort || '').trim(); + if (adminAddress || adminPort) { + listen = { + host: adminAddress || '0.0.0.0', + port: adminPort || '9090' + }; + } else { + // Upgrade compatibility with plugin model 1.2.x. + listen = parseAdminListen(general.adminListen || '0.0.0.0:9090'); + } const remoteValue = general.allowRemoteAdmin; const allowRemote = remoteValue === true || remoteValue === 1 || ['1', 'true', 'yes', 'on'].indexOf(String(remoteValue || '').toLowerCase()) !== -1; diff --git a/opnsense-plugin/www/rustproxy/src/opnsense/service/templates/OPNsense/RustProxy/rustproxy.conf b/opnsense-plugin/www/rustproxy/src/opnsense/service/templates/OPNsense/RustProxy/rustproxy.conf index 893a477..dc4cffb 100644 --- a/opnsense-plugin/www/rustproxy/src/opnsense/service/templates/OPNsense/RustProxy/rustproxy.conf +++ b/opnsense-plugin/www/rustproxy/src/opnsense/service/templates/OPNsense/RustProxy/rustproxy.conf @@ -1,6 +1,18 @@ enabled="{% if not helpers.empty('OPNsense.rustproxy.general.enabled') %}1{% else %}0{% endif %}" -rustproxy_proxy_listen="{% if not helpers.empty('OPNsense.rustproxy.general.proxyListen') %}{{ OPNsense.rustproxy.general.proxyListen }}{% else %}0.0.0.0:8080{% endif %}" + +# New split listener fields. Empty values are resolved by rc.d using the +# legacy combined field (upgrade path) and finally the built-in defaults. +rustproxy_proxy_address="{% if not helpers.empty('OPNsense.rustproxy.general.proxyAddress') %}{{ OPNsense.rustproxy.general.proxyAddress }}{% endif %}" +rustproxy_proxy_port="{% if not helpers.empty('OPNsense.rustproxy.general.proxyPort') %}{{ OPNsense.rustproxy.general.proxyPort }}{% endif %}" rustproxy_tls_enabled="{% if not helpers.empty('OPNsense.rustproxy.general.tlsEnabled') %}1{% else %}0{% endif %}" -rustproxy_tls_listen="{% if not helpers.empty('OPNsense.rustproxy.general.tlsListen') %}{{ OPNsense.rustproxy.general.tlsListen }}{% else %}0.0.0.0:8181{% endif %}" -rustproxy_admin_listen="{% if not helpers.empty('OPNsense.rustproxy.general.adminListen') %}{{ OPNsense.rustproxy.general.adminListen }}{% else %}0.0.0.0:9090{% endif %}" +rustproxy_tls_address="{% if not helpers.empty('OPNsense.rustproxy.general.tlsAddress') %}{{ OPNsense.rustproxy.general.tlsAddress }}{% endif %}" +rustproxy_tls_port="{% if not helpers.empty('OPNsense.rustproxy.general.tlsPort') %}{{ OPNsense.rustproxy.general.tlsPort }}{% endif %}" +rustproxy_admin_address="{% if not helpers.empty('OPNsense.rustproxy.general.adminAddress') %}{{ OPNsense.rustproxy.general.adminAddress }}{% endif %}" +rustproxy_admin_port="{% if not helpers.empty('OPNsense.rustproxy.general.adminPort') %}{{ OPNsense.rustproxy.general.adminPort }}{% endif %}" rustproxy_allow_remote_admin="{% if not helpers.empty('OPNsense.rustproxy.general.allowRemoteAdmin') %}1{% else %}0{% endif %}" + +# Legacy 1.2.x combined settings. They are only used when the corresponding +# new split address/port fields are both empty. +rustproxy_proxy_listen_legacy="{% if not helpers.empty('OPNsense.rustproxy.general.proxyListen') %}{{ OPNsense.rustproxy.general.proxyListen }}{% endif %}" +rustproxy_tls_listen_legacy="{% if not helpers.empty('OPNsense.rustproxy.general.tlsListen') %}{{ OPNsense.rustproxy.general.tlsListen }}{% endif %}" +rustproxy_admin_listen_legacy="{% if not helpers.empty('OPNsense.rustproxy.general.adminListen') %}{{ OPNsense.rustproxy.general.adminListen }}{% endif %}" diff --git a/scripts/check.sh b/scripts/check.sh index e62f499..2eb4727 100755 --- a/scripts/check.sh +++ b/scripts/check.sh @@ -51,9 +51,33 @@ grep -q 'PACKAGING_WORKDIR=/opt/opn-rustproxy/packaging' "$ROOT/builder.env.exam [[ -f "$ROOT/builder/freebsd/patches/0.20.0/0001-opnsense-build.patch" ]] grep -q 'APPLY_FREEBSD_PATCHES=1' "$ROOT/builder.env.example" grep -q 'builder/freebsd/apply-patches.sh' "$ROOT/builder/debian/build-docker-release.sh" -grep -q 'rustproxy_run_dir:="/var/run/rustproxy"' "$ROOT/opnsense-plugin/www/rustproxy/src/etc/rc.d/rustproxy" -grep -q 'pidfile="${rustproxy_run_dir}/daemon.pid"' "$ROOT/opnsense-plugin/www/rustproxy/src/etc/rc.d/rustproxy" -grep -q 'child_pidfile="${rustproxy_run_dir}/rustproxy.pid"' "$ROOT/opnsense-plugin/www/rustproxy/src/etc/rc.d/rustproxy" -grep -q '/var/run/rustproxy' "$ROOT/opnsense-plugin/www/rustproxy/+POST_INSTALL.pre" + +rc_script="$ROOT/opnsense-plugin/www/rustproxy/src/etc/rc.d/rustproxy" +model="$ROOT/opnsense-plugin/www/rustproxy/src/opnsense/mvc/app/models/OPNsense/RustProxy/RustProxy.xml" +template="$ROOT/opnsense-plugin/www/rustproxy/src/opnsense/service/templates/OPNsense/RustProxy/rustproxy.conf" +post_install="$ROOT/opnsense-plugin/www/rustproxy/+POST_INSTALL.pre" + +grep -q 'rustproxy_run_dir:="/var/run/rustproxy"' "$rc_script" +grep -q 'rustproxy_user:="root"' "$rc_script" +grep -q 'rustproxy_group:="wheel"' "$rc_script" +grep -q 'rustproxy_resolve_listener' "$rc_script" +grep -q 'rustproxy_valid_port' "$rc_script" +grep -q 'pidfile="${rustproxy_run_dir}/daemon.pid"' "$rc_script" +grep -q 'child_pidfile="${rustproxy_run_dir}/rustproxy.pid"' "$rc_script" +grep -q '' "$model" +grep -q '' "$model" +grep -q '' "$model" +grep -q 'rustproxy_tls_port=' "$template" +grep -q 'rustproxy_tls_listen_legacy=' "$template" +grep -q 'root -g wheel' "$post_install" +grep -q '/var/run/rustproxy' "$post_install" + +# The generated command must never contain a literal listener ending in a colon +# from model defaults/templates. rc.d rejects/falls back from malformed legacy +# values before assembling runtime_args. +if grep -R --exclude='*.md' --exclude='check.sh' -nE 'tls_listen.*0\.0\.0\.0:"|--tls-listen 0\.0\.0\.0:' "$ROOT/opnsense-plugin"; then + echo "Malformed empty-port TLS listener found in plugin source" >&2 + exit 1 +fi echo "Repository checks passed."