git: 379784574f45 - main - www/bunkerweb: Enable ModSecurity when the module is available
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 24 Sep 2026 15:02:51 UTC
The branch main has been updated by joneum:
URL: https://cgit.FreeBSD.org/ports/commit/?id=379784574f45e219b4e85fa06e658ea8c825dc7a
commit 379784574f45e219b4e85fa06e658ea8c825dc7a
Author: Jochen Neumeister <joneum@FreeBSD.org>
AuthorDate: 2026-09-24 15:01:56 +0000
Commit: Jochen Neumeister <joneum@FreeBSD.org>
CommitDate: 2026-09-24 15:02:41 +0000
www/bunkerweb: Enable ModSecurity when the module is available
Render the ModSecurity directives only if
ngx_http_modsecurity_module.so is installed, like upstream does for
the stream module. Build www/openresty with the MODSECURITY option to
get it.
Point the remaining paths at their FreeBSD locations, error pages,
assets and rule files were read from /usr/share/bunkerweb.
Sponsored by: Netzkommune GmbH
---
www/bunkerweb/Makefile | 2 +-
...patch-src_common_confs_default-server-http.conf | 21 ++++--
.../files/patch-src_common_confs_nginx.conf | 10 ++-
...mon_core_antibot_confs_server-http_antibot.conf | 11 +++
...re_errors_confs_default-server-http_errors.conf | 13 ++--
...ommon_core_errors_confs_server-http_errors.conf | 31 ++++++--
...rc_common_core_grpc_confs_server-http_grpc.conf | 6 +-
...n_core_misc_confs_default-server-http_page.conf | 11 +++
...s_http_modsecurity-rules-global-crs.conf.modsec | 53 ++++++++++++++
...on_core_modsecurity_confs_http_modsecurity.conf | 12 ++--
...r-http_modsecurity-rules-global-crs.conf.modsec | 18 +++++
...confs_server-http_modsecurity-rules.conf.modsec | 84 ++++++++++++++++++++++
..._modsecurity_confs_server-http_modsecurity.conf | 15 ++--
...rc_common_core_mtls_confs_server-http_mtls.conf | 13 ++++
..._common_core_mtls_confs_server-stream_mtls.conf | 13 ++++
...verseproxy_confs_server-http_reverse-proxy.conf | 10 ++-
..._securitytxt_confs_server-http_securitytxt.conf | 11 +++
...ommon_core_ui_confs_default-server-http_ui.conf | 42 +++++++----
.../files/patch-src_common_gen_Templator.py | 21 +++++-
19 files changed, 342 insertions(+), 55 deletions(-)
diff --git a/www/bunkerweb/Makefile b/www/bunkerweb/Makefile
index 34461f646613..d2dead141fc1 100644
--- a/www/bunkerweb/Makefile
+++ b/www/bunkerweb/Makefile
@@ -1,6 +1,6 @@
PORTNAME= bunkerweb
DISTVERSION= 1.6.15
-PORTREVISION= 0
+PORTREVISION= 1
CATEGORIES= www security
MAINTAINER= joneum@FreeBSD.org
diff --git a/www/bunkerweb/files/patch-src_common_confs_default-server-http.conf b/www/bunkerweb/files/patch-src_common_confs_default-server-http.conf
index df549ad34660..9a3a6063a099 100644
--- a/www/bunkerweb/files/patch-src_common_confs_default-server-http.conf
+++ b/www/bunkerweb/files/patch-src_common_confs_default-server-http.conf
@@ -1,6 +1,6 @@
---- src/common/confs/default-server-http.conf.orig 2026-05-25 18:23:18 UTC
+--- src/common/confs/default-server-http.conf.orig 2026-09-21 08:05:39 UTC
+++ src/common/confs/default-server-http.conf
-@@ -45,7 +45,7 @@ server {
+@@ -45,7 +45,7 @@
{% endif %}
ssl_ecdh_curve {{ resolve_ssl_ecdh_curve(SSL_ECDH_CURVE) }};
{% if "TLSv1.2" in SSL_PROTOCOLS +%}
@@ -9,7 +9,7 @@
{% if SSL_CIPHERS_CUSTOM != "" %}
ssl_ciphers {{ SSL_CIPHERS_CUSTOM }};
{% else %}
-@@ -61,7 +61,6 @@ server {
+@@ -61,7 +61,6 @@
ssl_certificate /var/cache/bunkerweb/misc/default-server-cert.pem;
ssl_certificate_key /var/cache/bunkerweb/misc/default-server-cert.key;
{% if HTTP2 == "yes" %}
@@ -17,7 +17,7 @@
{% endif %}
{% set common_options = " ssl default_server" %}
{% if USE_PROXY_PROTOCOL == "yes" %}
-@@ -75,14 +74,10 @@ server {
+@@ -75,14 +74,10 @@
{% endfor %}
{% if "TLSv1.3" in SSL_PROTOCOLS and HTTP3 == "yes" and USE_PROXY_PROTOCOL == "no" %}
@@ -32,7 +32,16 @@
{% endif %}
ssl_client_hello_by_lua_block {
-@@ -233,10 +228,10 @@ server {
+@@ -178,7 +173,7 @@
+ add_header Last-Modified "";
+ server_tokens off;
+ default_type 'text/html';
+- root /usr/share/bunkerweb/loading;
++ root /usr/local/share/bunkerweb/bw/loading;
+ content_by_lua_block {
+ local utils = require "bunkerweb.utils"
+ local rand = utils.rand
+@@ -236,10 +231,10 @@
{% endif %}
# include core and plugins default-server configurations
@@ -41,7 +50,7 @@
# include custom default-server configurations
- include /etc/bunkerweb/configs/default-server-http/*.conf;
-+ include /usr/local/etc/bunkerweb/configs/default-server-http/*.conf;
++ include /usr/local/usr/local/etc/bunkerweb/configs/default-server-http/*.conf;
log_by_lua_block {
diff --git a/www/bunkerweb/files/patch-src_common_confs_nginx.conf b/www/bunkerweb/files/patch-src_common_confs_nginx.conf
index 1e2918d0edb6..f01714be4fc7 100644
--- a/www/bunkerweb/files/patch-src_common_confs_nginx.conf
+++ b/www/bunkerweb/files/patch-src_common_confs_nginx.conf
@@ -1,6 +1,6 @@
---- src/common/confs/nginx.conf.orig 2026-05-25 18:23:18 UTC
+--- src/common/confs/nginx.conf.orig 2026-09-21 08:05:39 UTC
+++ src/common/confs/nginx.conf
-@@ -1,27 +1,15 @@
+@@ -1,27 +1,19 @@
-# /etc/nginx/nginx.conf
+# /usr/local/etc/nginx/nginx.conf
@@ -23,6 +23,10 @@
-load_module /usr/share/bunkerweb/modules/ngx_stream_lua_module.so;
-load_module /usr/share/bunkerweb/modules/ngx_http_lua_upstream_module.so;
++{% if has_modsecurity +%}
++load_module /usr/local/nginx/modules/ngx_http_modsecurity_module.so;
++{% endif %}
++
{% if os.uname().sysname == "FreeBSD" -%}
# run workers as the dedicated BunkerWeb account
-user nginx;
@@ -30,7 +34,7 @@
{% endif %}
# PID file
-@@ -66,22 +54,22 @@ http {
+@@ -66,22 +58,22 @@
http {
# include base http configuration
diff --git a/www/bunkerweb/files/patch-src_common_core_antibot_confs_server-http_antibot.conf b/www/bunkerweb/files/patch-src_common_core_antibot_confs_server-http_antibot.conf
new file mode 100644
index 000000000000..1ecd0b6313c9
--- /dev/null
+++ b/www/bunkerweb/files/patch-src_common_core_antibot_confs_server-http_antibot.conf
@@ -0,0 +1,11 @@
+--- src/common/core/antibot/confs/server-http/antibot.conf.orig 2026-09-21 08:05:39 UTC
++++ src/common/core/antibot/confs/server-http/antibot.conf
+@@ -1,7 +1,7 @@
+ {%+ if USE_ANTIBOT != "no" -%}
+ location {{ ANTIBOT_URI }} {
+ default_type 'text/html';
+- root /usr/share/bunkerweb/core/antibot/files;
++ root /usr/local/share/bunkerweb/common/core/antibot/files;
+ content_by_lua_block {
+ local logger = require "bunkerweb.logger":new("ANTIBOT")
+ local helpers = require "bunkerweb.helpers"
diff --git a/www/bunkerweb/files/patch-src_common_core_errors_confs_default-server-http_errors.conf b/www/bunkerweb/files/patch-src_common_core_errors_confs_default-server-http_errors.conf
index f1c53fab2bb3..b3521bfb2d9b 100644
--- a/www/bunkerweb/files/patch-src_common_core_errors_confs_default-server-http_errors.conf
+++ b/www/bunkerweb/files/patch-src_common_core_errors_confs_default-server-http_errors.conf
@@ -1,10 +1,15 @@
---- src/common/core/errors/confs/default-server-http/errors.conf.orig 2026-05-25 18:23:18 UTC
+--- src/common/core/errors/confs/default-server-http/errors.conf.orig 2026-09-21 08:05:39 UTC
+++ src/common/core/errors/confs/default-server-http/errors.conf
-@@ -8,7 +8,6 @@ location {% if intercepted_error_code == "400" %}= /{%
+@@ -8,9 +8,11 @@
location {% if intercepted_error_code == "400" %}= /{% else %} @{% endif %}bwerror{{ intercepted_error_code }} {
auth_basic off;
internal;
-- modsecurity off;
++ {% if has_modsecurity %}
+ modsecurity off;
++ {% endif %}
default_type 'text/html';
- root /usr/share/bunkerweb/core/errors/files;
+- root /usr/share/bunkerweb/core/errors/files;
++ root /usr/local/share/bunkerweb/common/core/errors/files;
content_by_lua_block {
+ local logger = require "bunkerweb.logger"
+ local cerrors = require "errors.errors"
diff --git a/www/bunkerweb/files/patch-src_common_core_errors_confs_server-http_errors.conf b/www/bunkerweb/files/patch-src_common_core_errors_confs_server-http_errors.conf
index bd77464c4a99..762d4f352134 100644
--- a/www/bunkerweb/files/patch-src_common_core_errors_confs_server-http_errors.conf
+++ b/www/bunkerweb/files/patch-src_common_core_errors_confs_server-http_errors.conf
@@ -1,18 +1,35 @@
---- src/common/core/errors/confs/server-http/errors.conf.orig 2026-05-25 18:23:18 UTC
+--- src/common/core/errors/confs/server-http/errors.conf.orig 2026-09-21 08:05:39 UTC
+++ src/common/core/errors/confs/server-http/errors.conf
-@@ -6,7 +6,6 @@ location = {{ page }} {
- error_page {{ code }} {{ page }};
+@@ -12,7 +12,9 @@
+ error_page {{ code }} @bwcustomerror{{ code }};
+ location @bwcustomerror{{ code }} {
+ root {% if ROOT_FOLDER == "" %}/var/www/html/{% if MULTISITE == "yes" %}{{ SERVER_NAME.split(" ")[0] }}{% endif %}{% else %}{{ ROOT_FOLDER }}{% endif %};
++ {% if has_modsecurity %}
+ modsecurity off;
++ {% endif %}
+ auth_basic off;
+ rewrite ^ {{ page }} break;
+ }
+@@ -21,7 +23,9 @@
+ {% endif %}
location = {{ page }} {
root {% if ROOT_FOLDER == "" %}/var/www/html/{% if MULTISITE == "yes" %}{{ SERVER_NAME.split(" ")[0] }}{% endif %}{% else %}{{ ROOT_FOLDER }}{% endif %};
-- modsecurity off;
++ {% if has_modsecurity %}
+ modsecurity off;
++ {% endif %}
internal;
auth_basic off;
}
-@@ -27,7 +26,6 @@ location {% if intercepted_error_code == "400" %}= /{%
+@@ -42,9 +46,11 @@
location {% if intercepted_error_code == "400" %}= /{% else %} @{% endif %}bwerror{{ intercepted_error_code }} {
auth_basic off;
internal;
-- modsecurity off;
++ {% if has_modsecurity %}
+ modsecurity off;
++ {% endif %}
default_type 'text/html';
- root /usr/share/bunkerweb/core/errors/files;
+- root /usr/share/bunkerweb/core/errors/files;
++ root /usr/local/share/bunkerweb/common/core/errors/files;
content_by_lua_block {
+ local logger = require "bunkerweb.logger"
+ local cerrors = require "errors.errors"
diff --git a/www/bunkerweb/files/patch-src_common_core_grpc_confs_server-http_grpc.conf b/www/bunkerweb/files/patch-src_common_core_grpc_confs_server-http_grpc.conf
index f59f15528cb6..94c8295482aa 100644
--- a/www/bunkerweb/files/patch-src_common_core_grpc_confs_server-http_grpc.conf
+++ b/www/bunkerweb/files/patch-src_common_core_grpc_confs_server-http_grpc.conf
@@ -1,10 +1,12 @@
--- src/common/core/grpc/confs/server-http/grpc.conf.orig 2026-09-21 08:05:39 UTC
+++ src/common/core/grpc/confs/server-http/grpc.conf
-@@ -98,7 +98,6 @@
+@@ -98,7 +98,9 @@
location {% if url_modifier %}{{ url_modifier }} {% endif %}"{{ quoted_url }}" {
{% if USE_MODSECURITY == "yes" %}
# ModSecurity does not reliably support gRPC traffic patterns, it is always disabled on gRPC locations.
-- modsecurity off;
++ {% if has_modsecurity %}
+ modsecurity off;
++ {% endif %}
{% endif %}
{% if max_client_size != "" %}
client_max_body_size {{ max_client_size }};
diff --git a/www/bunkerweb/files/patch-src_common_core_misc_confs_default-server-http_page.conf b/www/bunkerweb/files/patch-src_common_core_misc_confs_default-server-http_page.conf
new file mode 100644
index 000000000000..b86b875690f4
--- /dev/null
+++ b/www/bunkerweb/files/patch-src_common_core_misc_confs_default-server-http_page.conf
@@ -0,0 +1,11 @@
+--- src/common/core/misc/confs/default-server-http/page.conf.orig 2026-09-21 08:05:39 UTC
++++ src/common/core/misc/confs/default-server-http/page.conf
+@@ -9,7 +9,7 @@
+ add_header Last-Modified "";
+ server_tokens off;
+ default_type 'text/html';
+- root /usr/share/bunkerweb/core/misc/files;
++ root /usr/local/share/bunkerweb/common/core/misc/files;
+ content_by_lua_block {
+ local utils = require "bunkerweb.utils"
+ local rand = utils.rand
diff --git a/www/bunkerweb/files/patch-src_common_core_modsecurity_confs_http_modsecurity-rules-global-crs.conf.modsec b/www/bunkerweb/files/patch-src_common_core_modsecurity_confs_http_modsecurity-rules-global-crs.conf.modsec
new file mode 100644
index 000000000000..a00cf3954216
--- /dev/null
+++ b/www/bunkerweb/files/patch-src_common_core_modsecurity_confs_http_modsecurity-rules-global-crs.conf.modsec
@@ -0,0 +1,53 @@
+--- src/common/core/modsecurity/confs/http/modsecurity-rules-global-crs.conf.modsec.orig 2026-09-21 08:05:39 UTC
++++ src/common/core/modsecurity/confs/http/modsecurity-rules-global-crs.conf.modsec
+@@ -102,15 +102,15 @@
+ {% if USE_MODSECURITY_CRS == "yes" -%}
+ # include OWASP CRS configurations
+ {% if effective_crs_version == "3" %}
+-include /usr/share/bunkerweb/core/modsecurity/files/crs-setup-v3.conf
++include /usr/local/share/bunkerweb/common/core/modsecurity/files/crs-setup-v3.conf
+ {% else %}
+-include /usr/share/bunkerweb/core/modsecurity/files/crs-setup-v4.conf
++include /usr/local/share/bunkerweb/common/core/modsecurity/files/crs-setup-v4.conf
+ {% endif %}
+
+ {% if USE_MODSECURITY_CRS_PLUGINS == "yes" and effective_crs_version != "3" -%}
+ # custom CRS plugins configurations before loading plugins
+- {% if is_custom_conf("/etc/bunkerweb/configs/crs-plugins-before") %}
+-include /etc/bunkerweb/configs/crs-plugins-before/*.conf
++ {% if is_custom_conf("/usr/local/etc/bunkerweb/configs/crs-plugins-before") %}
++include /usr/local/etc/bunkerweb/configs/crs-plugins-before/*.conf
+ {% endif %}
+ {% if is_custom_conf("/etc/nginx/crs-plugins-before") %}
+ include /etc/nginx/crs-plugins-before/*.conf
+@@ -118,8 +118,8 @@
+ {% endif %}
+
+ # custom CRS configurations before loading rules (e.g. exclusions)
+- {% if is_custom_conf("/etc/bunkerweb/configs/modsec-crs") %}
+-include /etc/bunkerweb/configs/modsec-crs/*.conf
++ {% if is_custom_conf("/usr/local/etc/bunkerweb/configs/modsec-crs") %}
++include /usr/local/etc/bunkerweb/configs/modsec-crs/*.conf
+ {% endif %}
+ {% if is_custom_conf("/etc/nginx/modsec-crs") %}
+ include /etc/nginx/modsec-crs/*.conf
+@@ -131,15 +131,15 @@
+
+ # include OWASP CRS rules
+ {% if effective_crs_version == "3" %}
+-include /usr/share/bunkerweb/core/modsecurity/files/coreruleset-v3/rules/*.conf
++include /usr/local/share/bunkerweb/common/core/modsecurity/files/coreruleset-v3/rules/*.conf
+ {% else %}
+-include /usr/share/bunkerweb/core/modsecurity/files/coreruleset-v4/rules/*.conf
++include /usr/local/share/bunkerweb/common/core/modsecurity/files/coreruleset-v4/rules/*.conf
+ {% endif %}
+
+ {% if USE_MODSECURITY_CRS_PLUGINS == "yes" and effective_crs_version != "3" %}
+ # custom CRS plugins configurations after loading plugins
+- {%- if is_custom_conf("/etc/bunkerweb/configs/crs-plugins-after") %}
+-include /etc/bunkerweb/configs/crs-plugins-after/*.conf
++ {%- if is_custom_conf("/usr/local/etc/bunkerweb/configs/crs-plugins-after") %}
++include /usr/local/etc/bunkerweb/configs/crs-plugins-after/*.conf
+ {%- endif %}
+ {% if is_custom_conf("/etc/nginx/crs-plugins-after") %}
+ include /etc/nginx/crs-plugins-after/*.conf
diff --git a/www/bunkerweb/files/patch-src_common_core_modsecurity_confs_http_modsecurity.conf b/www/bunkerweb/files/patch-src_common_core_modsecurity_confs_http_modsecurity.conf
index 6fdadea6aee9..934702f13ca9 100644
--- a/www/bunkerweb/files/patch-src_common_core_modsecurity_confs_http_modsecurity.conf
+++ b/www/bunkerweb/files/patch-src_common_core_modsecurity_confs_http_modsecurity.conf
@@ -1,7 +1,9 @@
---- src/common/core/modsecurity/confs/http/modsecurity.conf.orig 2026-05-10 11:05:38 UTC
+--- src/common/core/modsecurity/confs/http/modsecurity.conf.orig 2026-09-21 08:05:39 UTC
+++ src/common/core/modsecurity/confs/http/modsecurity.conf
-@@ -1,4 +1,2 @@
- {%- if USE_MODSECURITY == "yes" and USE_MODSECURITY_GLOBAL_CRS == "yes" -%}
--modsecurity on;
--modsecurity_rules_file {{ NGINX_PREFIX }}http/modsecurity-rules-global-crs.conf.modsec;
+@@ -1,4 +1,6 @@
++{% if has_modsecurity %}
+ {%- if USE_MODSECURITY_GLOBAL_CRS == "yes" and has_service_with(all, {"SERVER_TYPE": "http", "USE_MODSECURITY": "yes"}) -%}
+ modsecurity on;
+ modsecurity_rules_file {{ NGINX_PREFIX }}http/modsecurity-rules-global-crs.conf.modsec;
{%- endif %}
++{% endif %}
diff --git a/www/bunkerweb/files/patch-src_common_core_modsecurity_confs_server-http_modsecurity-rules-global-crs.conf.modsec b/www/bunkerweb/files/patch-src_common_core_modsecurity_confs_server-http_modsecurity-rules-global-crs.conf.modsec
new file mode 100644
index 000000000000..d3724e4f942c
--- /dev/null
+++ b/www/bunkerweb/files/patch-src_common_core_modsecurity_confs_server-http_modsecurity-rules-global-crs.conf.modsec
@@ -0,0 +1,18 @@
+--- src/common/core/modsecurity/confs/server-http/modsecurity-rules-global-crs.conf.modsec.orig 2026-09-21 08:05:39 UTC
++++ src/common/core/modsecurity/confs/server-http/modsecurity-rules-global-crs.conf.modsec
+@@ -80,11 +80,11 @@
+ {% endif %}
+
+ # custom rules after loading the CRS
+- {% if is_custom_conf("/etc/bunkerweb/configs/modsec") %}
+-include /etc/bunkerweb/configs/modsec/*.conf
++ {% if is_custom_conf("/usr/local/etc/bunkerweb/configs/modsec") %}
++include /usr/local/etc/bunkerweb/configs/modsec/*.conf
+ {% endif %}
+- {% if MULTISITE == "yes" and is_custom_conf("/etc/bunkerweb/configs/modsec/" + service_id) %}
+-include /etc/bunkerweb/configs/modsec/{{ service_id }}/*.conf
++ {% if MULTISITE == "yes" and is_custom_conf("/usr/local/etc/bunkerweb/configs/modsec/" + service_id) %}
++include /usr/local/etc/bunkerweb/configs/modsec/{{ service_id }}/*.conf
+ {% endif %}
+ {% if is_custom_conf("/etc/nginx/modsec") %}
+ include /etc/nginx/modsec/*.conf
diff --git a/www/bunkerweb/files/patch-src_common_core_modsecurity_confs_server-http_modsecurity-rules.conf.modsec b/www/bunkerweb/files/patch-src_common_core_modsecurity_confs_server-http_modsecurity-rules.conf.modsec
new file mode 100644
index 000000000000..d52567a504e3
--- /dev/null
+++ b/www/bunkerweb/files/patch-src_common_core_modsecurity_confs_server-http_modsecurity-rules.conf.modsec
@@ -0,0 +1,84 @@
+--- src/common/core/modsecurity/confs/server-http/modsecurity-rules.conf.modsec.orig 2026-09-21 08:05:39 UTC
++++ src/common/core/modsecurity/confs/server-http/modsecurity-rules.conf.modsec
+@@ -137,18 +137,18 @@
+ {% if USE_MODSECURITY_CRS == "yes" -%}
+ # include OWASP CRS configurations
+ {% if effective_crs_version == "3" %}
+-include /usr/share/bunkerweb/core/modsecurity/files/crs-setup-v3.conf
++include /usr/local/share/bunkerweb/common/core/modsecurity/files/crs-setup-v3.conf
+ {% else %}
+-include /usr/share/bunkerweb/core/modsecurity/files/crs-setup-v4.conf
++include /usr/local/share/bunkerweb/common/core/modsecurity/files/crs-setup-v4.conf
+ {% endif %}
+
+ {% if USE_MODSECURITY_CRS_PLUGINS == "yes" and effective_crs_version != "3" -%}
+ # custom CRS plugins configurations before loading plugins
+- {% if is_custom_conf("/etc/bunkerweb/configs/crs-plugins-before") %}
+-include /etc/bunkerweb/configs/crs-plugins-before/*.conf
++ {% if is_custom_conf("/usr/local/etc/bunkerweb/configs/crs-plugins-before") %}
++include /usr/local/etc/bunkerweb/configs/crs-plugins-before/*.conf
+ {% endif %}
+- {% if MULTISITE == "yes" and is_custom_conf("/etc/bunkerweb/configs/crs-plugins-before/" + service_id) %}
+-include /etc/bunkerweb/configs/crs-plugins-before/{{ service_id }}/*.conf
++ {% if MULTISITE == "yes" and is_custom_conf("/usr/local/etc/bunkerweb/configs/crs-plugins-before/" + service_id) %}
++include /usr/local/etc/bunkerweb/configs/crs-plugins-before/{{ service_id }}/*.conf
+ {% endif %}
+ {% if is_custom_conf("/etc/nginx/crs-plugins-before") %}
+ include /etc/nginx/crs-plugins-before/*.conf
+@@ -184,11 +184,11 @@
+ {% endif %}
+
+ # custom CRS configurations before loading rules (e.g. exclusions)
+- {% if is_custom_conf("/etc/bunkerweb/configs/modsec-crs") %}
+-include /etc/bunkerweb/configs/modsec-crs/*.conf
++ {% if is_custom_conf("/usr/local/etc/bunkerweb/configs/modsec-crs") %}
++include /usr/local/etc/bunkerweb/configs/modsec-crs/*.conf
+ {% endif %}
+- {% if MULTISITE == "yes" and is_custom_conf("/etc/bunkerweb/configs/modsec-crs/" + service_id) %}
+-include /etc/bunkerweb/configs/modsec-crs/{{ service_id }}/*.conf
++ {% if MULTISITE == "yes" and is_custom_conf("/usr/local/etc/bunkerweb/configs/modsec-crs/" + service_id) %}
++include /usr/local/etc/bunkerweb/configs/modsec-crs/{{ service_id }}/*.conf
+ {% endif %}
+ {% if is_custom_conf("/etc/nginx/modsec-crs") %}
+ include /etc/nginx/modsec-crs/*.conf
+@@ -213,18 +213,18 @@
+
+ # include OWASP CRS rules
+ {% if effective_crs_version == "3" %}
+-include /usr/share/bunkerweb/core/modsecurity/files/coreruleset-v3/rules/*.conf
++include /usr/local/share/bunkerweb/common/core/modsecurity/files/coreruleset-v3/rules/*.conf
+ {% else %}
+-include /usr/share/bunkerweb/core/modsecurity/files/coreruleset-v4/rules/*.conf
++include /usr/local/share/bunkerweb/common/core/modsecurity/files/coreruleset-v4/rules/*.conf
+ {% endif %}
+
+ {% if USE_MODSECURITY_CRS_PLUGINS == "yes" and effective_crs_version != "3" %}
+ # custom CRS plugins configurations after loading plugins
+- {%- if is_custom_conf("/etc/bunkerweb/configs/crs-plugins-after") %}
+-include /etc/bunkerweb/configs/crs-plugins-after/*.conf
++ {%- if is_custom_conf("/usr/local/etc/bunkerweb/configs/crs-plugins-after") %}
++include /usr/local/etc/bunkerweb/configs/crs-plugins-after/*.conf
+ {%- endif %}
+- {% if MULTISITE == "yes" and is_custom_conf("/etc/bunkerweb/configs/crs-plugins-after/" + service_id) %}
+-include /etc/bunkerweb/configs/crs-plugins-after/{{ service_id }}/*.conf
++ {% if MULTISITE == "yes" and is_custom_conf("/usr/local/etc/bunkerweb/configs/crs-plugins-after/" + service_id) %}
++include /usr/local/etc/bunkerweb/configs/crs-plugins-after/{{ service_id }}/*.conf
+ {% endif %}
+ {% if is_custom_conf("/etc/nginx/crs-plugins-after") %}
+ include /etc/nginx/crs-plugins-after/*.conf
+@@ -256,11 +256,11 @@
+ {% endif +%}
+
+ # custom rules after loading the CRS
+- {% if is_custom_conf("/etc/bunkerweb/configs/modsec") %}
+-include /etc/bunkerweb/configs/modsec/*.conf
++ {% if is_custom_conf("/usr/local/etc/bunkerweb/configs/modsec") %}
++include /usr/local/etc/bunkerweb/configs/modsec/*.conf
+ {% endif %}
+- {% if MULTISITE == "yes" and is_custom_conf("/etc/bunkerweb/configs/modsec/" + service_id) %}
+-include /etc/bunkerweb/configs/modsec/{{ service_id }}/*.conf
++ {% if MULTISITE == "yes" and is_custom_conf("/usr/local/etc/bunkerweb/configs/modsec/" + service_id) %}
++include /usr/local/etc/bunkerweb/configs/modsec/{{ service_id }}/*.conf
+ {% endif %}
+ {% if is_custom_conf("/etc/nginx/modsec") %}
+ include /etc/nginx/modsec/*.conf
diff --git a/www/bunkerweb/files/patch-src_common_core_modsecurity_confs_server-http_modsecurity.conf b/www/bunkerweb/files/patch-src_common_core_modsecurity_confs_server-http_modsecurity.conf
index 8ee9c1dc7885..c490da8ccfc3 100644
--- a/www/bunkerweb/files/patch-src_common_core_modsecurity_confs_server-http_modsecurity.conf
+++ b/www/bunkerweb/files/patch-src_common_core_modsecurity_confs_server-http_modsecurity.conf
@@ -1,13 +1,12 @@
---- src/common/core/modsecurity/confs/server-http/modsecurity.conf.orig 2026-05-10 11:05:38 UTC
+--- src/common/core/modsecurity/confs/server-http/modsecurity.conf.orig 2026-09-21 08:05:39 UTC
+++ src/common/core/modsecurity/confs/server-http/modsecurity.conf
-@@ -1,10 +1,6 @@
+@@ -1,3 +1,4 @@
++{% if has_modsecurity %}
{% if USE_MODSECURITY == "yes" %}
--modsecurity on;
+ modsecurity on;
{% if USE_MODSECURITY_GLOBAL_CRS == "yes" %}
--modsecurity_rules_file {{ NGINX_PREFIX }}server-http/modsecurity-rules-global-crs.conf.modsec;
- {% else %}
--modsecurity_rules_file {{ NGINX_PREFIX }}server-http/modsecurity-rules.conf.modsec;
- {% endif %}
+@@ -8,3 +9,4 @@
{% else %}
--modsecurity off;
+ modsecurity off;
{% endif %}
++{% endif %}
diff --git a/www/bunkerweb/files/patch-src_common_core_mtls_confs_server-http_mtls.conf b/www/bunkerweb/files/patch-src_common_core_mtls_confs_server-http_mtls.conf
new file mode 100644
index 000000000000..d7b12db1ee5e
--- /dev/null
+++ b/www/bunkerweb/files/patch-src_common_core_mtls_confs_server-http_mtls.conf
@@ -0,0 +1,13 @@
+--- src/common/core/mtls/confs/server-http/mtls.conf.orig 2026-09-21 08:05:39 UTC
++++ src/common/core/mtls/confs/server-http/mtls.conf
+@@ -11,8 +11,8 @@
+ {% endif %}
+ {% elif verify_mode != "optional_no_ca" %}
+ # No validated client CA bundle available yet for this server: mTLS points at a placeholder CA nothing can be validated against, so the verification directives stay in place instead of being dropped. Set MTLS_CA_CERTIFICATE or MTLS_CA_CERTIFICATE_DATA; the Scheduler validates the bundle and distributes it to every instance.
+-ssl_client_certificate /usr/share/bunkerweb/core/mtls/misc/placeholder-ca.pem;
+-ssl_trusted_certificate /usr/share/bunkerweb/core/mtls/misc/placeholder-ca.pem;
++ssl_client_certificate /usr/local/share/bunkerweb/common/core/mtls/misc/placeholder-ca.pem;
++ssl_trusted_certificate /usr/local/share/bunkerweb/common/core/mtls/misc/placeholder-ca.pem;
+ {% endif %}
+
+ ssl_verify_client {{ verify_mode }};
diff --git a/www/bunkerweb/files/patch-src_common_core_mtls_confs_server-stream_mtls.conf b/www/bunkerweb/files/patch-src_common_core_mtls_confs_server-stream_mtls.conf
new file mode 100644
index 000000000000..69036f3f884a
--- /dev/null
+++ b/www/bunkerweb/files/patch-src_common_core_mtls_confs_server-stream_mtls.conf
@@ -0,0 +1,13 @@
+--- src/common/core/mtls/confs/server-stream/mtls.conf.orig 2026-09-21 08:05:39 UTC
++++ src/common/core/mtls/confs/server-stream/mtls.conf
+@@ -11,8 +11,8 @@
+ {% endif %}
+ {% elif verify_mode != "optional_no_ca" %}
+ # No validated client CA bundle available yet for this stream server: mTLS points at a placeholder CA nothing can be validated against, so the verification directives stay in place instead of being dropped. Set MTLS_CA_CERTIFICATE or MTLS_CA_CERTIFICATE_DATA; the Scheduler validates the bundle and distributes it to every instance.
+-ssl_client_certificate /usr/share/bunkerweb/core/mtls/misc/placeholder-ca.pem;
+-ssl_trusted_certificate /usr/share/bunkerweb/core/mtls/misc/placeholder-ca.pem;
++ssl_client_certificate /usr/local/share/bunkerweb/common/core/mtls/misc/placeholder-ca.pem;
++ssl_trusted_certificate /usr/local/share/bunkerweb/common/core/mtls/misc/placeholder-ca.pem;
+ {% endif %}
+
+ ssl_verify_client {{ verify_mode }};
diff --git a/www/bunkerweb/files/patch-src_common_core_reverseproxy_confs_server-http_reverse-proxy.conf b/www/bunkerweb/files/patch-src_common_core_reverseproxy_confs_server-http_reverse-proxy.conf
index b610e01a9df6..42a1a6a3e7e4 100644
--- a/www/bunkerweb/files/patch-src_common_core_reverseproxy_confs_server-http_reverse-proxy.conf
+++ b/www/bunkerweb/files/patch-src_common_core_reverseproxy_confs_server-http_reverse-proxy.conf
@@ -1,16 +1,20 @@
--- src/common/core/reverseproxy/confs/server-http/reverse-proxy.conf.orig 2026-09-21 08:05:39 UTC
+++ src/common/core/reverseproxy/confs/server-http/reverse-proxy.conf
-@@ -130,13 +130,11 @@
+@@ -130,13 +130,17 @@
location {% if url_modifier %}{{ url_modifier }} {% endif %}"{{ quoted_url }}" {
etag off;
{% if USE_MODSECURITY == "yes" and modsecurity_location == "no" %}
-- modsecurity off;
++ {% if has_modsecurity %}
+ modsecurity off;
++ {% endif %}
{% endif %}
{% if max_client_size != "" %}
client_max_body_size {{ max_client_size }};
{% if USE_MODSECURITY == "yes" and modsecurity_location != "no" %}
{% set max_client_size_bytes = (max_client_size[:-1]|int * {"k": 1024, "K": 1024, "m": 1048576, "M": 1048576, "g": 1073741824, "G": 1073741824}[max_client_size[-1]]) if max_client_size[-1] in "kKmMgG" else max_client_size|int %}
-- modsecurity_rules 'SecRequestBodyLimit {{ max_client_size_bytes }}';
++ {% if has_modsecurity %}
+ modsecurity_rules 'SecRequestBodyLimit {{ max_client_size_bytes }}';
++ {% endif %}
{% endif %}
{% endif %}
set $backend{{ index }} "{{ host }}";
diff --git a/www/bunkerweb/files/patch-src_common_core_securitytxt_confs_server-http_securitytxt.conf b/www/bunkerweb/files/patch-src_common_core_securitytxt_confs_server-http_securitytxt.conf
new file mode 100644
index 000000000000..bc210d736656
--- /dev/null
+++ b/www/bunkerweb/files/patch-src_common_core_securitytxt_confs_server-http_securitytxt.conf
@@ -0,0 +1,11 @@
+--- src/common/core/securitytxt/confs/server-http/securitytxt.conf.orig 2026-09-21 08:05:39 UTC
++++ src/common/core/securitytxt/confs/server-http/securitytxt.conf
+@@ -1,7 +1,7 @@
+ {%- if USE_SECURITYTXT == "yes" and SECURITYTXT_CONTACT != "" -%}
+ location = {{ SECURITYTXT_URI }} {
+ default_type 'text/plain; charset=utf-8';
+- root /usr/share/bunkerweb/core/securitytxt/files;
++ root /usr/local/share/bunkerweb/common/core/securitytxt/files;
+ content_by_lua_block {
+ local logger = require "bunkerweb.logger":new("SECURITYTXT")
+ local helpers = require "bunkerweb.helpers"
diff --git a/www/bunkerweb/files/patch-src_common_core_ui_confs_default-server-http_ui.conf b/www/bunkerweb/files/patch-src_common_core_ui_confs_default-server-http_ui.conf
index 090c0d580a9a..a9453e58bb98 100644
--- a/www/bunkerweb/files/patch-src_common_core_ui_confs_default-server-http_ui.conf
+++ b/www/bunkerweb/files/patch-src_common_core_ui_confs_default-server-http_ui.conf
@@ -1,58 +1,72 @@
--- src/common/core/ui/confs/default-server-http/ui.conf.orig 2026-09-21 08:05:39 UTC
+++ src/common/core/ui/confs/default-server-http/ui.conf
-@@ -35,7 +35,6 @@
+@@ -35,7 +35,9 @@
# in http/ui.modsec-crs cannot match. Disable modsec on the UI proxy
# locations only — other defenses (limit, badbehavior, crowdsec, allowlists)
# still run via the BunkerWeb Lua pipeline.
-- modsecurity off;
++ {% if has_modsecurity %}
+ modsecurity off;
++ {% endif %}
proxy_pass $backendui;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
-@@ -53,7 +52,6 @@
+@@ -53,7 +55,9 @@
}
location = /login {
-- modsecurity off;
++ {% if has_modsecurity %}
+ modsecurity off;
++ {% endif %}
etag off;
add_header Last-Modified "";
proxy_pass $backendui;
-@@ -73,7 +71,6 @@
+@@ -73,7 +77,9 @@
}
location = /logout {
-- modsecurity off;
++ {% if has_modsecurity %}
+ modsecurity off;
++ {% endif %}
etag off;
add_header Last-Modified "";
proxy_pass $backendui;
-@@ -94,7 +91,6 @@
+@@ -94,7 +100,9 @@
# Serve CSS, Fonts, Images, JavaScript and Libs without modifying the response body
location ~ ^/setup/(css|fonts|img|js|libs|locales)(.*)$ {
-- modsecurity off;
++ {% if has_modsecurity %}
+ modsecurity off;
++ {% endif %}
# Capture the asset type and the remaining path
# Example: /setup/js/app.js -> /js/app.js
proxy_pass $backendui/$1$2;
-@@ -122,7 +118,6 @@
+@@ -122,7 +130,9 @@
}
location /setup {
-- modsecurity off;
++ {% if has_modsecurity %}
+ modsecurity off;
++ {% endif %}
etag off;
add_header Last-Modified "";
proxy_pass $backendui;
-@@ -171,7 +166,6 @@
+@@ -171,7 +181,9 @@
}
location /setup/loading {
-- modsecurity off;
++ {% if has_modsecurity %}
+ modsecurity off;
++ {% endif %}
etag off;
add_header Last-Modified "";
proxy_pass $backendui;
-@@ -220,7 +214,6 @@
+@@ -220,7 +232,9 @@
}
location /setup/check {
-- modsecurity off;
++ {% if has_modsecurity %}
+ modsecurity off;
++ {% endif %}
etag off;
add_header Last-Modified "";
add_header 'Access-Control-Allow-Origin' '*' always;
diff --git a/www/bunkerweb/files/patch-src_common_gen_Templator.py b/www/bunkerweb/files/patch-src_common_gen_Templator.py
index 2020696cdb2d..86484eb742eb 100644
--- a/www/bunkerweb/files/patch-src_common_gen_Templator.py
+++ b/www/bunkerweb/files/patch-src_common_gen_Templator.py
@@ -1,6 +1,23 @@
---- src/common/gen/Templator.py.orig 2026-05-28 20:12:40 UTC
+--- src/common/gen/Templator.py.orig 2026-09-21 08:05:39 UTC
+++ src/common/gen/Templator.py
-@@ -650,6 +650,7 @@ class Templator:
+@@ -9,7 +9,7 @@
+ from glob import glob
+ from math import ceil
+ import multiprocessing as mp
+-from os.path import basename, join, sep
++from os.path import basename, isfile, join, sep
+ from pathlib import Path
+ from random import choice
+ from ssl import PROTOCOL_TLS_SERVER, SSLContext
+@@ -441,6 +441,7 @@
+ "import": import_module,
+ "resolve_ssl_ecdh_curve": resolve_ssl_ecdh_curve,
+ "normalize_memory_size": Templator._normalize_memory_size,
++ "has_modsecurity": isfile("/usr/local/nginx/modules/ngx_http_modsecurity_module.so"),
+ }
+
+ self._server_env_cache: Dict[str, Environment] = {}
+@@ -721,6 +722,7 @@
template_vars = self._base_template_vars.copy()
template_vars["all"] = full_config
template_vars.update(config)