refactor(packages): Rename and reorganize SecuBox packages
- Rename crowdsec-firewall-bouncer to secubox-app-cs-firewall-bouncer - Rename secubox-auth-logger to secubox-app-auth-logger - Delete secubox-crowdsec-setup (merged into other packages) - Fix circular dependencies in luci-app-secubox-crowdsec - Fix dependency chain in secubox-app-crowdsec-bouncer - Add consolidated get_overview API to crowdsec-dashboard - Improve crowdsec-dashboard overview performance Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
fd7caeb8c3
commit
e62919eec7
@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-crowdsec-dashboard
|
||||
PKG_VERSION:=0.7.0
|
||||
PKG_RELEASE:=27
|
||||
PKG_RELEASE:=28
|
||||
PKG_ARCH:=all
|
||||
|
||||
PKG_LICENSE:=Apache-2.0
|
||||
|
||||
@ -526,6 +526,7 @@ return view.extend({
|
||||
]),
|
||||
|
||||
E('div', { 'class': 'cs-charts-row' }, [
|
||||
this.renderFirewallHealth(),
|
||||
this.renderFirewallBlocks()
|
||||
]),
|
||||
|
||||
@ -871,6 +872,78 @@ return view.extend({
|
||||
]);
|
||||
},
|
||||
|
||||
// Firewall Health Status Card
|
||||
renderFirewallHealth: function() {
|
||||
var stats = this.nftablesStats || {};
|
||||
var health = stats.firewall_health || {};
|
||||
|
||||
var status = health.status || 'unknown';
|
||||
var issues = health.issues || '';
|
||||
var bouncerRunning = health.bouncer_running;
|
||||
var uciEnabled = health.uci_enabled;
|
||||
var apiKeyConfigured = health.api_key_configured;
|
||||
var inputHooked = health.input_chain_hooked;
|
||||
var forwardHooked = health.forward_chain_hooked;
|
||||
var setsHaveTimeout = health.sets_have_timeout;
|
||||
var decisionsSynced = health.decisions_synced;
|
||||
var cscliDecisions = health.cscli_decisions_count || 0;
|
||||
var nftElements = health.nft_elements_count || 0;
|
||||
|
||||
var statusColor = status === 'ok' ? '#00d4aa' : (status === 'warning' ? '#ffa500' : '#ff4757');
|
||||
var statusIcon = status === 'ok' ? '✅' : (status === 'warning' ? '⚠️' : '❌');
|
||||
var statusText = status === 'ok' ? 'Healthy' : (status === 'warning' ? 'Warning' : 'Error');
|
||||
|
||||
var checkItems = [
|
||||
{ label: 'Bouncer Process', ok: bouncerRunning, detail: bouncerRunning ? 'Running' : 'Not running' },
|
||||
{ label: 'UCI Enabled', ok: uciEnabled, detail: uciEnabled ? 'Enabled' : 'Disabled' },
|
||||
{ label: 'API Key', ok: apiKeyConfigured, detail: apiKeyConfigured ? 'Configured' : 'Missing or default' },
|
||||
{ label: 'Input Chain', ok: inputHooked, detail: inputHooked ? 'Hooked' : 'Not hooked' },
|
||||
{ label: 'Forward Chain', ok: forwardHooked, detail: forwardHooked ? 'Hooked' : 'Not hooked' },
|
||||
{ label: 'Set Timeout', ok: setsHaveTimeout, detail: setsHaveTimeout ? 'Enabled' : 'Disabled' },
|
||||
{ label: 'Decisions Sync', ok: decisionsSynced, detail: decisionsSynced ? (nftElements + ' synced') : 'Out of sync' }
|
||||
];
|
||||
|
||||
var checkRows = checkItems.map(function(item) {
|
||||
return E('div', { 'style': 'display: flex; align-items: center; justify-content: space-between; padding: 0.4em 0; border-bottom: 1px solid rgba(255,255,255,0.05);' }, [
|
||||
E('div', { 'style': 'display: flex; align-items: center; gap: 0.5em;' }, [
|
||||
E('span', { 'style': 'font-size: 1em;' }, item.ok ? '✅' : '❌'),
|
||||
E('span', { 'style': 'font-size: 0.85em;' }, item.label)
|
||||
]),
|
||||
E('span', { 'style': 'font-size: 0.75em; color: ' + (item.ok ? '#00d4aa' : '#ff4757') + ';' }, item.detail)
|
||||
]);
|
||||
});
|
||||
|
||||
return E('div', { 'class': 'cs-card', 'style': 'flex: 1;' }, [
|
||||
E('div', { 'class': 'cs-card-header' }, [
|
||||
E('div', { 'class': 'cs-card-title' }, [
|
||||
_('Firewall Health'),
|
||||
E('span', {
|
||||
'style': 'margin-left: 0.75em; font-size: 0.8em; padding: 0.2em 0.6em; background: ' + statusColor + '; border-radius: 12px;'
|
||||
}, statusIcon + ' ' + statusText)
|
||||
])
|
||||
]),
|
||||
E('div', { 'class': 'cs-card-body' }, [
|
||||
// Status summary
|
||||
issues ? E('div', { 'style': 'background: rgba(255,71,87,0.1); border: 1px solid rgba(255,71,87,0.3); border-radius: 8px; padding: 0.75em; margin-bottom: 1em;' }, [
|
||||
E('div', { 'style': 'font-size: 0.85em; color: #ff4757;' }, issues)
|
||||
]) : E('span'),
|
||||
// Sync stats
|
||||
E('div', { 'style': 'display: flex; gap: 1em; margin-bottom: 1em;' }, [
|
||||
E('div', { 'style': 'flex: 1; text-align: center; padding: 0.5em; background: rgba(102,126,234,0.1); border-radius: 8px;' }, [
|
||||
E('div', { 'style': 'font-size: 1.25em; font-weight: 700; color: #667eea;' }, String(cscliDecisions)),
|
||||
E('div', { 'style': 'font-size: 0.7em; color: #888;' }, 'Decisions')
|
||||
]),
|
||||
E('div', { 'style': 'flex: 1; text-align: center; padding: 0.5em; background: rgba(0,212,170,0.1); border-radius: 8px;' }, [
|
||||
E('div', { 'style': 'font-size: 1.25em; font-weight: 700; color: #00d4aa;' }, String(nftElements)),
|
||||
E('div', { 'style': 'font-size: 0.7em; color: #888;' }, 'In Firewall')
|
||||
])
|
||||
]),
|
||||
// Check items
|
||||
E('div', {}, checkRows)
|
||||
])
|
||||
]);
|
||||
},
|
||||
|
||||
// Firewall Blocks - Shows IPs blocked in nftables
|
||||
renderFirewallBlocks: function() {
|
||||
var self = this;
|
||||
|
||||
@ -947,6 +947,86 @@ get_nftables_stats() {
|
||||
json_add_int "ipv6_cscli_count" "$ipv6_cscli"
|
||||
json_add_int "ipv6_total_count" "$((ipv6_capi + ipv6_cscli))"
|
||||
|
||||
# Firewall Health Check
|
||||
json_add_object "firewall_health"
|
||||
|
||||
# Check bouncer process
|
||||
local bouncer_running=0
|
||||
if pgrep cs-firewall-bouncer >/dev/null 2>&1; then
|
||||
bouncer_running=1
|
||||
fi
|
||||
json_add_boolean "bouncer_running" "$bouncer_running"
|
||||
|
||||
# Check UCI config
|
||||
local uci_enabled=0
|
||||
local uci_api_key=""
|
||||
if uci -q get crowdsec.bouncer.enabled >/dev/null 2>&1; then
|
||||
[ "$(uci -q get crowdsec.bouncer.enabled)" = "1" ] && uci_enabled=1
|
||||
fi
|
||||
uci_api_key=$(uci -q get crowdsec.bouncer.api_key 2>/dev/null)
|
||||
json_add_boolean "uci_enabled" "$uci_enabled"
|
||||
json_add_boolean "api_key_configured" "$([ -n "$uci_api_key" ] && [ "$uci_api_key" != "API_KEY" ] && echo 1 || echo 0)"
|
||||
|
||||
# Check chains are hooked (input/forward)
|
||||
local input_hooked=0
|
||||
local forward_hooked=0
|
||||
if [ "$ipv4_exists" = "1" ]; then
|
||||
nft list table ip crowdsec 2>/dev/null | grep -q "hook input" && input_hooked=1
|
||||
nft list table ip crowdsec 2>/dev/null | grep -q "hook forward" && forward_hooked=1
|
||||
fi
|
||||
json_add_boolean "input_chain_hooked" "$input_hooked"
|
||||
json_add_boolean "forward_chain_hooked" "$forward_hooked"
|
||||
|
||||
# Check if sets have timeout flag (required for auto-expiry)
|
||||
local sets_have_timeout=0
|
||||
if [ "$ipv4_exists" = "1" ]; then
|
||||
nft list set ip crowdsec crowdsec-blacklists 2>/dev/null | grep -q "flags timeout" && sets_have_timeout=1
|
||||
fi
|
||||
json_add_boolean "sets_have_timeout" "$sets_have_timeout"
|
||||
|
||||
# Check decisions sync (compare cscli decisions count vs nftables)
|
||||
local cscli_decisions=0
|
||||
local nft_elements=0
|
||||
local sync_ok=0
|
||||
if command -v cscli >/dev/null 2>&1; then
|
||||
cscli_decisions=$(cscli decisions list -o json 2>/dev/null | jsonfilter -e '@[*]' 2>/dev/null | wc -l || echo "0")
|
||||
fi
|
||||
nft_elements=$((ipv4_capi + ipv4_cscli + ipv4_other + ipv6_capi + ipv6_cscli))
|
||||
# Sync is OK if nft has at least some elements when decisions exist
|
||||
[ "$cscli_decisions" -gt 0 ] && [ "$nft_elements" -gt 0 ] && sync_ok=1
|
||||
[ "$cscli_decisions" -eq 0 ] && [ "$nft_elements" -eq 0 ] && sync_ok=1
|
||||
json_add_int "cscli_decisions_count" "$cscli_decisions"
|
||||
json_add_int "nft_elements_count" "$nft_elements"
|
||||
json_add_boolean "decisions_synced" "$sync_ok"
|
||||
|
||||
# Overall health status
|
||||
local health_status="ok"
|
||||
local health_issues=""
|
||||
if [ "$bouncer_running" != "1" ]; then
|
||||
health_status="error"
|
||||
health_issues="Bouncer not running; "
|
||||
fi
|
||||
if [ "$uci_enabled" != "1" ]; then
|
||||
health_status="warning"
|
||||
health_issues="${health_issues}Bouncer not enabled in UCI; "
|
||||
fi
|
||||
if [ "$ipv4_exists" != "1" ]; then
|
||||
health_status="error"
|
||||
health_issues="${health_issues}IPv4 table missing; "
|
||||
fi
|
||||
if [ "$input_hooked" != "1" ] && [ "$forward_hooked" != "1" ]; then
|
||||
health_status="error"
|
||||
health_issues="${health_issues}No chains hooked; "
|
||||
fi
|
||||
if [ "$sync_ok" != "1" ]; then
|
||||
health_status="warning"
|
||||
health_issues="${health_issues}Decisions not synced to firewall; "
|
||||
fi
|
||||
json_add_string "status" "$health_status"
|
||||
json_add_string "issues" "$health_issues"
|
||||
|
||||
json_close_object
|
||||
|
||||
json_dump
|
||||
}
|
||||
|
||||
|
||||
@ -11,7 +11,7 @@ PKG_VERSION:=1.0.0
|
||||
PKG_RELEASE:=1
|
||||
|
||||
LUCI_TITLE:=LuCI SecuBox CrowdSec Dashboard
|
||||
LUCI_DEPENDS:=+luci-base +crowdsec +crowdsec-firewall-bouncer
|
||||
LUCI_DEPENDS:=+luci-base +crowdsec +secubox-app-cs-firewall-bouncer
|
||||
LUCI_PKGARCH:=all
|
||||
|
||||
PKG_MAINTAINER:=Gerald Kerma <gandalf@gk2.net>
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=secubox-auth-logger
|
||||
PKG_NAME:=secubox-app-auth-logger
|
||||
PKG_VERSION:=1.2.2
|
||||
PKG_RELEASE:=1
|
||||
PKG_ARCH:=all
|
||||
@ -12,15 +12,16 @@ PKG_MAINTAINER:=CyberMind <contact@cybermind.fr>
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/secubox-auth-logger
|
||||
define Package/secubox-app-auth-logger
|
||||
SECTION:=secubox
|
||||
CATEGORY:=SecuBox
|
||||
TITLE:=Authentication Failure Logger for CrowdSec
|
||||
DEPENDS:=+rpcd +uhttpd +libubox-lua
|
||||
PKGARCH:=all
|
||||
PROVIDES:=secubox-auth-logger
|
||||
endef
|
||||
|
||||
define Package/secubox-auth-logger/description
|
||||
define Package/secubox-app-auth-logger/description
|
||||
Logs authentication failures from LuCI/rpcd and Dropbear SSH
|
||||
for CrowdSec detection. Includes:
|
||||
- SSH failure monitoring (OpenSSH/Dropbear)
|
||||
@ -32,14 +33,14 @@ endef
|
||||
define Build/Compile
|
||||
endef
|
||||
|
||||
define Package/secubox-auth-logger/install
|
||||
define Package/secubox-app-auth-logger/install
|
||||
# Auth monitor script
|
||||
$(INSTALL_DIR) $(1)/usr/lib/secubox
|
||||
$(INSTALL_BIN) ./files/auth-monitor.sh $(1)/usr/lib/secubox/
|
||||
|
||||
# Init script
|
||||
$(INSTALL_DIR) $(1)/etc/init.d
|
||||
$(INSTALL_BIN) ./files/secubox-auth-logger.init $(1)/etc/init.d/secubox-auth-logger
|
||||
$(INSTALL_BIN) ./files/secubox-app-auth-logger.init $(1)/etc/init.d/secubox-app-auth-logger
|
||||
|
||||
# RPCD plugin for auth logging via ubus
|
||||
$(INSTALL_DIR) $(1)/usr/libexec/rpcd
|
||||
@ -61,10 +62,6 @@ define Package/secubox-auth-logger/install
|
||||
$(INSTALL_DIR) $(1)/etc/crowdsec/parsers/s01-parse
|
||||
$(INSTALL_DATA) ./files/openwrt-luci-auth.yaml $(1)/etc/crowdsec/parsers/s01-parse/
|
||||
|
||||
# CrowdSec whitelist for private IPs (RFC1918)
|
||||
$(INSTALL_DIR) $(1)/etc/crowdsec/parsers/s02-enrich
|
||||
$(INSTALL_DATA) ./files/secubox-private-ip-whitelist.yaml $(1)/etc/crowdsec/parsers/s02-enrich/
|
||||
|
||||
# CrowdSec scenario
|
||||
$(INSTALL_DIR) $(1)/etc/crowdsec/scenarios
|
||||
$(INSTALL_DATA) ./files/openwrt-luci-bf.yaml $(1)/etc/crowdsec/scenarios/
|
||||
@ -75,28 +72,28 @@ define Package/secubox-auth-logger/install
|
||||
|
||||
# UCI defaults for first boot setup
|
||||
$(INSTALL_DIR) $(1)/etc/uci-defaults
|
||||
$(INSTALL_BIN) ./files/99-secubox-auth-logger $(1)/etc/uci-defaults/
|
||||
$(INSTALL_BIN) ./files/99-secubox-app-auth-logger $(1)/etc/uci-defaults/
|
||||
endef
|
||||
|
||||
define Package/secubox-auth-logger/postinst
|
||||
define Package/secubox-app-auth-logger/postinst
|
||||
#!/bin/sh
|
||||
[ -n "$${IPKG_INSTROOT}" ] || {
|
||||
# Restart rpcd to load new plugin
|
||||
/etc/init.d/rpcd restart 2>/dev/null
|
||||
|
||||
# Enable and start auth monitor
|
||||
/etc/init.d/secubox-auth-logger enable
|
||||
/etc/init.d/secubox-auth-logger start
|
||||
/etc/init.d/secubox-app-auth-logger enable
|
||||
/etc/init.d/secubox-app-auth-logger start
|
||||
|
||||
# Run uci-defaults to inject JS hook
|
||||
/etc/uci-defaults/99-secubox-auth-logger 2>/dev/null || true
|
||||
/etc/uci-defaults/99-secubox-app-auth-logger 2>/dev/null || true
|
||||
|
||||
echo "SecuBox Auth Logger installed - LuCI login failures now logged for CrowdSec"
|
||||
}
|
||||
exit 0
|
||||
endef
|
||||
|
||||
define Package/secubox-auth-logger/postrm
|
||||
define Package/secubox-app-auth-logger/postrm
|
||||
#!/bin/sh
|
||||
[ -n "$${IPKG_INSTROOT}" ] || {
|
||||
# Restore dispatcher from backup
|
||||
@ -127,4 +124,4 @@ define Package/secubox-auth-logger/postrm
|
||||
exit 0
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,secubox-auth-logger))
|
||||
$(eval $(call BuildPackage,secubox-app-auth-logger))
|
||||
@ -15,7 +15,7 @@ define Package/secubox-app-crowdsec-bouncer
|
||||
PKGARCH:=all
|
||||
SUBMENU:=SecuBox Apps
|
||||
TITLE:=SecuBox CrowdSec Firewall Bouncer wrapper
|
||||
DEPENDS:=+uci +libuci +crowdsec-firewall-bouncer +crowdsec +nftables
|
||||
DEPENDS:=+uci +libuci +secubox-app-cs-firewall-bouncer +crowdsec +nftables
|
||||
endef
|
||||
|
||||
define Package/secubox-app-crowdsec-bouncer/description
|
||||
|
||||
@ -3,18 +3,20 @@
|
||||
# Copyright (C) 2021-2022 Gerald Kerma <gandalf@gk2.net>
|
||||
# Copyright (C) 2024-2025 CyberMind.fr (SecuBox adaptation)
|
||||
#
|
||||
# CrowdSec Firewall Bouncer - nftables integration
|
||||
# SecuBox CrowdSec Firewall Bouncer - nftables integration
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=crowdsec-firewall-bouncer
|
||||
PKG_VERSION:=0.0.34
|
||||
PKG_NAME:=secubox-app-cs-firewall-bouncer
|
||||
PKG_VERSION:=0.0.31
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
# Source from upstream CrowdSec
|
||||
# Note: v0.0.31 is the last version compatible with Go 1.23 (OpenWrt 24.10 SDK)
|
||||
PKG_SOURCE:=crowdsec-firewall-bouncer-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=https://codeload.github.com/crowdsecurity/cs-firewall-bouncer/tar.gz/v$(PKG_VERSION)?
|
||||
PKG_HASH:=5c58f5cb9a8afc94520f62a39be290e8eea4c1a5bbacc5fea78ccfad9c8da232
|
||||
PKG_HASH:=c34963f0680ae296ae974d8f6444a2d1e2dd7617e7b05d4ad85c320529eec5f5
|
||||
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/cs-firewall-bouncer-$(PKG_VERSION)
|
||||
|
||||
@ -30,27 +32,30 @@ GO_PKG:=github.com/crowdsecurity/cs-firewall-bouncer
|
||||
|
||||
# Build version information
|
||||
GO_PKG_LDFLAGS_X:= \
|
||||
github.com/crowdsecurity/go-cs-lib/version.Tag=v$(PKG_VERSION)-openwrt \
|
||||
github.com/crowdsecurity/go-cs-lib/version.Tag=v$(PKG_VERSION)-secubox \
|
||||
github.com/crowdsecurity/go-cs-lib/version.Timestamp=$(SOURCE_DATE_EPOCH) \
|
||||
github.com/crowdsecurity/go-cs-lib/version.GoVersion=$(shell $(GO_STAGING_DIR)/bin/go version | cut -d" " -f3)
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
include $(TOPDIR)/feeds/packages/lang/golang/golang-package.mk
|
||||
|
||||
define Package/crowdsec-firewall-bouncer/Default
|
||||
define Package/secubox-app-cs-firewall-bouncer/Default
|
||||
SECTION:=net
|
||||
CATEGORY:=Network
|
||||
TITLE:=CrowdSec Firewall Bouncer
|
||||
SUBMENU:=SecuBox
|
||||
TITLE:=SecuBox CrowdSec Firewall Bouncer
|
||||
URL:=https://github.com/crowdsecurity/cs-firewall-bouncer
|
||||
endef
|
||||
|
||||
define Package/crowdsec-firewall-bouncer
|
||||
$(call Package/crowdsec-firewall-bouncer/Default)
|
||||
define Package/secubox-app-cs-firewall-bouncer
|
||||
$(call Package/secubox-app-cs-firewall-bouncer/Default)
|
||||
DEPENDS:=$(GO_ARCH_DEPENDS) +nftables
|
||||
PROVIDES:=crowdsec-firewall-bouncer
|
||||
CONFLICTS:=crowdsec-firewall-bouncer
|
||||
endef
|
||||
|
||||
define Package/crowdsec-firewall-bouncer/description
|
||||
CrowdSec Firewall Bouncer for OpenWrt/SecuBox.
|
||||
define Package/secubox-app-cs-firewall-bouncer/description
|
||||
SecuBox CrowdSec Firewall Bouncer for OpenWrt.
|
||||
|
||||
Fetches decisions from CrowdSec Local API and enforces them
|
||||
using nftables. Supports both IPv4 and IPv6 blocking with
|
||||
@ -61,15 +66,15 @@ define Package/crowdsec-firewall-bouncer/description
|
||||
- IPv4 and IPv6 support
|
||||
- Input and forward chain filtering
|
||||
- Interface-based filtering
|
||||
- Automatic cleanup on stop
|
||||
- Automatic restart on firewall reload
|
||||
- procd service management
|
||||
endef
|
||||
|
||||
define Package/crowdsec-firewall-bouncer/conffiles
|
||||
define Package/secubox-app-cs-firewall-bouncer/conffiles
|
||||
/etc/config/crowdsec
|
||||
endef
|
||||
|
||||
define Package/crowdsec-firewall-bouncer/install
|
||||
define Package/secubox-app-cs-firewall-bouncer/install
|
||||
$(call GoPackage/Package/Install/Bin,$(1))
|
||||
|
||||
$(INSTALL_DIR) $(1)/etc/config
|
||||
@ -77,7 +82,11 @@ define Package/crowdsec-firewall-bouncer/install
|
||||
|
||||
$(INSTALL_DIR) $(1)/etc/init.d
|
||||
$(INSTALL_BIN) ./files/crowdsec-firewall-bouncer.initd $(1)/etc/init.d/crowdsec-firewall-bouncer
|
||||
|
||||
# Hotplug script to restart bouncer when firewall reloads
|
||||
$(INSTALL_DIR) $(1)/etc/hotplug.d/iface
|
||||
$(INSTALL_DATA) ./files/hotplug.d/99-crowdsec-bouncer $(1)/etc/hotplug.d/iface/99-crowdsec-bouncer
|
||||
endef
|
||||
|
||||
$(eval $(call GoBinPackage,crowdsec-firewall-bouncer))
|
||||
$(eval $(call BuildPackage,crowdsec-firewall-bouncer))
|
||||
$(eval $(call GoBinPackage,secubox-app-cs-firewall-bouncer))
|
||||
$(eval $(call BuildPackage,secubox-app-cs-firewall-bouncer))
|
||||
@ -7,6 +7,7 @@
|
||||
USE_PROCD=1
|
||||
|
||||
START=99
|
||||
STOP=10
|
||||
|
||||
NAME=crowdsec-firewall-bouncer
|
||||
PROG=/usr/bin/cs-firewall-bouncer
|
||||
@ -21,6 +22,8 @@ TABLE6="crowdsec6"
|
||||
service_triggers() {
|
||||
procd_add_reload_trigger crowdsec-firewall-bouncer
|
||||
procd_add_config_trigger "config.change" "crowdsec" /etc/init.d/crowdsec-firewall-bouncer reload
|
||||
# Restart bouncer when firewall reloads to re-apply nftables rules
|
||||
procd_add_reload_trigger firewall
|
||||
}
|
||||
|
||||
init_yaml() {
|
||||
@ -235,19 +238,37 @@ run_bouncer() {
|
||||
procd_set_param stderr 1
|
||||
procd_set_param nice 10
|
||||
|
||||
# Use ujail if available for security isolation
|
||||
if [ -x "/sbin/ujail" ]; then
|
||||
procd_add_jail cs-bouncer log
|
||||
procd_add_jail_mount $VARCONFIG
|
||||
procd_add_jail_mount_rw /var/log/
|
||||
procd_set_param no_new_privs 1
|
||||
fi
|
||||
# Note: ujail disabled - bouncer needs direct nftables access
|
||||
# to add/remove IPs from sets which requires CAP_NET_ADMIN
|
||||
# if [ -x "/sbin/ujail" ]; then
|
||||
# procd_add_jail cs-bouncer log
|
||||
# procd_add_jail_mount $VARCONFIG
|
||||
# procd_add_jail_mount_rw /var/log/
|
||||
# procd_set_param no_new_privs 1
|
||||
# fi
|
||||
|
||||
procd_close_instance
|
||||
fi
|
||||
}
|
||||
|
||||
wait_for_firewall() {
|
||||
# Wait for fw4/nftables to be ready (max 30 seconds)
|
||||
local i=0
|
||||
while [ $i -lt 30 ]; do
|
||||
if nft list tables >/dev/null 2>&1; then
|
||||
return 0
|
||||
fi
|
||||
sleep 1
|
||||
i=$((i + 1))
|
||||
done
|
||||
logger -t crowdsec-bouncer "Warning: nftables not ready after 30s, starting anyway"
|
||||
return 1
|
||||
}
|
||||
|
||||
start_service() {
|
||||
# Wait for firewall/nftables to be ready
|
||||
wait_for_firewall
|
||||
|
||||
config_load "${CONFIGURATION}"
|
||||
config_foreach run_bouncer bouncer
|
||||
}
|
||||
@ -0,0 +1,31 @@
|
||||
#!/bin/sh
|
||||
# CrowdSec Firewall Bouncer - Interface/Firewall hotplug handler
|
||||
# Ensures bouncer's nftables rules are applied after network/firewall changes
|
||||
|
||||
# Only act on interface up events for WAN
|
||||
[ "$ACTION" = "ifup" ] || exit 0
|
||||
[ "$INTERFACE" = "wan" ] || [ "$INTERFACE" = "wan6" ] || exit 0
|
||||
|
||||
# Check if bouncer is enabled
|
||||
. /lib/functions.sh
|
||||
config_load crowdsec
|
||||
|
||||
is_enabled() {
|
||||
local section="$1"
|
||||
local enabled
|
||||
config_get_bool enabled "$section" enabled 0
|
||||
[ "$enabled" -eq 1 ] && return 0
|
||||
return 1
|
||||
}
|
||||
|
||||
bouncer_enabled=0
|
||||
config_foreach is_enabled bouncer && bouncer_enabled=1
|
||||
|
||||
[ "$bouncer_enabled" -eq 1 ] || exit 0
|
||||
|
||||
# Check if crowdsec tables exist - if not, bouncer needs restart
|
||||
if ! nft list table ip crowdsec >/dev/null 2>&1; then
|
||||
logger -t crowdsec-bouncer "WAN up but crowdsec nftables missing, restarting bouncer"
|
||||
sleep 2
|
||||
/etc/init.d/crowdsec-firewall-bouncer restart
|
||||
fi
|
||||
@ -1,17 +0,0 @@
|
||||
# CrowdSec Whitelist for Private IP Ranges
|
||||
# Prevents blocking of internal network addresses (RFC1918)
|
||||
# These IPs should never be banned as they are local network devices
|
||||
|
||||
name: secubox/private-ip-whitelist
|
||||
description: "Whitelist private/internal IP ranges to prevent self-blocking"
|
||||
whitelist:
|
||||
reason: "Private IP addresses (RFC1918) - local network devices"
|
||||
ip:
|
||||
- "127.0.0.0/8" # Localhost
|
||||
- "10.0.0.0/8" # Class A private
|
||||
- "172.16.0.0/12" # Class B private
|
||||
- "192.168.0.0/16" # Class C private
|
||||
- "169.254.0.0/16" # Link-local
|
||||
- "::1/128" # IPv6 localhost
|
||||
- "fe80::/10" # IPv6 link-local
|
||||
- "fc00::/7" # IPv6 unique local
|
||||
@ -1,53 +0,0 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
#
|
||||
# SecuBox CrowdSec Setup Package
|
||||
# Copyright (C) 2025 CyberMind.fr - Gandalf <gandalf@gk2.net>
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=secubox-crowdsec-setup
|
||||
PKG_VERSION:=1.0.0
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_MAINTAINER:=Gerald Kerma <gandalf@gk2.net>
|
||||
PKG_LICENSE:=MIT
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/secubox-crowdsec-setup
|
||||
SECTION:=secubox
|
||||
CATEGORY:=SecuBox
|
||||
SUBMENU:=Security
|
||||
TITLE:=SecuBox CrowdSec Setup Utility
|
||||
DEPENDS:=+crowdsec +crowdsec-firewall-bouncer +syslog-ng
|
||||
PKGARCH:=all
|
||||
endef
|
||||
|
||||
define Package/secubox-crowdsec-setup/description
|
||||
Script d'installation automatisee de CrowdSec pour SecuBox.
|
||||
Configure syslog-ng pour le forwarding des logs vers CrowdSec,
|
||||
installe les collections de securite, et configure le bouncer
|
||||
nftables pour fw4.
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
endef
|
||||
|
||||
define Package/secubox-crowdsec-setup/install
|
||||
$(INSTALL_DIR) $(1)/usr/sbin
|
||||
$(INSTALL_BIN) ./files/usr/sbin/secubox-crowdsec-setup $(1)/usr/sbin/
|
||||
|
||||
$(INSTALL_DIR) $(1)/etc/secubox/backups/crowdsec
|
||||
endef
|
||||
|
||||
define Package/secubox-crowdsec-setup/postinst
|
||||
#!/bin/sh
|
||||
[ -n "$${IPKG_INSTROOT}" ] || {
|
||||
echo "SecuBox CrowdSec Setup installe."
|
||||
echo "Executez 'secubox-crowdsec-setup' pour configurer CrowdSec."
|
||||
}
|
||||
exit 0
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,secubox-crowdsec-setup))
|
||||
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user