git: d5d30594edb0 - main - www/bunkerweb: Fix Let's Encrypt, multisite and the profile page
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 12 Oct 2026 14:36:07 UTC
The branch main has been updated by joneum:
URL: https://cgit.FreeBSD.org/ports/commit/?id=d5d30594edb00cdeb63008a853eff747ddc601b6
commit d5d30594edb00cdeb63008a853eff747ddc601b6
Author: Jochen Neumeister <joneum@FreeBSD.org>
AuthorDate: 2026-10-12 14:35:22 +0000
Commit: Jochen Neumeister <joneum@FreeBSD.org>
CommitDate: 2026-10-12 14:35:22 +0000
www/bunkerweb: Fix Let's Encrypt, multisite and the profile page
- Let's Encrypt: BunkerWeb runs certbot from its own Linux layout. Add
security/py-certbot to RUN_DEPENDS, point CERTBOT_BIN, DEPS_PATH and
the plugin path to the installed locations, and install the certbot
hook scripts executable since certbot runs them directly.
- Multisite: the Templator patch forced NGINX_PREFIX to the global
directory for every server. With MULTISITE=yes each server then
included /usr/local/etc/nginx/set-lua.conf, which only exists without
multisite, and nginx -t failed. Only set the prefix when the server
configuration does not provide one.
- Profile page: devel/py-user_agents is still at 1.0.1 and lacks
get_browser(), get_os() and get_device(), so /profile failed with an
AttributeError and two-factor setup was unreachable. Build the same
strings from the attributes 1.0.1 provides.
Sponsored by: Netzkommune GmbH
---
www/bunkerweb/Makefile | 12 ++++++-
.../files/patch-src_common_gen_Templator.py | 5 +--
.../files/patch-src_ui_app_routes_profile.py | 37 ++++++++++++++++++++++
3 files changed, 51 insertions(+), 3 deletions(-)
diff --git a/www/bunkerweb/Makefile b/www/bunkerweb/Makefile
index 9f42aa167a8c..0102d275a9b9 100644
--- a/www/bunkerweb/Makefile
+++ b/www/bunkerweb/Makefile
@@ -1,6 +1,6 @@
PORTNAME= bunkerweb
DISTVERSION= 1.6.15
-PORTREVISION= 2
+PORTREVISION= 3
CATEGORIES= www security
MAINTAINER= joneum@FreeBSD.org
@@ -28,6 +28,7 @@ RUN_DEPENDS= openresty:www/openresty \
${PYTHON_PKGNAMEPREFIX}pymysql>0:databases/py-pymysql@${PY_FLAVOR} \
${LUA_MODLIBDIR}/cjson.so:devel/lua-cjson@${LUA_FLAVOR} \
${PYTHON_PKGNAMEPREFIX}bcrypt>0:security/py-bcrypt@${PY_FLAVOR} \
+ ${PYTHON_PKGNAMEPREFIX}certbot>0:security/py-certbot@${PY_FLAVOR} \
${PYTHON_PKGNAMEPREFIX}biscuit-python>0:security/py-biscuit-python@${PY_FLAVOR} \
${PYTHON_PKGNAMEPREFIX}passlib>0:security/py-passlib@${PY_FLAVOR} \
${PYTHON_PKGNAMEPREFIX}docker>0:sysutils/py-docker@${PY_FLAVOR} \
@@ -70,6 +71,12 @@ post-patch:
${FIND} ${WRKSRC} -name "*.orig" -delete
${REINPLACE_CMD} -e 's|python3 ${DATADIR}/common/utils/|${PYTHON_CMD} ${DATADIR}/common/utils/|' \
${WRKSRC}/src/bw/lua/bunkerweb/api.lua
+ ${REINPLACE_CMD} \
+ -e 's|join(sep, "usr", "share", "bunkerweb", "deps", "python", "bin", "certbot")|"${LOCALBASE}/bin/certbot"|' \
+ -e 's|join(sep, "usr", "share", "bunkerweb", "deps", "python")|"${DATADIR}/deps/python"|' \
+ -e 's|Path(sep, "usr", "share", "bunkerweb", "core", "letsencrypt")|Path("${DATADIR}/common/core/letsencrypt")|' \
+ ${WRKSRC}/src/common/core/letsencrypt/jobs/letsencrypt_utils.py \
+ ${WRKSRC}/src/common/core/letsencrypt/ui/blueprints/letsencrypt.py
do-install:
${MKDIR} ${STAGEDIR}${DATADIR}
@@ -88,6 +95,9 @@ post-install:
${FIND} ${STAGEDIR}${DATADIR} -type f -name '*.sh' -exec ${CHMOD} 0755 {} \;
${CHMOD} 0755 ${STAGEDIR}${DATADIR}/common/gen/main.py
${CHMOD} 0755 ${STAGEDIR}${DATADIR}/common/gen/save_config.py
+ ${CHMOD} 0755 ${STAGEDIR}${DATADIR}/common/core/letsencrypt/jobs/certbot-auth.py \
+ ${STAGEDIR}${DATADIR}/common/core/letsencrypt/jobs/certbot-cleanup.py \
+ ${STAGEDIR}${DATADIR}/common/core/letsencrypt/jobs/certbot-deploy.py
${INSTALL_SCRIPT} ${FILESDIR}/freebsd-migrate.py \
${STAGEDIR}${DATADIR}/common/db/
diff --git a/www/bunkerweb/files/patch-src_common_gen_Templator.py b/www/bunkerweb/files/patch-src_common_gen_Templator.py
index 86484eb742eb..abbf0823ef75 100644
--- a/www/bunkerweb/files/patch-src_common_gen_Templator.py
+++ b/www/bunkerweb/files/patch-src_common_gen_Templator.py
@@ -17,11 +17,12 @@
}
self._server_env_cache: Dict[str, Environment] = {}
-@@ -721,6 +722,7 @@
+@@ -721,6 +722,8 @@
template_vars = self._base_template_vars.copy()
template_vars["all"] = full_config
template_vars.update(config)
-+ template_vars["NGINX_PREFIX"] = f"{self._target}/"
++ if "NGINX_PREFIX" not in config:
++ template_vars["NGINX_PREFIX"] = f"{self._target}/"
for template in templates:
name = basename(template) if any(template.endswith(root_conf) for root_conf in self._global_templates) else None
diff --git a/www/bunkerweb/files/patch-src_ui_app_routes_profile.py b/www/bunkerweb/files/patch-src_ui_app_routes_profile.py
new file mode 100644
index 000000000000..d33ab13d8c23
--- /dev/null
+++ b/www/bunkerweb/files/patch-src_ui_app_routes_profile.py
@@ -0,0 +1,37 @@
+--- src/ui/app/routes/profile.py.orig 2026-09-21 08:05:39 UTC
++++ src/ui/app/routes/profile.py
+@@ -5,6 +5,21 @@
+ from flask_login import current_user, login_required
+ from user_agents import parse
+
++
++# devel/py-user_agents is still at 1.0.1, which lacks the get_browser(),
++# get_os() and get_device() helpers added in 2.1. Build the same strings
++# from the attributes 1.0.1 already provides.
++def _ua_browser(ua):
++ return ("%s %s" % (ua.browser.family, ua.browser.version_string)).strip()
++
++
++def _ua_os(ua):
++ return ("%s %s" % (ua.os.family, ua.os.version_string)).strip()
++
++
++def _ua_device(ua):
++ return "PC" if ua.is_pc else ua.device.family
++
+ from app.models.totp import totp as TOTP
+
+ from app.dependencies import DB
+@@ -51,9 +66,9 @@
+ "current": (
+ db_session.get("id") == session.get("session_id") if isinstance(db_session, dict) and "session_id" in session else "id" not in db_session
+ ),
+- "browser": ua_data.get_browser(),
+- "os": ua_data.get_os(),
+- "device": ua_data.get_device(),
++ "browser": _ua_browser(ua_data),
++ "os": _ua_os(ua_data),
++ "device": _ua_device(ua_data),
+ "ip": (db_session.get("ip") if isinstance(db_session, dict) else session.get("ip", "-")) or "-",
+ "creation_date": _fmt_dt(creation_dt),
+ "last_activity": (