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_NAME:=luci-app-crowdsec-dashboard
|
||||||
PKG_VERSION:=0.7.0
|
PKG_VERSION:=0.7.0
|
||||||
PKG_RELEASE:=27
|
PKG_RELEASE:=28
|
||||||
PKG_ARCH:=all
|
PKG_ARCH:=all
|
||||||
|
|
||||||
PKG_LICENSE:=Apache-2.0
|
PKG_LICENSE:=Apache-2.0
|
||||||
|
|||||||
@ -526,6 +526,7 @@ return view.extend({
|
|||||||
]),
|
]),
|
||||||
|
|
||||||
E('div', { 'class': 'cs-charts-row' }, [
|
E('div', { 'class': 'cs-charts-row' }, [
|
||||||
|
this.renderFirewallHealth(),
|
||||||
this.renderFirewallBlocks()
|
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
|
// Firewall Blocks - Shows IPs blocked in nftables
|
||||||
renderFirewallBlocks: function() {
|
renderFirewallBlocks: function() {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|||||||
@ -947,6 +947,86 @@ get_nftables_stats() {
|
|||||||
json_add_int "ipv6_cscli_count" "$ipv6_cscli"
|
json_add_int "ipv6_cscli_count" "$ipv6_cscli"
|
||||||
json_add_int "ipv6_total_count" "$((ipv6_capi + 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
|
json_dump
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -11,7 +11,7 @@ PKG_VERSION:=1.0.0
|
|||||||
PKG_RELEASE:=1
|
PKG_RELEASE:=1
|
||||||
|
|
||||||
LUCI_TITLE:=LuCI SecuBox CrowdSec Dashboard
|
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
|
LUCI_PKGARCH:=all
|
||||||
|
|
||||||
PKG_MAINTAINER:=Gerald Kerma <gandalf@gk2.net>
|
PKG_MAINTAINER:=Gerald Kerma <gandalf@gk2.net>
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
include $(TOPDIR)/rules.mk
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
PKG_NAME:=secubox-auth-logger
|
PKG_NAME:=secubox-app-auth-logger
|
||||||
PKG_VERSION:=1.2.2
|
PKG_VERSION:=1.2.2
|
||||||
PKG_RELEASE:=1
|
PKG_RELEASE:=1
|
||||||
PKG_ARCH:=all
|
PKG_ARCH:=all
|
||||||
@ -12,15 +12,16 @@ PKG_MAINTAINER:=CyberMind <contact@cybermind.fr>
|
|||||||
|
|
||||||
include $(INCLUDE_DIR)/package.mk
|
include $(INCLUDE_DIR)/package.mk
|
||||||
|
|
||||||
define Package/secubox-auth-logger
|
define Package/secubox-app-auth-logger
|
||||||
SECTION:=secubox
|
SECTION:=secubox
|
||||||
CATEGORY:=SecuBox
|
CATEGORY:=SecuBox
|
||||||
TITLE:=Authentication Failure Logger for CrowdSec
|
TITLE:=Authentication Failure Logger for CrowdSec
|
||||||
DEPENDS:=+rpcd +uhttpd +libubox-lua
|
DEPENDS:=+rpcd +uhttpd +libubox-lua
|
||||||
PKGARCH:=all
|
PKGARCH:=all
|
||||||
|
PROVIDES:=secubox-auth-logger
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define Package/secubox-auth-logger/description
|
define Package/secubox-app-auth-logger/description
|
||||||
Logs authentication failures from LuCI/rpcd and Dropbear SSH
|
Logs authentication failures from LuCI/rpcd and Dropbear SSH
|
||||||
for CrowdSec detection. Includes:
|
for CrowdSec detection. Includes:
|
||||||
- SSH failure monitoring (OpenSSH/Dropbear)
|
- SSH failure monitoring (OpenSSH/Dropbear)
|
||||||
@ -32,14 +33,14 @@ endef
|
|||||||
define Build/Compile
|
define Build/Compile
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define Package/secubox-auth-logger/install
|
define Package/secubox-app-auth-logger/install
|
||||||
# Auth monitor script
|
# Auth monitor script
|
||||||
$(INSTALL_DIR) $(1)/usr/lib/secubox
|
$(INSTALL_DIR) $(1)/usr/lib/secubox
|
||||||
$(INSTALL_BIN) ./files/auth-monitor.sh $(1)/usr/lib/secubox/
|
$(INSTALL_BIN) ./files/auth-monitor.sh $(1)/usr/lib/secubox/
|
||||||
|
|
||||||
# Init script
|
# Init script
|
||||||
$(INSTALL_DIR) $(1)/etc/init.d
|
$(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
|
# RPCD plugin for auth logging via ubus
|
||||||
$(INSTALL_DIR) $(1)/usr/libexec/rpcd
|
$(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_DIR) $(1)/etc/crowdsec/parsers/s01-parse
|
||||||
$(INSTALL_DATA) ./files/openwrt-luci-auth.yaml $(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
|
# CrowdSec scenario
|
||||||
$(INSTALL_DIR) $(1)/etc/crowdsec/scenarios
|
$(INSTALL_DIR) $(1)/etc/crowdsec/scenarios
|
||||||
$(INSTALL_DATA) ./files/openwrt-luci-bf.yaml $(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
|
# UCI defaults for first boot setup
|
||||||
$(INSTALL_DIR) $(1)/etc/uci-defaults
|
$(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
|
endef
|
||||||
|
|
||||||
define Package/secubox-auth-logger/postinst
|
define Package/secubox-app-auth-logger/postinst
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
[ -n "$${IPKG_INSTROOT}" ] || {
|
[ -n "$${IPKG_INSTROOT}" ] || {
|
||||||
# Restart rpcd to load new plugin
|
# Restart rpcd to load new plugin
|
||||||
/etc/init.d/rpcd restart 2>/dev/null
|
/etc/init.d/rpcd restart 2>/dev/null
|
||||||
|
|
||||||
# Enable and start auth monitor
|
# Enable and start auth monitor
|
||||||
/etc/init.d/secubox-auth-logger enable
|
/etc/init.d/secubox-app-auth-logger enable
|
||||||
/etc/init.d/secubox-auth-logger start
|
/etc/init.d/secubox-app-auth-logger start
|
||||||
|
|
||||||
# Run uci-defaults to inject JS hook
|
# 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"
|
echo "SecuBox Auth Logger installed - LuCI login failures now logged for CrowdSec"
|
||||||
}
|
}
|
||||||
exit 0
|
exit 0
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define Package/secubox-auth-logger/postrm
|
define Package/secubox-app-auth-logger/postrm
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
[ -n "$${IPKG_INSTROOT}" ] || {
|
[ -n "$${IPKG_INSTROOT}" ] || {
|
||||||
# Restore dispatcher from backup
|
# Restore dispatcher from backup
|
||||||
@ -127,4 +124,4 @@ define Package/secubox-auth-logger/postrm
|
|||||||
exit 0
|
exit 0
|
||||||
endef
|
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
|
PKGARCH:=all
|
||||||
SUBMENU:=SecuBox Apps
|
SUBMENU:=SecuBox Apps
|
||||||
TITLE:=SecuBox CrowdSec Firewall Bouncer wrapper
|
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
|
endef
|
||||||
|
|
||||||
define Package/secubox-app-crowdsec-bouncer/description
|
define Package/secubox-app-crowdsec-bouncer/description
|
||||||
|
|||||||
@ -3,18 +3,20 @@
|
|||||||
# Copyright (C) 2021-2022 Gerald Kerma <gandalf@gk2.net>
|
# Copyright (C) 2021-2022 Gerald Kerma <gandalf@gk2.net>
|
||||||
# Copyright (C) 2024-2025 CyberMind.fr (SecuBox adaptation)
|
# Copyright (C) 2024-2025 CyberMind.fr (SecuBox adaptation)
|
||||||
#
|
#
|
||||||
# CrowdSec Firewall Bouncer - nftables integration
|
# SecuBox CrowdSec Firewall Bouncer - nftables integration
|
||||||
#
|
#
|
||||||
|
|
||||||
include $(TOPDIR)/rules.mk
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
PKG_NAME:=crowdsec-firewall-bouncer
|
PKG_NAME:=secubox-app-cs-firewall-bouncer
|
||||||
PKG_VERSION:=0.0.34
|
PKG_VERSION:=0.0.31
|
||||||
PKG_RELEASE:=1
|
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_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)
|
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
|
# Build version information
|
||||||
GO_PKG_LDFLAGS_X:= \
|
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.Timestamp=$(SOURCE_DATE_EPOCH) \
|
||||||
github.com/crowdsecurity/go-cs-lib/version.GoVersion=$(shell $(GO_STAGING_DIR)/bin/go version | cut -d" " -f3)
|
github.com/crowdsecurity/go-cs-lib/version.GoVersion=$(shell $(GO_STAGING_DIR)/bin/go version | cut -d" " -f3)
|
||||||
|
|
||||||
include $(INCLUDE_DIR)/package.mk
|
include $(INCLUDE_DIR)/package.mk
|
||||||
include $(TOPDIR)/feeds/packages/lang/golang/golang-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
|
SECTION:=net
|
||||||
CATEGORY:=Network
|
CATEGORY:=Network
|
||||||
TITLE:=CrowdSec Firewall Bouncer
|
SUBMENU:=SecuBox
|
||||||
|
TITLE:=SecuBox CrowdSec Firewall Bouncer
|
||||||
URL:=https://github.com/crowdsecurity/cs-firewall-bouncer
|
URL:=https://github.com/crowdsecurity/cs-firewall-bouncer
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define Package/crowdsec-firewall-bouncer
|
define Package/secubox-app-cs-firewall-bouncer
|
||||||
$(call Package/crowdsec-firewall-bouncer/Default)
|
$(call Package/secubox-app-cs-firewall-bouncer/Default)
|
||||||
DEPENDS:=$(GO_ARCH_DEPENDS) +nftables
|
DEPENDS:=$(GO_ARCH_DEPENDS) +nftables
|
||||||
|
PROVIDES:=crowdsec-firewall-bouncer
|
||||||
|
CONFLICTS:=crowdsec-firewall-bouncer
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define Package/crowdsec-firewall-bouncer/description
|
define Package/secubox-app-cs-firewall-bouncer/description
|
||||||
CrowdSec Firewall Bouncer for OpenWrt/SecuBox.
|
SecuBox CrowdSec Firewall Bouncer for OpenWrt.
|
||||||
|
|
||||||
Fetches decisions from CrowdSec Local API and enforces them
|
Fetches decisions from CrowdSec Local API and enforces them
|
||||||
using nftables. Supports both IPv4 and IPv6 blocking with
|
using nftables. Supports both IPv4 and IPv6 blocking with
|
||||||
@ -61,15 +66,15 @@ define Package/crowdsec-firewall-bouncer/description
|
|||||||
- IPv4 and IPv6 support
|
- IPv4 and IPv6 support
|
||||||
- Input and forward chain filtering
|
- Input and forward chain filtering
|
||||||
- Interface-based filtering
|
- Interface-based filtering
|
||||||
- Automatic cleanup on stop
|
- Automatic restart on firewall reload
|
||||||
- procd service management
|
- procd service management
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define Package/crowdsec-firewall-bouncer/conffiles
|
define Package/secubox-app-cs-firewall-bouncer/conffiles
|
||||||
/etc/config/crowdsec
|
/etc/config/crowdsec
|
||||||
endef
|
endef
|
||||||
|
|
||||||
define Package/crowdsec-firewall-bouncer/install
|
define Package/secubox-app-cs-firewall-bouncer/install
|
||||||
$(call GoPackage/Package/Install/Bin,$(1))
|
$(call GoPackage/Package/Install/Bin,$(1))
|
||||||
|
|
||||||
$(INSTALL_DIR) $(1)/etc/config
|
$(INSTALL_DIR) $(1)/etc/config
|
||||||
@ -77,7 +82,11 @@ define Package/crowdsec-firewall-bouncer/install
|
|||||||
|
|
||||||
$(INSTALL_DIR) $(1)/etc/init.d
|
$(INSTALL_DIR) $(1)/etc/init.d
|
||||||
$(INSTALL_BIN) ./files/crowdsec-firewall-bouncer.initd $(1)/etc/init.d/crowdsec-firewall-bouncer
|
$(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
|
endef
|
||||||
|
|
||||||
$(eval $(call GoBinPackage,crowdsec-firewall-bouncer))
|
$(eval $(call GoBinPackage,secubox-app-cs-firewall-bouncer))
|
||||||
$(eval $(call BuildPackage,crowdsec-firewall-bouncer))
|
$(eval $(call BuildPackage,secubox-app-cs-firewall-bouncer))
|
||||||
@ -7,6 +7,7 @@
|
|||||||
USE_PROCD=1
|
USE_PROCD=1
|
||||||
|
|
||||||
START=99
|
START=99
|
||||||
|
STOP=10
|
||||||
|
|
||||||
NAME=crowdsec-firewall-bouncer
|
NAME=crowdsec-firewall-bouncer
|
||||||
PROG=/usr/bin/cs-firewall-bouncer
|
PROG=/usr/bin/cs-firewall-bouncer
|
||||||
@ -21,6 +22,8 @@ TABLE6="crowdsec6"
|
|||||||
service_triggers() {
|
service_triggers() {
|
||||||
procd_add_reload_trigger crowdsec-firewall-bouncer
|
procd_add_reload_trigger crowdsec-firewall-bouncer
|
||||||
procd_add_config_trigger "config.change" "crowdsec" /etc/init.d/crowdsec-firewall-bouncer reload
|
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() {
|
init_yaml() {
|
||||||
@ -235,19 +238,37 @@ run_bouncer() {
|
|||||||
procd_set_param stderr 1
|
procd_set_param stderr 1
|
||||||
procd_set_param nice 10
|
procd_set_param nice 10
|
||||||
|
|
||||||
# Use ujail if available for security isolation
|
# Note: ujail disabled - bouncer needs direct nftables access
|
||||||
if [ -x "/sbin/ujail" ]; then
|
# to add/remove IPs from sets which requires CAP_NET_ADMIN
|
||||||
procd_add_jail cs-bouncer log
|
# if [ -x "/sbin/ujail" ]; then
|
||||||
procd_add_jail_mount $VARCONFIG
|
# procd_add_jail cs-bouncer log
|
||||||
procd_add_jail_mount_rw /var/log/
|
# procd_add_jail_mount $VARCONFIG
|
||||||
procd_set_param no_new_privs 1
|
# procd_add_jail_mount_rw /var/log/
|
||||||
fi
|
# procd_set_param no_new_privs 1
|
||||||
|
# fi
|
||||||
|
|
||||||
procd_close_instance
|
procd_close_instance
|
||||||
fi
|
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() {
|
start_service() {
|
||||||
|
# Wait for firewall/nftables to be ready
|
||||||
|
wait_for_firewall
|
||||||
|
|
||||||
config_load "${CONFIGURATION}"
|
config_load "${CONFIGURATION}"
|
||||||
config_foreach run_bouncer bouncer
|
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