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:
parent
22b344225c
commit
2053cfb614
@ -126,6 +126,14 @@ init_yaml() {
|
|||||||
sed -i "s,^\(\s*api_key\s*:\s*\).*\$,\1$api_key," $VARCONFIG
|
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() {
|
init_nftables() {
|
||||||
local section="$1"
|
local section="$1"
|
||||||
|
|
||||||
@ -152,7 +160,16 @@ init_nftables() {
|
|||||||
config_get_bool filter_forward $section filter_forward '1'
|
config_get_bool filter_forward $section filter_forward '1'
|
||||||
config_get chain_name $section chain_name "crowdsec-chain"
|
config_get chain_name $section chain_name "crowdsec-chain"
|
||||||
config_get chain6_name $section chain6_name "crowdsec6-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
|
if [ "$deny_log" -eq "1" ]; then
|
||||||
log_term="log prefix \"${log_prefix}\""
|
log_term="log prefix \"${log_prefix}\""
|
||||||
|
|||||||
@ -4,7 +4,7 @@
|
|||||||
include $(TOPDIR)/rules.mk
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
PKG_NAME:=secubox-auth-logger
|
PKG_NAME:=secubox-auth-logger
|
||||||
PKG_VERSION:=1.1.0
|
PKG_VERSION:=1.2.0
|
||||||
PKG_RELEASE:=1
|
PKG_RELEASE:=1
|
||||||
PKG_ARCH:=all
|
PKG_ARCH:=all
|
||||||
PKG_LICENSE:=Apache-2.0
|
PKG_LICENSE:=Apache-2.0
|
||||||
@ -95,10 +95,30 @@ endef
|
|||||||
define Package/secubox-auth-logger/postrm
|
define Package/secubox-auth-logger/postrm
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
[ -n "$${IPKG_INSTROOT}" ] || {
|
[ -n "$${IPKG_INSTROOT}" ] || {
|
||||||
# Remove JS hook from LuCI header
|
# Restore dispatcher from backup
|
||||||
if [ -f /usr/lib/lua/luci/view/themes/bootstrap/header.htm ]; then
|
DISPATCHER="/usr/share/ucode/luci/dispatcher.uc"
|
||||||
sed -i '/secubox-auth-hook/d' /usr/lib/lua/luci/view/themes/bootstrap/header.htm 2>/dev/null || true
|
if [ -f "$${DISPATCHER}.bak" ]; then
|
||||||
|
mv "$${DISPATCHER}.bak" "$$DISPATCHER"
|
||||||
|
echo "Restored LuCI dispatcher from backup"
|
||||||
fi
|
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
|
exit 0
|
||||||
endef
|
endef
|
||||||
|
|||||||
@ -1,11 +1,13 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
# SecuBox Auth Logger - Post-install configuration
|
# 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
|
# Copyright (C) 2024 CyberMind.fr
|
||||||
|
|
||||||
# Note: Dropbear 2024.86 does NOT support -v flag
|
LOG_FILE="/var/log/secubox-auth.log"
|
||||||
# Auth monitoring relies on parsing existing syslog messages
|
DISPATCHER="/usr/share/ucode/luci/dispatcher.uc"
|
||||||
# The auth-monitor.sh script watches logread for auth failures
|
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
|
# Enable uhttpd syslog for LuCI login monitoring
|
||||||
if [ -f /etc/config/uhttpd ]; then
|
if [ -f /etc/config/uhttpd ]; then
|
||||||
@ -14,52 +16,90 @@ if [ -f /etc/config/uhttpd ]; then
|
|||||||
/etc/init.d/uhttpd restart 2>/dev/null
|
/etc/init.d/uhttpd restart 2>/dev/null
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Create auth log file for secubox-auth-logger
|
# Create auth log file for CrowdSec
|
||||||
touch /var/log/secubox-auth.log
|
touch "$LOG_FILE"
|
||||||
chmod 644 /var/log/secubox-auth.log
|
chmod 644 "$LOG_FILE"
|
||||||
|
|
||||||
# Inject JS hook into LuCI login page
|
# Patch the LuCI dispatcher to log authentication failures
|
||||||
# Try multiple locations for different LuCI versions/themes
|
# 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() {
|
inject_js_hook() {
|
||||||
local hook_script='<script src="/luci-static/resources/secubox/secubox-auth-hook.js"></script>'
|
# Method 1: Modern LuCI (ucode templates) - openwrt2020 theme
|
||||||
local hook_marker="secubox-auth-hook"
|
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 [ -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
|
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
|
sed -i "s|</head>|$JS_HOOK\n</head>|" /usr/lib/lua/luci/view/themes/bootstrap/header.htm 2>/dev/null
|
||||||
fi
|
fi
|
||||||
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 [ -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
|
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
|
sed -i "s|</head>|$JS_HOOK\n</head>|" /usr/lib/lua/luci/view/themes/material/header.htm 2>/dev/null
|
||||||
fi
|
fi
|
||||||
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 [ -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
|
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
|
sed -i "s|</head>|$JS_HOOK\n</head>|" /usr/lib/lua/luci/view/themes/openwrt/header.htm 2>/dev/null
|
||||||
fi
|
fi
|
||||||
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 [ -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
|
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
|
sed -i "s|</head>|$JS_HOOK\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
|
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Main installation
|
||||||
|
patch_dispatcher
|
||||||
inject_js_hook
|
inject_js_hook
|
||||||
|
|
||||||
# Restart rpcd to load new ubus object
|
# Restart rpcd to load new ubus object
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user