From 322704c6bcea422e7c585939205c2b3f2470e8e0 Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Wed, 13 May 2026 17:20:23 +1000 Subject: [PATCH 01/25] Update Webmin conf script to also write IPv6 rules --- conf/turnkey.d/webmin-fw | 66 ++++++++++++++++++++++++++-------------- 1 file changed, 43 insertions(+), 23 deletions(-) diff --git a/conf/turnkey.d/webmin-fw b/conf/turnkey.d/webmin-fw index e1619a6b..1faccf41 100755 --- a/conf/turnkey.d/webmin-fw +++ b/conf/turnkey.d/webmin-fw @@ -1,10 +1,23 @@ -#!/bin/sh -e +#!/bin/bash -e -set ${WEBMIN_FW_TCP_INCOMING:=22 80 443 12321} +# TODO: drop use of iptables-legacy and use nftables directly -CONF=/etc/iptables.up.rules +set "${WEBMIN_FW_TCP_INCOMING:=22 80 443 12321}" +# Read into an array of sorted unique values +readarray -t WEBMIN_FW_TCP_INCOMING \ + < <(tr ' ' '\n' <<< "$WEBMIN_FW_TCP_INCOMING" | sort -un) -cat > $CONF < "$conf" <> $CONF -done - -if [ "$WEBMIN_FW_UDP_INCOMING" ]; then - for port in $WEBMIN_FW_UDP_INCOMING; do - echo "-A INPUT -p udp -m udp --dport $port -j ACCEPT" >> $CONF + for port in "${WEBMIN_FW_TCP_INCOMING[@]}"; do + echo "-A INPUT -p tcp -m tcp --dport $port -j ACCEPT" >> "$conf" done -fi -if [ "$WEBMIN_FW_TCP_INCOMING_REJECT" ]; then - for port in $WEBMIN_FW_TCP_INCOMING_REJECT; do - echo "-A INPUT -p tcp -m tcp --dport $port -j REJECT" >> $CONF - done -fi + if [[ "$WEBMIN_FW_UDP_INCOMING" ]]; then + readarray -t WEBMIN_FW_UDP_INCOMING \ + < <(tr ' ' '\n' <<< "$WEBMIN_FW_UDP_INCOMING" | sort -un) + for port in "${WEBMIN_FW_UDP_INCOMING[@]}"; do + echo "-A INPUT -p udp -m udp --dport $port -j ACCEPT" >> "$conf" + done + fi -echo "COMMIT" >> $CONF + if [ "$WEBMIN_FW_TCP_INCOMING_REJECT" ]; then + readarray -t WEBMIN_FW_TCP_INCOMING_REJECT \ + < <(tr ' ' '\n' <<< "$WEBMIN_FW_TCP_INCOMING_REJECT" | sort -un) + for port in "${WEBMIN_FW_TCP_INCOMING_REJECT[@]}"; do + echo "-A INPUT -p tcp -m tcp --dport $port -j REJECT" >> "$conf" + done + fi -sed -i "/^$/d" $CONF + echo "COMMIT" >> "$conf" + sed -i "/^$/d" "$conf" +done -# As of Buster, Debian uses nftables for firewall; but webmin only supports legacy -# iptables - see https://github.com/webmin/webmin/issues/1097 +# Debian has been using nftables for firewall for some time; but historically +# Webmin only supported legacy iptables. Webmin now supports nftables so as per +# TODO at top of this file TKL should migrate to nftables, but for now we'll +# continue to leverage legacy iptables functionality via 'iptables-legacy'. +# +# See https://github.com/webmin/webmin/issues/1097 update-alternatives --set iptables /usr/sbin/iptables-legacy update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy From 2fe4e0148ffd0ad5288ced470dc1b31b25c66724 Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Thu, 14 May 2026 12:34:22 +1000 Subject: [PATCH 02/25] Enable HSTS, redirect HTTP => HTTPS and note disabling TLSv1.2 in future --- conf/turnkey.d/webmin-conf | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/conf/turnkey.d/webmin-conf b/conf/turnkey.d/webmin-conf index 97b63661..7cad92b2 100755 --- a/conf/turnkey.d/webmin-conf +++ b/conf/turnkey.d/webmin-conf @@ -5,10 +5,10 @@ CONF=/etc/webmin/miniserv.conf update_or_add() { key=$1 value=$2 - if grep -q "$key" $CONF; then - sed -i "s|$key=.*|$key=$value|" $CONF + if grep -q "$key" "$CONF"; then + sed -i "s|$key=.*|$key=$value|" "$CONF" else - echo "$key=$value" >> $CONF + echo "$key=$value" >> "$CONF" fi } @@ -23,6 +23,8 @@ update_or_add error_handler_403 403.cgi update_or_add nolog '\/stats\.cgi\?xhr\-stats\=general' update_or_add no_tls1 1 update_or_add no_tls1_1 1 +# TODO: Disable TLSv1.2 in a future release (i.e. append '1': 'no_tls1_2 1') update_or_add no_tls1_2 update_or_add extracas -update_or_add ssl_hsts 0 +update_or_add ssl_hsts 1 +update_or_add ssl_redirect 1 From 492ed75ac2437a3a3730e59cf7a6fbc0f07193e7 Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Fri, 15 May 2026 11:50:24 +1000 Subject: [PATCH 03/25] Update logging and merge into conf/turnkey.d/webmin-conf; rename webmin-conf-logging --- .../{webmin-conf => webmin-conf-logging} | 19 +++++++++++++++++++ conf/turnkey.d/webmin-handy-log | 13 ------------- 2 files changed, 19 insertions(+), 13 deletions(-) rename conf/turnkey.d/{webmin-conf => webmin-conf-logging} (52%) delete mode 100755 conf/turnkey.d/webmin-handy-log diff --git a/conf/turnkey.d/webmin-conf b/conf/turnkey.d/webmin-conf-logging similarity index 52% rename from conf/turnkey.d/webmin-conf rename to conf/turnkey.d/webmin-conf-logging index 7cad92b2..85278831 100755 --- a/conf/turnkey.d/webmin-conf +++ b/conf/turnkey.d/webmin-conf-logging @@ -1,6 +1,7 @@ #!/bin/sh -e CONF=/etc/webmin/miniserv.conf +LOG_DIR=/var/log/webmin update_or_add() { key=$1 @@ -28,3 +29,21 @@ update_or_add no_tls1_2 update_or_add extracas update_or_add ssl_hsts 1 update_or_add ssl_redirect 1 +# update logfile location +update_or_add logfile "$LOG_DIR/miniserv.log" +update_or_add errorlog "$LOG_DIR/miniserv.error" + +# Note: Updating Webmin config for it's own log file as below does not actually +# work (continues to log to /var/webmin/webmin.log) but we'll work around that +# via symlinks and update the config file to point to the actual log file +# anyway. +CONF=/etc/webmin/config +update_or_add logfile "$LOG_DIR/webmin.log" + +# Prime log files and set permissions +mkdir -p "$LOG_DIR" +touch "$LOG_DIR{miniserv.log,miniserv.error,webmin.log}" +chmod 750 "$LOG_DIR" +chmod 640 "$LOG_DIR"*.log +rm -f /var/webmin/webmin.log +ln -sf /var/log/webmin/webmin.log /var/webmin/webmin.log diff --git a/conf/turnkey.d/webmin-handy-log b/conf/turnkey.d/webmin-handy-log deleted file mode 100755 index 20354494..00000000 --- a/conf/turnkey.d/webmin-handy-log +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/bash -e - -# set up convenience links to Webmin log files - -WEBMIN_VAR=/var/webmin -WEBMIN_LOG=/var/log/webmin - -mkdir -p $WEBMIN_LOG - -files=(miniserv.error webmin.log) -for f in "${files[@]}"; do - ln -s "$WEBMIN_VAR/$f" "$WEBMIN_LOG/$f" -done From 4d2690cc967651874f3adeb78bb115ffc4910ae1 Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Tue, 19 May 2026 14:34:10 +1000 Subject: [PATCH 04/25] Bugfix webmin-conf-logging --- conf/turnkey.d/webmin-conf-logging | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/conf/turnkey.d/webmin-conf-logging b/conf/turnkey.d/webmin-conf-logging index 85278831..c73fd286 100755 --- a/conf/turnkey.d/webmin-conf-logging +++ b/conf/turnkey.d/webmin-conf-logging @@ -1,4 +1,4 @@ -#!/bin/sh -e +#!/bin/bash -e CONF=/etc/webmin/miniserv.conf LOG_DIR=/var/log/webmin @@ -42,8 +42,8 @@ update_or_add logfile "$LOG_DIR/webmin.log" # Prime log files and set permissions mkdir -p "$LOG_DIR" -touch "$LOG_DIR{miniserv.log,miniserv.error,webmin.log}" +touch "$LOG_DIR"/{miniserv.log,miniserv.error,webmin.log} chmod 750 "$LOG_DIR" -chmod 640 "$LOG_DIR"*.log +chmod 640 "$LOG_DIR"/*.log rm -f /var/webmin/webmin.log ln -sf /var/log/webmin/webmin.log /var/webmin/webmin.log From b654e3e421309a44d580b42f7984e9a65257ab92 Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Tue, 19 May 2026 14:46:23 +1000 Subject: [PATCH 05/25] Work around bash script race condition (process substitution directly into readarray) --- conf/turnkey.d/webmin-fw | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/conf/turnkey.d/webmin-fw b/conf/turnkey.d/webmin-fw index 1faccf41..3e01d5e6 100755 --- a/conf/turnkey.d/webmin-fw +++ b/conf/turnkey.d/webmin-fw @@ -3,9 +3,19 @@ # TODO: drop use of iptables-legacy and use nftables directly set "${WEBMIN_FW_TCP_INCOMING:=22 80 443 12321}" + # Read into an array of sorted unique values -readarray -t WEBMIN_FW_TCP_INCOMING \ - < <(tr ' ' '\n' <<< "$WEBMIN_FW_TCP_INCOMING" | sort -un) +# Note: lastpipe is enabled to work around race condition when combining +# readarray directly with process substitution in bash scripts (job control +# must be off) +shopt -s lastpipe + +tr ' ' '\n' <<<"$WEBMIN_FW_TCP_INCOMING" \ + | sort -un \ + | readarray -t WEBMIN_FW_TCP_INCOMING + +# Disable lastpipe again to ensure no unexpected behavior later... +shopt -u lastpipe for conf in /etc/iptables.up.rules /etc/ip6tables.up.rules; do if [[ "$conf" == *"ip6"* ]]; then From dcee63f025656137e0214656640c0729ee0a684c Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Wed, 20 May 2026 10:00:17 +1000 Subject: [PATCH 06/25] Update fail2ban defaults; longer 'findtime' to 10min (hardened); increase 'maxretry' to 3 (slight easing) --- overlays/turnkey.d/fail2ban/etc/fail2ban/jail.local | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/overlays/turnkey.d/fail2ban/etc/fail2ban/jail.local b/overlays/turnkey.d/fail2ban/etc/fail2ban/jail.local index 28eb775e..ccd1b765 100644 --- a/overlays/turnkey.d/fail2ban/etc/fail2ban/jail.local +++ b/overlays/turnkey.d/fail2ban/etc/fail2ban/jail.local @@ -9,8 +9,8 @@ [DEFAULT] ignoreip = 127.0.0.1/8 ::1 bantime = 3600 -findtime = 10 -maxretry = 2 +findtime = 600 # 10 minutes +maxretry = 3 backend = systemd [sshd] From f92d4d5308e56a32ad392aee3a17e5134730333c Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Wed, 20 May 2026 11:30:11 +1000 Subject: [PATCH 07/25] Webmin conf - Force ssl/tls and hsts; 30 min session timeout --- conf/turnkey.d/webmin-conf-logging | 2 ++ 1 file changed, 2 insertions(+) diff --git a/conf/turnkey.d/webmin-conf-logging b/conf/turnkey.d/webmin-conf-logging index c73fd286..c3467647 100755 --- a/conf/turnkey.d/webmin-conf-logging +++ b/conf/turnkey.d/webmin-conf-logging @@ -28,7 +28,9 @@ update_or_add no_tls1_1 1 update_or_add no_tls1_2 update_or_add extracas update_or_add ssl_hsts 1 +update_or_add ssl_enforce 2 # force with hsts - '1' forces ssl but not hsts update_or_add ssl_redirect 1 +update_or_add session_timeout 1800 # 30 minutes # update logfile location update_or_add logfile "$LOG_DIR/miniserv.log" update_or_add errorlog "$LOG_DIR/miniserv.error" From 690455543199f546d6dc62776dce98fdc1bc5cb0 Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Wed, 20 May 2026 15:55:39 +1000 Subject: [PATCH 08/25] Don't install webmin-net by default - works around #2118 --- plans/turnkey/base | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/plans/turnkey/base b/plans/turnkey/base index e805ed45..ab598125 100644 --- a/plans/turnkey/base +++ b/plans/turnkey/base @@ -62,7 +62,9 @@ ncurses-term /* support additional $TERM values */ webmin webmin-authentic-theme -webmin-net +// webmin-net causing issues so excluded for now +// see https://github.com/turnkeylinux/tracker/issues/2118 +//webmin-net webmin-software webmin-useradmin webmin-passwd From aaf1c4d402a9eed4c2481bf9bd8186097040b837 Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Wed, 20 May 2026 15:57:37 +1000 Subject: [PATCH 09/25] Install iptables-persistent - resolves issue enabling/disabling firewall via Webmin --- plans/turnkey/base | 1 + 1 file changed, 1 insertion(+) diff --git a/plans/turnkey/base b/plans/turnkey/base index ab598125..634b3cab 100644 --- a/plans/turnkey/base +++ b/plans/turnkey/base @@ -84,6 +84,7 @@ libfile-mimeinfo-perl /* webmin-filemin requires to extract archives */ logrotate iptables +iptables-persistent webmin-firewall webmin-firewall6 fail2ban From 20f20bda49859acc5f2f584d8a3b264ff3fac318 Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Wed, 20 May 2026 16:01:49 +1000 Subject: [PATCH 10/25] Update firewall rule generation for use with 'iptables-persistent' package --- conf/turnkey.d/webmin-fw | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/conf/turnkey.d/webmin-fw b/conf/turnkey.d/webmin-fw index 3e01d5e6..854facaf 100755 --- a/conf/turnkey.d/webmin-fw +++ b/conf/turnkey.d/webmin-fw @@ -17,8 +17,9 @@ tr ' ' '\n' <<<"$WEBMIN_FW_TCP_INCOMING" \ # Disable lastpipe again to ensure no unexpected behavior later... shopt -u lastpipe -for conf in /etc/iptables.up.rules /etc/ip6tables.up.rules; do - if [[ "$conf" == *"ip6"* ]]; then +# iptables-persistent package compatible config +for conf in /etc/iptables/rules.v4 /etc/iptables/rules.v6; do + if [[ "$conf" == *"rules.v6" ]]; then # IPv6 should all accept all ICMPv6 types, not just echo-request # ICMPv6 is essential for neighbour discovery (NDP), router # advertisements, and path MTU - blocking it breaks IPv6 networking From 748dc54c691d6b33a52d62e366f6a5343ad67b61 Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Wed, 20 May 2026 16:27:35 +1000 Subject: [PATCH 11/25] Update TurnKey webmin patch to disable Webmin Let's Encrypt --- .../webmin/usr/local/src/webmin.patch | 30 +++++++++++-------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/overlays/turnkey.d/webmin/usr/local/src/webmin.patch b/overlays/turnkey.d/webmin/usr/local/src/webmin.patch index cf76bcbb..d27ce764 100644 --- a/overlays/turnkey.d/webmin/usr/local/src/webmin.patch +++ b/overlays/turnkey.d/webmin/usr/local/src/webmin.patch @@ -1,19 +1,25 @@ diff --git a/edit_ssl.cgi b/edit_ssl.cgi -index dd98182..1a4cd77 100755 +index a8b6274..f552dbb 100755 --- a/edit_ssl.cgi +++ b/edit_ssl.cgi -@@ -259,13 +259,14 @@ print ui_tabs_end_tab(); - print ui_tabs_start_tab("mode", "lets"); - print "$text{'ssl_letsdesc'}

\n"; +@@ -261,19 +261,15 @@ print ui_tabs_end_tab(); + # Let's Encrypt form + print ui_tabs_start_tab("mode", "lets"); -my $err = &check_letsencrypt(); +my $err = 1; - if ($err) { -- print "",&text('ssl_letserr', $err),"

\n"; -- print &get_letsencrypt_install_message( -- "/$module_name/edit_ssl.cgi?mode=lets", $text{'ssl_title'}); -- print "

\n"; -- print &text('ssl_letserr2', "../config.cgi?$module_name"),"

\n"; + print $text{'ssl_letsdesc'}; + if (!$err) { +- print &ui_tag('span', +- &ui_details({ +- 'class' => 'inline inlined', +- 'title' => '', +- 'content' => $text{'ssl_letsdesc2'}, +- }))."\n". +- &ui_tag('style', +- ".ui--span>details.inline>summary+span {\n". +- "margin-top: 0;\n". +- "}\n"); + print "Unfortunately the Webmin Let's Encrypt module currrently clashes"; + print " with TurnKey's SSL conf and has been disabled

\n"; + print "

To use Let's Encrypt, please use "; + print "Let's Encrypt plugin docs.

"; } - else { - # Show form to create a cert + print "

\n"; + From 58c6ebc186032cf5762e1280869b85de865f948b Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Wed, 20 May 2026 16:36:51 +1000 Subject: [PATCH 12/25] Fail if Webmin LE patch doesn't apply cleanly --- conf/turnkey.d/webmin-lets-enc | 2 ++ 1 file changed, 2 insertions(+) diff --git a/conf/turnkey.d/webmin-lets-enc b/conf/turnkey.d/webmin-lets-enc index a19d84ed..2ae13e0e 100755 --- a/conf/turnkey.d/webmin-lets-enc +++ b/conf/turnkey.d/webmin-lets-enc @@ -3,5 +3,7 @@ # Disable Webmin Let's Encrypt config - via patch cd /usr/share/webmin/webmin +# test patch first; --check exits non-zero if doesn't apply cleanly +git apply --check /usr/local/src/webmin.patch git apply /usr/local/src/webmin.patch rm /usr/local/src/webmin.patch From 3cbcbce6115a9c9fea9fdb5b0b401c1dad537fe1 Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Wed, 20 May 2026 10:35:09 +1000 Subject: [PATCH 13/25] Configure adminer specific logging for all supported webservers - consistant log location regardless --- conf/adminer | 9 ++++++++- conf/adminer-lighttpd | 1 + overlays/adminer/etc/adminer/apache.conf | 3 +++ overlays/adminer/etc/adminer/lighttpd.conf | 6 ++++++ overlays/adminer/etc/adminer/nginx.conf | 4 +++- 5 files changed, 21 insertions(+), 2 deletions(-) diff --git a/conf/adminer b/conf/adminer index 3df8d007..347bf947 100755 --- a/conf/adminer +++ b/conf/adminer @@ -10,7 +10,14 @@ ln -sf $ADMINER_DIR/designs/nette/adminer.css $STATIC_DIR/default.css ln -sf /etc/adminer/adminer.css /usr/share/adminer/adminer/adminer.css -# ensure www-data has read access to php files in /etc/adminer +# Ensure www-data has read access to php files in /etc/adminer chown root:www-data /etc/adminer /etc/adminer/tkl-*.php /etc/adminer/adminer.css chmod 755 /etc/adminer chmod 644 /etc/adminer/tkl-*.php /etc/adminer/adminer.css + +# Set up custom Adminer specific logging (config in relevant webserver vhosts) +mkdir -p /var/log/adminer +touch /var/log/adminer/{access.log,error.log} +chown -R root:adm /var/log/adminer +chmod 755 /var/log/adminer +chmod 644 /var/log/adminer/*.log diff --git a/conf/adminer-lighttpd b/conf/adminer-lighttpd index 588cd4a2..bb3f47dc 100755 --- a/conf/adminer-lighttpd +++ b/conf/adminer-lighttpd @@ -6,3 +6,4 @@ sed -i 's|^[[:space:]]*#([[:space:]]*"mod_redirect".*)|\1|' /etc/lighttpd/lightt # Link conf file to available-sites, and enable it ln -s /etc/adminer/lighttpd.conf /etc/lighttpd/conf-available/50-adminer.conf lighty-enable-mod adminer || true +lighty-enable-mod accesslog diff --git a/overlays/adminer/etc/adminer/apache.conf b/overlays/adminer/etc/adminer/apache.conf index 3e170e6f..2500e7ba 100644 --- a/overlays/adminer/etc/adminer/apache.conf +++ b/overlays/adminer/etc/adminer/apache.conf @@ -6,6 +6,9 @@ Alias /adminer/static /usr/share/adminer/adminer/static Alias /externals /usr/share/adminer/externals Alias /editor /usr/share/adminer/editor + + CustomLog /var/log/adminer/access.log combined + ErrorLog /var/log/adminer/error.log diff --git a/overlays/adminer/etc/adminer/lighttpd.conf b/overlays/adminer/etc/adminer/lighttpd.conf index 8d483033..4b41e7eb 100644 --- a/overlays/adminer/etc/adminer/lighttpd.conf +++ b/overlays/adminer/etc/adminer/lighttpd.conf @@ -29,6 +29,9 @@ $SERVER["socket"] == "0.0.0.0:12322" { server.document-root = "/usr/share/adminer/adminer/" alias.url = alias_redirects follow-symlink = "enable" + + accesslog.filename = "/var/log/adminer/access.log" + server.errorlog = "/var/log/adminer/error.log" } # IPv6 @@ -37,4 +40,7 @@ $SERVER["socket"] == "[::]:12322" { server.document-root = "/usr/share/adminer/adminer/" alias.url = alias_redirects follow-symlink = "enable" + + accesslog.filename = "/var/log/adminer/access.log" + server.errorlog = "/var/log/adminer/error.log" } diff --git a/overlays/adminer/etc/adminer/nginx.conf b/overlays/adminer/etc/adminer/nginx.conf index 53915003..f3ae57be 100644 --- a/overlays/adminer/etc/adminer/nginx.conf +++ b/overlays/adminer/etc/adminer/nginx.conf @@ -5,7 +5,9 @@ server { listen [::]:12322 ssl; include /etc/nginx/snippets/ssl.conf; root /usr/share/adminer/adminer/; - error_log /var/log/nginx/adminer-error.log; + + access_log /var/log/adminer/access.log; + error_log /var/log/adminer/error.log; location / { index tkl-index.php index.php; From 4421794b494cd5cd6770269ba8af23cb809b27c2 Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Wed, 20 May 2026 10:36:15 +1000 Subject: [PATCH 14/25] Rotate Adminer log files (webserver agnostic) --- overlays/adminer/etc/logrotate.d/adminer | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 overlays/adminer/etc/logrotate.d/adminer diff --git a/overlays/adminer/etc/logrotate.d/adminer b/overlays/adminer/etc/logrotate.d/adminer new file mode 100644 index 00000000..479404e0 --- /dev/null +++ b/overlays/adminer/etc/logrotate.d/adminer @@ -0,0 +1,23 @@ +/var/log/adminer/access.log +/var/log/adminer/error.log { + weekly + rotate 4 + compress + missingok + notifempty + sharedscripts + postrotate + # Apache + if systemctl is-active --quiet apache2; then + systemctl reload apache2 + fi + # Nginx + if systemctl is-active --quiet nginx; then + systemctl reload nginx + fi + # Lighttpd + if systemctl is-active --quiet lighttpd; then + systemctl reload lighttpd + fi + endscript +} From d974c0ec3b4993c529b5918dc0051b4bd845c629 Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Wed, 20 May 2026 10:37:57 +1000 Subject: [PATCH 15/25] Add Adminer fail2ban conf --- conf/adminer | 11 +++++++++++ .../adminer/etc/fail2ban/filter.d/adminer-auth.conf | 12 ++++++++++++ 2 files changed, 23 insertions(+) create mode 100644 overlays/adminer/etc/fail2ban/filter.d/adminer-auth.conf diff --git a/conf/adminer b/conf/adminer index 347bf947..c30f6d9e 100755 --- a/conf/adminer +++ b/conf/adminer @@ -21,3 +21,14 @@ touch /var/log/adminer/{access.log,error.log} chown -R root:adm /var/log/adminer chmod 755 /var/log/adminer chmod 644 /var/log/adminer/*.log + +# Configure fail2ban protection for Adminer +cat >> /etc/fail2ban/jail.local < .* "POST /adminer\.php.*" (200|302) .*$ + +ignoreregex = From 6f98b9b78213ee80e9a34cfa9af08877511dda09 Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Wed, 20 May 2026 16:54:22 +1000 Subject: [PATCH 16/25] Bugfix sed command (extended regex without '-E') --- conf/adminer-lighttpd | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/adminer-lighttpd b/conf/adminer-lighttpd index bb3f47dc..2fbaefb7 100755 --- a/conf/adminer-lighttpd +++ b/conf/adminer-lighttpd @@ -1,7 +1,7 @@ #!/bin/bash -ex # Ensure redirection is enabled -sed -i 's|^[[:space:]]*#([[:space:]]*"mod_redirect".*)|\1|' /etc/lighttpd/lighttpd.conf +sed -Ei 's|^[[:space:]]*#([[:space:]]*"mod_redirect".*)|\1|' /etc/lighttpd/lighttpd.conf # Link conf file to available-sites, and enable it ln -s /etc/adminer/lighttpd.conf /etc/lighttpd/conf-available/50-adminer.conf From f1557fea94ddb7ca536fb5fb6309de2897cc5fab Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Fri, 22 May 2026 12:48:29 +1000 Subject: [PATCH 17/25] Remove redundant bugfix --- conf/turnkey.d/fail2ban-fixes | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/conf/turnkey.d/fail2ban-fixes b/conf/turnkey.d/fail2ban-fixes index 83612bc0..c961bc37 100755 --- a/conf/turnkey.d/fail2ban-fixes +++ b/conf/turnkey.d/fail2ban-fixes @@ -8,28 +8,6 @@ if ! grep -q '^allowipv6' $CONF; then sed -i '\|^\[Definition\]|a \\nallowipv6 = auto' $CONF fi -# ensure that fail2ban blocks known users with incorrect key - see Debian -# Bug #1038779 - https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1038779 - -cat > fail2ban.patch <(?P\S+)|(?:(?! from ).)*? from %(__on_port_opt)s(?: ssh\d*)?(?(cond_user): |(?:(?:(?! from ).)*)$) - # consider failed publickey for valid users too (don't need RE, see cmnfailed): --cmnfailre-failed-pub-any = -+cmnfailre-failed-pub-any = ^Failed publickey for (?P\S+)|(?:(?! from ).)*? from %(__on_port_opt)s(?: ssh\d*)?(?(cond_user): |(?:(?:(?! from ).)*)$) - # same as invalid, but consider failed publickey for valid users too, just as no failure (helper to get IP and user-name only, see cmnfailed): --cmnfailre-failed-pub-nofail = -+cmnfailre-failed-pub-nofail = - # don't consider failed publickey as failures (don't need RE, see cmnfailed): - cmnfailre-failed-pub-ignore = - -EOF -git apply fail2ban.patch -rm fail2ban.patch - cat > /etc/cron.weekly/fail2ban < Date: Fri, 22 May 2026 12:51:27 +1000 Subject: [PATCH 18/25] Remove another redundant bugfix --- conf/turnkey.d/fail2ban-fixes | 8 -------- 1 file changed, 8 deletions(-) diff --git a/conf/turnkey.d/fail2ban-fixes b/conf/turnkey.d/fail2ban-fixes index c961bc37..7398cea4 100755 --- a/conf/turnkey.d/fail2ban-fixes +++ b/conf/turnkey.d/fail2ban-fixes @@ -1,13 +1,5 @@ #!/bin/bash -e -# explictly allow ipv6 - see Debian bug #1024305: -# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1024305 - -CONF=/etc/fail2ban/fail2ban.conf -if ! grep -q '^allowipv6' $CONF; then - sed -i '\|^\[Definition\]|a \\nallowipv6 = auto' $CONF -fi - cat > /etc/cron.weekly/fail2ban < Date: Fri, 22 May 2026 13:10:20 +1000 Subject: [PATCH 19/25] Remove invalid lighty conf (removed in v1.4.56 - Trixie has v1.4.79) --- overlays/lighttpd/etc/lighttpd/ssl-params.conf | 1 - 1 file changed, 1 deletion(-) diff --git a/overlays/lighttpd/etc/lighttpd/ssl-params.conf b/overlays/lighttpd/etc/lighttpd/ssl-params.conf index 3349834c..a7426044 100644 --- a/overlays/lighttpd/etc/lighttpd/ssl-params.conf +++ b/overlays/lighttpd/etc/lighttpd/ssl-params.conf @@ -5,7 +5,6 @@ ssl.pemfile = "/etc/ssl/private/cert.pem" ssl.privkey = "/etc/ssl/private/cert.key" -ssl.dh-file = "/etc/ssl/private/dhparams.pem" ssl.openssl.ssl-conf-cmd = ("MinProtocol" => "TLSv1.2") # lighttpd 1.4.79 TLS default appends X448 From 0afd9399c98a2f08776251a6d551b546fda5a39e Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Fri, 22 May 2026 13:12:12 +1000 Subject: [PATCH 20/25] Enable TKL default ciphers --- overlays/lighttpd/etc/lighttpd/ssl-params.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/overlays/lighttpd/etc/lighttpd/ssl-params.conf b/overlays/lighttpd/etc/lighttpd/ssl-params.conf index a7426044..33b88cc7 100644 --- a/overlays/lighttpd/etc/lighttpd/ssl-params.conf +++ b/overlays/lighttpd/etc/lighttpd/ssl-params.conf @@ -14,7 +14,7 @@ ssl.openssl.ssl-conf-cmd = ("MinProtocol" => "TLSv1.2") # See https://wiki.lighttpd.net/Docs_SSL # Uncomment to better match the less restricted Mozilla intermediate spec. # (TKL Ciphers set by common/conf/turnkey.d/zz-ssl-ciphers) -#ssl.openssl.ssl-conf-cmd += ("CipherString" => "ZZ_SSL_CIPHERS") +ssl.openssl.ssl-conf-cmd += ("CipherString" => "ZZ_SSL_CIPHERS") # HSTS config + additional hardening server.modules += ("mod_redirect") From 550cd1264c8ffccd2681057daef9017056d248c5 Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Fri, 22 May 2026 14:07:27 +1000 Subject: [PATCH 21/25] Lighty doesn't appear to support aliases, so replace config with symlink; also ensure tkl-index matches first --- conf/adminer-lighttpd | 3 +++ overlays/adminer/etc/adminer/lighttpd.conf | 17 ++--------------- 2 files changed, 5 insertions(+), 15 deletions(-) diff --git a/conf/adminer-lighttpd b/conf/adminer-lighttpd index 2fbaefb7..b89579b2 100755 --- a/conf/adminer-lighttpd +++ b/conf/adminer-lighttpd @@ -7,3 +7,6 @@ sed -Ei 's|^[[:space:]]*#([[:space:]]*"mod_redirect".*)|\1|' /etc/lighttpd/light ln -s /etc/adminer/lighttpd.conf /etc/lighttpd/conf-available/50-adminer.conf lighty-enable-mod adminer || true lighty-enable-mod accesslog + +# Lighty doesn't support aliases, so we need to symlink tkl-index +ln -sf /etc/adminer/tkl-index.php /usr/share/adminer/adminer/tkl-index.php diff --git a/overlays/adminer/etc/adminer/lighttpd.conf b/overlays/adminer/etc/adminer/lighttpd.conf index 4b41e7eb..f3a92906 100644 --- a/overlays/adminer/etc/adminer/lighttpd.conf +++ b/overlays/adminer/etc/adminer/lighttpd.conf @@ -8,25 +8,11 @@ var.alias_redirects = ( "/externals/" => "/usr/share/adminer/externals/" ) -# Map tkl-index.php URL to the actual file in /etc/adminer/ -$HTTP["url"] == "/tkl-index.php" { - fastcgi.server = ( - ".php" => (( - "socket" => "/run/php/php-fpm.sock", # may need adjustment? - "check-local" => "disable", - "bin-environment" => ( - "SCRIPT_FILENAME" => "/etc/adminer/tkl-index.php" - ) - )) - ) -} - -index-file.names += ( "tkl-index.php" ) - # IPv4 $SERVER["socket"] == "0.0.0.0:12322" { ssl.engine = "enable" server.document-root = "/usr/share/adminer/adminer/" + index-file.names = ( "tkl-index.php", "index.php" ) alias.url = alias_redirects follow-symlink = "enable" @@ -38,6 +24,7 @@ $SERVER["socket"] == "0.0.0.0:12322" { $SERVER["socket"] == "[::]:12322" { ssl.engine = "enable" server.document-root = "/usr/share/adminer/adminer/" + index-file.names = ( "tkl-index.php", "index.php" ) alias.url = alias_redirects follow-symlink = "enable" From 586a6bdca8c3da1dd1915aabdda986f04fc10288 Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Fri, 22 May 2026 14:11:23 +1000 Subject: [PATCH 22/25] Lighty fails if www-data can't write to logs --- conf/adminer | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/conf/adminer b/conf/adminer index c30f6d9e..99dc7d85 100755 --- a/conf/adminer +++ b/conf/adminer @@ -18,7 +18,7 @@ chmod 644 /etc/adminer/tkl-*.php /etc/adminer/adminer.css # Set up custom Adminer specific logging (config in relevant webserver vhosts) mkdir -p /var/log/adminer touch /var/log/adminer/{access.log,error.log} -chown -R root:adm /var/log/adminer +chown -R www-data:www-data /var/log/adminer chmod 755 /var/log/adminer chmod 644 /var/log/adminer/*.log From 91fc88f2fc45a7a9002bdb8cf6b06e3987b5dee6 Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Fri, 22 May 2026 14:16:35 +1000 Subject: [PATCH 23/25] Default root ownership of /etc/adminer - www-data only needs access to php/css files --- conf/adminer | 1 + 1 file changed, 1 insertion(+) diff --git a/conf/adminer b/conf/adminer index 99dc7d85..76f8ca3b 100755 --- a/conf/adminer +++ b/conf/adminer @@ -11,6 +11,7 @@ ln -sf $ADMINER_DIR/designs/nette/adminer.css $STATIC_DIR/default.css ln -sf /etc/adminer/adminer.css /usr/share/adminer/adminer/adminer.css # Ensure www-data has read access to php files in /etc/adminer +chown -R root:adm /etc/adminer chown root:www-data /etc/adminer /etc/adminer/tkl-*.php /etc/adminer/adminer.css chmod 755 /etc/adminer chmod 644 /etc/adminer/tkl-*.php /etc/adminer/adminer.css From ef7669daf6f668c94e2d17b0d44bb15a444c97c0 Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Fri, 22 May 2026 17:02:08 +1000 Subject: [PATCH 24/25] Fix nginx adminer config --- overlays/adminer/etc/adminer/nginx.conf | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/overlays/adminer/etc/adminer/nginx.conf b/overlays/adminer/etc/adminer/nginx.conf index f3ae57be..5d08e819 100644 --- a/overlays/adminer/etc/adminer/nginx.conf +++ b/overlays/adminer/etc/adminer/nginx.conf @@ -16,9 +16,10 @@ server { # Route tkl-index.php to /etc/adminer/ location = /tkl-index.php { + include /etc/nginx/snippets/fastcgi-php.conf; fastcgi_param HTTPS on; fastcgi_param SCRIPT_FILENAME /etc/adminer/tkl-index.php; - include /etc/nginx/snippets/php-fpm.conf; + fastcgi_pass unix:/run/php/php-fpm.sock; } location ~ \.php$ { From 95912290f8a2d41c26b62eb455615490cf369507 Mon Sep 17 00:00:00 2001 From: Jeremy Davis Date: Fri, 22 May 2026 17:11:52 +1000 Subject: [PATCH 25/25] Enable php-fpm by default and split http & https blocks --- .../nginx/etc/nginx/sites-available/tkl-default | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/overlays/nginx/etc/nginx/sites-available/tkl-default b/overlays/nginx/etc/nginx/sites-available/tkl-default index 9938d683..8a02b446 100644 --- a/overlays/nginx/etc/nginx/sites-available/tkl-default +++ b/overlays/nginx/etc/nginx/sites-available/tkl-default @@ -18,14 +18,18 @@ ## # Default server configuration -# + +# HTTP server { listen 80 default_server; listen [::]:80 default_server; - + server_name _; # temporary redirect to https - update to permanent (308) for production return 307 https://$host$request_uri; +} +# HTTPS +server { # SSL configuration listen 443 ssl default_server; listen [::]:443 ssl default_server; @@ -33,8 +37,8 @@ server { root /var/www; - # Ensure index.php is at the end of this list if using php-fpm - index index.html index.htm; + # index.php can be removed from the end of this list when not using php-fpm + index index.html index.htm index.php; server_name _; @@ -44,8 +48,8 @@ server { try_files $uri $uri/ =404; } - # Uncomment to enable PHP-FPM - #include snippets/php-fpm.conf; + # Comment to disable PHP-FPM + include snippets/php-fpm.conf; # Deny access to all dot files location ~ /\. {