Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion www/nginx/Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
PLUGIN_NAME= nginx
PLUGIN_VERSION= 1.36
PLUGIN_REVISION= 5
PLUGIN_REVISION= 6
PLUGIN_COMMENT= Nginx HTTP server and reverse proxy
PLUGIN_DEPENDS= nginx
PLUGIN_MAINTAINER= franz.fabian.94@gmail.com
Expand Down
1 change: 1 addition & 0 deletions www/nginx/pkg-descr
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Plugin Changelog

* Add optional HTTP/3 support with dynamic Alt-Svc (contributed by Jan Chlouba)
* Fix HTTP/3 reuseport duplicates (contributed by Jan Chlouba)
* Make upstream client-address headers configurable (X-Forwarded-For, Forwarded, CF-/True-Client-IP)

1.35

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,29 @@
<advanced>true</advanced>
<type>checkbox</type>
</field>
<field>
<id>upstream.xff_header_mode</id>
<label>XFF: Mode</label>
<style>selectpicker</style>
<type>dropdown</type>
<advanced>true</advanced>
<help>Append (default) keeps the X-Forwarded-For chain via $proxy_add_x_forwarded_for. Replace sends only the validated client address ($remote_addr). Drop suppresses the header.</help>
</field>
<field>
<id>upstream.forwarded_header_mode</id>
<label>Forwarded: Mode</label>
<style>selectpicker</style>
<type>dropdown</type>
<advanced>true</advanced>
<help>Preserve (default) leaves a client-supplied Forwarded header unchanged. Replace sets a sanitized RFC 7239 value from $remote_addr and $scheme. Drop suppresses the header. Backends that prefer Forwarded may otherwise accept a spoofed address.</help>
</field>
<field>
<id>upstream.suppress_client_headers</id>
<label>Suppress CF-/True-Client-IP</label>
<help>Clear CF-Connecting-IP and True-Client-IP before proxying so they cannot bypass the validated client address.</help>
<advanced>true</advanced>
<type>checkbox</type>
</field>
<field>
<id>upstream.tls_enable</id>
<label>Enable TLS (HTTPS)</label>
Expand Down
24 changes: 23 additions & 1 deletion www/nginx/src/opnsense/mvc/app/models/OPNsense/Nginx/Nginx.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<model>
<mount>//OPNsense/Nginx</mount>
<version>1.35.2</version>
<version>1.35.3</version>
<description>nginx web server, reverse proxy and waf</description>
<items>
<general>
Expand Down Expand Up @@ -131,6 +131,28 @@
<Default>0</Default>
<Required>Y</Required>
</x_forwarded_host_verbatim>
<xff_header_mode type="OptionField">
<OptionValues>
<append>Append</append>
<replace>Replace</replace>
<drop>Drop</drop>
</OptionValues>
<Required>Y</Required>
<Default>append</Default>
</xff_header_mode>
<forwarded_header_mode type="OptionField">
<OptionValues>
<preserve>Preserve</preserve>
<replace>Replace</replace>
<drop>Drop</drop>
</OptionValues>
<Required>Y</Required>
<Default>preserve</Default>
</forwarded_header_mode>
<suppress_client_headers type="BooleanField">
<Default>0</Default>
<Required>Y</Required>
</suppress_client_headers>
<proxy_protocol type="BooleanField">
<Default>0</Default>
<Required>Y</Required>
Expand Down
18 changes: 18 additions & 0 deletions www/nginx/src/opnsense/service/templates/OPNsense/Nginx/http.conf
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,24 @@ map $ssl_server_name $upstream_sni_name {
'' $host;
}

{% set need_forwarded_map = [] %}
{% for upstream in helpers.toList('OPNsense.Nginx.upstream') %}
{% if upstream.forwarded_header_mode is defined and upstream.forwarded_header_mode == 'replace' %}
{% do need_forwarded_map.append(1) %}
{% endif %}
{% endfor %}
{% if need_forwarded_map %}
# Maps used in location.conf for RFC 7239 Forwarded header
map $remote_addr $forwarded_for {
~^[0-9.]+$ "for=$remote_addr";
~^[0-9A-Fa-f:.]+$ "for=\"[$remote_addr]\"";
default "for=unknown";
}
map $scheme $proxy_forwarded {
default "$forwarded_for;proto=$scheme";
}
{% endif %}

include http_post/*.conf;

# TODO add when core is ready for allowing nginx to serve the web interface
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,10 +176,25 @@ location {{ location.matchtype }} {{ location.urlpattern }} {
proxy_set_header Early-Data $ssl_early_data;
{% endif %}
proxy_set_header X-Real-IP $remote_addr;
{% if upstream.xff_header_mode is defined and upstream.xff_header_mode == 'replace' %}
proxy_set_header X-Forwarded-For $remote_addr;
{% elif upstream.xff_header_mode is defined and upstream.xff_header_mode == 'drop' %}
proxy_set_header X-Forwarded-For "";
{% else %}
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
{% endif %}
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Port $server_port;
proxy_set_header X-Forwarded-Host {% if upstream.x_forwarded_host_verbatim is defined and upstream.x_forwarded_host_verbatim == '1'%}$http_host{% else %}$host{% endif %};
{% if upstream.forwarded_header_mode is defined and upstream.forwarded_header_mode == 'replace' %}
proxy_set_header Forwarded $proxy_forwarded;
{% elif upstream.forwarded_header_mode is defined and upstream.forwarded_header_mode == 'drop' %}
proxy_set_header Forwarded "";
{% endif %}
{% if upstream.suppress_client_headers is defined and upstream.suppress_client_headers == '1' %}
proxy_set_header CF-Connecting-IP "";
proxy_set_header True-Client-IP "";
{% endif %}
proxy_set_header X-TLS-Client-Intercepted $tls_intercepted;
{% if location.proxy_read_timeout is defined and location.proxy_read_timeout != '' %}
proxy_read_timeout {{ location.proxy_read_timeout }}s;
Expand Down