fix(crowdsec): Patch dispatcher for auth logging and fix firewall interfaces

- secubox-auth-logger v1.2.0: Patch LuCI ucode dispatcher.uc to log
  authentication failures server-side instead of relying on JS hooks
- crowdsec-firewall-bouncer: Add helper function for UCI list reading
  and default to eth1, br-lan, br-wan interfaces to ensure WAN traffic
  is checked against the blocklist
- Update postrm to properly restore dispatcher backup on uninstall

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
CyberMind-FR 2026-01-13 15:50:55 +01:00
parent 22b344225c
commit 2053cfb614
3 changed files with 112 additions and 35 deletions

View File

@ -126,6 +126,14 @@ init_yaml() {
sed -i "s,^\(\s*api_key\s*:\s*\).*\$,\1$api_key," $VARCONFIG
}
_add_interface_to_list() {
if [ -z "$interface_list" ]; then
interface_list="$1"
else
interface_list="$interface_list $1"
fi
}
init_nftables() {
local section="$1"
@ -152,7 +160,16 @@ init_nftables() {
config_get_bool filter_forward $section filter_forward '1'
config_get chain_name $section chain_name "crowdsec-chain"
config_get chain6_name $section chain6_name "crowdsec6-chain"
config_get interface $section interface 'eth1'
# Read interface list properly (UCI list or single value)
local interface_list=""
config_list_foreach "$section" interface _add_interface_to_list
if [ -z "$interface_list" ]; then
# Fallback: try single value
config_get interface_list $section interface ''
fi
# Default interfaces for SecuBox (eth1=WAN on x86, br-wan=WAN bridge, br-lan=LAN)
interface="${interface_list:-eth1, br-lan, br-wan}"
if [ "$deny_log" -eq "1" ]; then
log_term="log prefix \"${log_prefix}\""

View File

@ -4,7 +4,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=secubox-auth-logger
PKG_VERSION:=1.1.0
PKG_VERSION:=1.2.0
PKG_RELEASE:=1
PKG_ARCH:=all
PKG_LICENSE:=Apache-2.0
@ -95,10 +95,30 @@ endef
define Package/secubox-auth-logger/postrm
#!/bin/sh
[ -n "$${IPKG_INSTROOT}" ] || {
# Remove JS hook from LuCI header
if [ -f /usr/lib/lua/luci/view/themes/bootstrap/header.htm ]; then
sed -i '/secubox-auth-hook/d' /usr/lib/lua/luci/view/themes/bootstrap/header.htm 2>/dev/null || true
# Restore dispatcher from backup
DISPATCHER="/usr/share/ucode/luci/dispatcher.uc"
if [ -f "$${DISPATCHER}.bak" ]; then
mv "$${DISPATCHER}.bak" "$$DISPATCHER"
echo "Restored LuCI dispatcher from backup"
fi
# Remove JS hook from modern LuCI theme headers
for header in /usr/share/ucode/luci/template/themes/*/header.ut; do
[ -f "$$header" ] && sed -i '/secubox-auth-hook/d' "$$header" 2>/dev/null || true
done
# Remove JS hook from legacy LuCI theme headers
for header in /usr/lib/lua/luci/view/themes/*/header.htm; do
[ -f "$$header" ] && sed -i '/secubox-auth-hook/d' "$$header" 2>/dev/null || true
done
# Remove JS hook from sysauth
if [ -f /usr/lib/lua/luci/view/sysauth.htm ]; then
sed -i '/secubox-auth-hook/d' /usr/lib/lua/luci/view/sysauth.htm 2>/dev/null || true
fi
# Restart uhttpd to apply changes
/etc/init.d/uhttpd restart 2>/dev/null || true
}
exit 0
endef

View File

@ -1,11 +1,13 @@
#!/bin/sh
# SecuBox Auth Logger - Post-install configuration
# Enables verbose logging for uhttpd and configures CrowdSec
# Patches LuCI dispatcher to log auth failures for CrowdSec
# Copyright (C) 2024 CyberMind.fr
# Note: Dropbear 2024.86 does NOT support -v flag
# Auth monitoring relies on parsing existing syslog messages
# The auth-monitor.sh script watches logread for auth failures
LOG_FILE="/var/log/secubox-auth.log"
DISPATCHER="/usr/share/ucode/luci/dispatcher.uc"
JS_HOOK='<script src="/luci-static/resources/secubox/secubox-auth-hook.js"></script>'
HOOK_MARKER="secubox-auth-hook"
AUTH_LOG_MARKER="_secubox_auth_log"
# Enable uhttpd syslog for LuCI login monitoring
if [ -f /etc/config/uhttpd ]; then
@ -14,52 +16,90 @@ if [ -f /etc/config/uhttpd ]; then
/etc/init.d/uhttpd restart 2>/dev/null
fi
# Create auth log file for secubox-auth-logger
touch /var/log/secubox-auth.log
chmod 644 /var/log/secubox-auth.log
# Create auth log file for CrowdSec
touch "$LOG_FILE"
chmod 644 "$LOG_FILE"
# Inject JS hook into LuCI login page
# Try multiple locations for different LuCI versions/themes
# Patch the LuCI dispatcher to log authentication failures
# This is the reliable server-side solution that works with modern LuCI (ucode)
patch_dispatcher() {
if [ ! -f "$DISPATCHER" ]; then
echo "Warning: LuCI dispatcher not found at $DISPATCHER"
return 1
fi
# Check if already patched
if grep -q "$AUTH_LOG_MARKER" "$DISPATCHER" 2>/dev/null; then
echo "Dispatcher already patched for auth logging"
return 0
fi
# Find the line with "if (!session)" - this is where auth failures happen
# We insert logging code right after this condition
if grep -q "if (!session)" "$DISPATCHER"; then
# Create backup
cp "$DISPATCHER" "${DISPATCHER}.bak"
# Insert auth failure logging code after "if (!session) {"
# The code logs to /var/log/secubox-auth.log in syslog format
sed -i 's/if (!session) {/if (!session) { let _secubox_auth_log = open("\/var\/log\/secubox-auth.log", "a"); if (_secubox_auth_log) { let _h = http.getenv("HTTP_HOST") || "OpenWrt"; let _ts = time(); let _d = localtime(_ts); let _month = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"][_d.mon]; let _fmt = sprintf("%s %2d %02d:%02d:%02d", _month, _d.mday, _d.hour, _d.min, _d.sec); _secubox_auth_log.write(_fmt + " " + _h + " secubox-auth[" + getpid() + "]: authentication failure for " + (user || "root") + " from " + (http.getenv("REMOTE_ADDR") || "unknown") + " via luci\\n"); _secubox_auth_log.close(); }/' "$DISPATCHER"
echo "Dispatcher patched for auth failure logging"
return 0
else
echo "Warning: Could not find auth check in dispatcher"
return 1
fi
}
# Inject JS hook into LuCI theme header (backup method)
# This provides client-side detection as a fallback
inject_js_hook() {
local hook_script='<script src="/luci-static/resources/secubox/secubox-auth-hook.js"></script>'
local hook_marker="secubox-auth-hook"
# Method 1: Modern LuCI (ucode templates) - openwrt2020 theme
if [ -f /usr/share/ucode/luci/template/themes/openwrt2020/header.ut ]; then
if ! grep -q "$HOOK_MARKER" /usr/share/ucode/luci/template/themes/openwrt2020/header.ut 2>/dev/null; then
sed -i "s|</head>|$JS_HOOK</head>|" /usr/share/ucode/luci/template/themes/openwrt2020/header.ut 2>/dev/null
fi
fi
# Method 1: Bootstrap theme header (LuCI 19.x+)
# Method 2: Modern LuCI (ucode templates) - bootstrap theme
if [ -f /usr/share/ucode/luci/template/themes/bootstrap/header.ut ]; then
if ! grep -q "$HOOK_MARKER" /usr/share/ucode/luci/template/themes/bootstrap/header.ut 2>/dev/null; then
sed -i "s|</head>|$JS_HOOK</head>|" /usr/share/ucode/luci/template/themes/bootstrap/header.ut 2>/dev/null
fi
fi
# Method 3: Legacy LuCI (Lua templates) - bootstrap theme
if [ -f /usr/lib/lua/luci/view/themes/bootstrap/header.htm ]; then
if ! grep -q "$hook_marker" /usr/lib/lua/luci/view/themes/bootstrap/header.htm 2>/dev/null; then
sed -i "s|</head>|$hook_script\n</head>|" /usr/lib/lua/luci/view/themes/bootstrap/header.htm 2>/dev/null
if ! grep -q "$HOOK_MARKER" /usr/lib/lua/luci/view/themes/bootstrap/header.htm 2>/dev/null; then
sed -i "s|</head>|$JS_HOOK\n</head>|" /usr/lib/lua/luci/view/themes/bootstrap/header.htm 2>/dev/null
fi
fi
# Method 2: Material theme header
# Method 4: Legacy LuCI (Lua templates) - material theme
if [ -f /usr/lib/lua/luci/view/themes/material/header.htm ]; then
if ! grep -q "$hook_marker" /usr/lib/lua/luci/view/themes/material/header.htm 2>/dev/null; then
sed -i "s|</head>|$hook_script\n</head>|" /usr/lib/lua/luci/view/themes/material/header.htm 2>/dev/null
if ! grep -q "$HOOK_MARKER" /usr/lib/lua/luci/view/themes/material/header.htm 2>/dev/null; then
sed -i "s|</head>|$JS_HOOK\n</head>|" /usr/lib/lua/luci/view/themes/material/header.htm 2>/dev/null
fi
fi
# Method 3: OpenWrt theme header
# Method 5: Legacy LuCI (Lua templates) - openwrt theme
if [ -f /usr/lib/lua/luci/view/themes/openwrt/header.htm ]; then
if ! grep -q "$hook_marker" /usr/lib/lua/luci/view/themes/openwrt/header.htm 2>/dev/null; then
sed -i "s|</head>|$hook_script\n</head>|" /usr/lib/lua/luci/view/themes/openwrt/header.htm 2>/dev/null
if ! grep -q "$HOOK_MARKER" /usr/lib/lua/luci/view/themes/openwrt/header.htm 2>/dev/null; then
sed -i "s|</head>|$JS_HOOK\n</head>|" /usr/lib/lua/luci/view/themes/openwrt/header.htm 2>/dev/null
fi
fi
# Method 4: Base sysauth view (fallback for login page)
# Method 6: Legacy LuCI sysauth view (fallback)
if [ -f /usr/lib/lua/luci/view/sysauth.htm ]; then
if ! grep -q "$hook_marker" /usr/lib/lua/luci/view/sysauth.htm 2>/dev/null; then
sed -i "s|</head>|$hook_script\n</head>|" /usr/lib/lua/luci/view/sysauth.htm 2>/dev/null
fi
fi
# Method 5: LuCI2 / luci-mod-admin-full footer
if [ -f /www/luci-static/resources/footer.htm ]; then
if ! grep -q "$hook_marker" /www/luci-static/resources/footer.htm 2>/dev/null; then
echo "$hook_script" >> /www/luci-static/resources/footer.htm 2>/dev/null
if ! grep -q "$HOOK_MARKER" /usr/lib/lua/luci/view/sysauth.htm 2>/dev/null; then
sed -i "s|</head>|$JS_HOOK\n</head>|" /usr/lib/lua/luci/view/sysauth.htm 2>/dev/null
fi
fi
}
# Main installation
patch_dispatcher
inject_js_hook
# Restart rpcd to load new ubus object