diff --git a/www/nginx/README.md b/www/nginx/README.md new file mode 100644 index 000000000..e094ccd0f --- /dev/null +++ b/www/nginx/README.md @@ -0,0 +1,60 @@ +# The nginx plugin + +## Frontend Development + +The nginx plugin is special in its implementation because it needs +some advanced functions (frontend and backend) to work. + +Since the scripts are bigger and contain some templating, +it depends on the following libraries: + +* underscore.js or lodash (tooling library) +* backbone.js (client side MVC framework) + +Since this still leads to many classes and methods, +the files are built as ES6 modules, +which are built using webpack. + +To install the frontend code, pleaste navigate into the +www/nginx/src/opnsense/www/js/nginx directory and +run `npm install` to install the build tools. +When all dependencies are installed, you should be able to run +`node_modules/.bin/webpack-cli --config webpack.conf.js` +to build the JavaScript files. +Please note that the files ending with `.html` are converted +to JavaScript functions (handled as lodash templates). + +If you need to debug something, you can switch from `production` +to `development` in the `webpack.conf.js`. + +## Backend + +Most are standard but some endpoints support maps, which are not +supported by OPNsense core. + +You can detect them simply as they are doing more than just a mapping +to the *base methods. + +Such mappings work in the way that they catch up the request, +map the internal data first, and then forward their UUIDs +to the *base method. + +## The nginx plugin as infrastucture + +The include pattern for nginx vhosts is +`opnsense__vhost_plugins/*.conf` which means that all files in the +directory `/usr/local/etc/nginx/opnsense__vhost_plugins`, which end +with `.conf` are automatically included and served. +Type can be http or stream. +Please make sure your plugin creates a valid configuration because +otherwise nginx will not start. + +This is intended for plugins, which do need some data to be served via +HTTP or TCP (for example traffic stats, a local FastCGI service, +converting an unix socket to TCP etc.) but do not want to serve themself. + +## Hooking a HTTP server block + +Just create a directory called `UUID_pre` or `UUID_post` in the nginx +configuration directory and place a file ending with `.conf` in it. +UUID is the UUID of the server object. diff --git a/www/nginx/pkg-descr b/www/nginx/pkg-descr index 5a545c1d6..a806432da 100644 --- a/www/nginx/pkg-descr +++ b/www/nginx/pkg-descr @@ -12,6 +12,9 @@ Plugin Changelog * update lodash to v4.17.11 * Breaking: remove the WAF policy match type "=" as it is not supported (if you have them in use, unlink and delete them before installing this update) +* allow plugins via include hooks +* Breaking: the enabled flag in the general setting now works (en- or disables all vhosts in the plugin itself, but always serves plugins). Default was false so make sure you have it enabled before upgrade. +* Alias support for downstream proxies (trust setting) 1.7 diff --git a/www/nginx/src/etc/nginx/opnsense_http_vhost_plugins/README b/www/nginx/src/etc/nginx/opnsense_http_vhost_plugins/README new file mode 100644 index 000000000..71db74169 --- /dev/null +++ b/www/nginx/src/etc/nginx/opnsense_http_vhost_plugins/README @@ -0,0 +1 @@ +Place server {} in this directory - they are not affected by the enable / disable flag \ No newline at end of file diff --git a/www/nginx/src/etc/nginx/opnsense_stream_vhost_plugins/README b/www/nginx/src/etc/nginx/opnsense_stream_vhost_plugins/README new file mode 100644 index 000000000..71db74169 --- /dev/null +++ b/www/nginx/src/etc/nginx/opnsense_stream_vhost_plugins/README @@ -0,0 +1 @@ +Place server {} in this directory - they are not affected by the enable / disable flag \ No newline at end of file diff --git a/www/nginx/src/opnsense/mvc/app/controllers/OPNsense/Nginx/forms/httpserver.xml b/www/nginx/src/opnsense/mvc/app/controllers/OPNsense/Nginx/forms/httpserver.xml index 9c57cbc97..4cb0b96d5 100644 --- a/www/nginx/src/opnsense/mvc/app/controllers/OPNsense/Nginx/forms/httpserver.xml +++ b/www/nginx/src/opnsense/mvc/app/controllers/OPNsense/Nginx/forms/httpserver.xml @@ -25,6 +25,14 @@ true Enter a list of IP addresses or CIDR networks which are allowed to override the source IP address using the specified header. + + httpserver.trusted_proxies_alias + + + dropdown + true + Choose a Firewall Alias for trusted proxies. + httpserver.real_ip_source diff --git a/www/nginx/src/opnsense/mvc/app/controllers/OPNsense/Nginx/forms/settings.xml b/www/nginx/src/opnsense/mvc/app/controllers/OPNsense/Nginx/forms/settings.xml index 94100b302..1b72b18da 100644 --- a/www/nginx/src/opnsense/mvc/app/controllers/OPNsense/Nginx/forms/settings.xml +++ b/www/nginx/src/opnsense/mvc/app/controllers/OPNsense/Nginx/forms/settings.xml @@ -5,7 +5,7 @@ nginx.general.enabled checkbox - Enable or disable the nginx service. + Enable configured services. diff --git a/www/nginx/src/opnsense/mvc/app/models/OPNsense/Nginx/Nginx.xml b/www/nginx/src/opnsense/mvc/app/models/OPNsense/Nginx/Nginx.xml index 5d661089b..106650659 100644 --- a/www/nginx/src/opnsense/mvc/app/models/OPNsense/Nginx/Nginx.xml +++ b/www/nginx/src/opnsense/mvc/app/models/OPNsense/Nginx/Nginx.xml @@ -550,6 +550,21 @@ /^((?:\d+\.){3,3}\d+|[a-f0-9\:]+)(?:\/\d+)?(,?(?:(?:(\d+\.){3,3}\d+|[a-f0-9\:]+)(?:\/\d+)?))*$/i Y + + + + + Selected alias not found + N + N + X-Real-IP (default) diff --git a/www/nginx/src/opnsense/service/templates/OPNsense/Nginx/http.conf b/www/nginx/src/opnsense/service/templates/OPNsense/Nginx/http.conf index 7d66d1af3..64ffd2293 100644 --- a/www/nginx/src/opnsense/service/templates/OPNsense/Nginx/http.conf +++ b/www/nginx/src/opnsense/service/templates/OPNsense/Nginx/http.conf @@ -57,7 +57,11 @@ if cache_path.use_temp_path is defined and cache_path.use_temp_path == '1' {% include "OPNsense/Nginx/upstream.conf" ignore missing with context %} + +include opnsense_http_vhost_plugins/*.conf; + {% set listen_list = [] %} +{% if OPNsense.Nginx.general.enabled is defined and OPNsense.Nginx.general.enabled == '1' %} {% for server in helpers.toList('OPNsense.Nginx.http_server') %} {% set single_servername = server.servername.split(",")[0] %} server { @@ -97,6 +101,16 @@ server { set_real_ip_from {{ trusted_proxy }}; {% endfor %} {% endif %} +{% if server.trusted_proxies_alias is defined and server.trusted_proxies_alias != '' %} +{% for trusted_proxy_uuid in server.trusted_proxies_alias.split(',') %} +{% set trusted_proxy_alias = helpers.getUUID(trusted_proxy_uuid) %} +{% if trusted_proxy_alias is defined and trusted_proxy_alias.content is defined %} +{% for alias_line in trusted_proxy_alias.content.split("\n") %} + set_real_ip_from {{ alias_line }}; +{% endfor %} +{% endif %} +{% endfor %} +{% endif %} {% endif %} {% if server.charset is defined %} charset {{ server.charset }}; @@ -220,6 +234,7 @@ server { return 302 https://$host$request_uri; } {% endif %} + include {{ server['@uuid'] }}_pre/*.conf; {% if server.rewrites is defined %} {% for rewrite_uuid in server.rewrites.split(',') %} {% set rewrite = helpers.getUUID(rewrite_uuid) %} @@ -236,6 +251,9 @@ server { {% endfor %} {% endif %} + include {{ server['@uuid'] }}_post/*.conf; + } {% endfor %} +{% endif %} diff --git a/www/nginx/src/opnsense/service/templates/OPNsense/Nginx/location.conf b/www/nginx/src/opnsense/service/templates/OPNsense/Nginx/location.conf index 366492fdc..c08818cb8 100644 --- a/www/nginx/src/opnsense/service/templates/OPNsense/Nginx/location.conf +++ b/www/nginx/src/opnsense/service/templates/OPNsense/Nginx/location.conf @@ -18,11 +18,13 @@ location {{ location.matchtype }} {{ location.urlpattern }} { {% if location.custom_policy is defined %} {% for custom_policy_uuid in location.custom_policy.split(',') %} {% set custom_policy = helpers.getUUID(custom_policy_uuid) %} -{% set naxsi_ruletype = 'basic' %} -{% include "OPNsense/Nginx/naxsirule.conf" ignore missing with context %} +{% if custom_policy is defined %} +{% set naxsi_ruletype = 'basic' %} +{% include "OPNsense/Nginx/naxsirule.conf" ignore missing with context %} CheckRule "$policy{{ custom_policy_uuid.replace('-', '') }} {{ custom_policy.operator }} {{ custom_policy.value }}" {{ custom_policy.action }}; -{% endfor %} +{% endif %} +{% endfor %} {% endif %} {% if location.rewrites is defined %} {% for rewrite_uuid in location.rewrites.split(',') %} diff --git a/www/nginx/src/opnsense/service/templates/OPNsense/Nginx/naxsirule.conf b/www/nginx/src/opnsense/service/templates/OPNsense/Nginx/naxsirule.conf index 24fc0af6c..87ede90c3 100644 --- a/www/nginx/src/opnsense/service/templates/OPNsense/Nginx/naxsirule.conf +++ b/www/nginx/src/opnsense/service/templates/OPNsense/Nginx/naxsirule.conf @@ -48,7 +48,6 @@ {{ ruletype }} {{ rule.match_type }}:{{ rule.identifier }}; {% endif %} {%- endmacro %} - {% if naxsi_ruletype == 'basic' %} {# current policy in loop is available as custom_policy, the uuid as custom_policy_uuid #} {% if custom_policy.naxsi_rules is defined %} diff --git a/www/nginx/src/opnsense/service/templates/OPNsense/Nginx/streams.conf b/www/nginx/src/opnsense/service/templates/OPNsense/Nginx/streams.conf index 2b7e340b7..8216eb4f6 100644 --- a/www/nginx/src/opnsense/service/templates/OPNsense/Nginx/streams.conf +++ b/www/nginx/src/opnsense/service/templates/OPNsense/Nginx/streams.conf @@ -23,7 +23,7 @@ } {% endfor %} -# upstream maps + # upstream maps {% for upstream_map in helpers.toList('OPNsense.Nginx.sni_hostname_upstream_map') %} map $ssl_preread_server_name $hostmap{{ upstream_map['@uuid'].replace('-','') }} { {% for map_entry_uuid in upstream_map.data.split(',') %} @@ -34,6 +34,10 @@ } {% endfor %} + + include opnsense_stream_vhost_plugins/*.conf; + +{% if OPNsense.Nginx.general.enabled is defined and OPNsense.Nginx.general.enabled == '1' %} {% for server in helpers.toList('OPNsense.Nginx.stream_server') %} # servers server { @@ -93,3 +97,4 @@ } {% endfor %} +{% endif %}