diff --git a/package/secubox/secubox-app-crowdsec-custom/Makefile b/package/secubox/secubox-app-crowdsec-custom/Makefile new file mode 100644 index 0000000..cd160fb --- /dev/null +++ b/package/secubox/secubox-app-crowdsec-custom/Makefile @@ -0,0 +1,113 @@ +# Copyright (C) 2024-2025 CyberMind.fr +# Licensed under Apache-2.0 + +include $(TOPDIR)/rules.mk + +PKG_NAME:=secubox-app-crowdsec-custom +PKG_VERSION:=1.0.0 +PKG_RELEASE:=1 +PKG_ARCH:=all +PKG_LICENSE:=Apache-2.0 +PKG_MAINTAINER:=CyberMind + +include $(INCLUDE_DIR)/package.mk + +define Package/secubox-app-crowdsec-custom + SECTION:=secubox + CATEGORY:=SecuBox + TITLE:=CrowdSec Custom Scenarios for SecuBox + DEPENDS:=+crowdsec +crowdsec-firewall-bouncer + PKGARCH:=all + PROVIDES:=secubox-crowdsec-custom +endef + +define Package/secubox-app-crowdsec-custom/description + Custom CrowdSec configurations for SecuBox web interface protection. + Includes: + - HTTP authentication bruteforce detection + - Path scanning/enumeration detection + - LuCI/uhttpd auth failure monitoring + - Nginx reverse proxy monitoring (if used) + - Whitelist for trusted networks +endef + +define Build/Compile +endef + +define Package/secubox-app-crowdsec-custom/install + # Acquisition configs + $(INSTALL_DIR) $(1)/etc/crowdsec/acquis.d + $(INSTALL_DATA) ./files/acquis.d/secubox-uhttpd.yaml $(1)/etc/crowdsec/acquis.d/ + $(INSTALL_DATA) ./files/acquis.d/secubox-nginx.yaml $(1)/etc/crowdsec/acquis.d/ + $(INSTALL_DATA) ./files/acquis.d/secubox-auth.yaml $(1)/etc/crowdsec/acquis.d/ + + # Custom parsers + $(INSTALL_DIR) $(1)/etc/crowdsec/parsers/s01-parse + $(INSTALL_DATA) ./files/parsers/s01-parse/secubox-luci-auth.yaml $(1)/etc/crowdsec/parsers/s01-parse/ + + $(INSTALL_DIR) $(1)/etc/crowdsec/parsers/s02-enrich + $(INSTALL_DATA) ./files/parsers/s02-enrich/secubox-whitelist.yaml $(1)/etc/crowdsec/parsers/s02-enrich/ + + # Custom scenarios + $(INSTALL_DIR) $(1)/etc/crowdsec/scenarios + $(INSTALL_DATA) ./files/scenarios/secubox-auth-bruteforce.yaml $(1)/etc/crowdsec/scenarios/ + $(INSTALL_DATA) ./files/scenarios/secubox-http-bruteforce.yaml $(1)/etc/crowdsec/scenarios/ + + # UCI defaults for first boot setup + $(INSTALL_DIR) $(1)/etc/uci-defaults + $(INSTALL_BIN) ./files/99-secubox-app-crowdsec-custom $(1)/etc/uci-defaults/ +endef + +define Package/secubox-app-crowdsec-custom/postinst +#!/bin/sh +[ -n "$${IPKG_INSTROOT}" ] || { + echo "Installing CrowdSec collections for SecuBox..." + + # Install standard collections + cscli collections install crowdsecurity/linux 2>/dev/null || true + cscli collections install crowdsecurity/sshd 2>/dev/null || true + cscli collections install crowdsecurity/base-http-scenarios 2>/dev/null || true + cscli collections install crowdsecurity/http-cve 2>/dev/null || true + cscli collections install crowdsecurity/nginx 2>/dev/null || true + cscli collections install crowdsecurity/http-dos 2>/dev/null || true + + # Install parsers + cscli parsers install crowdsecurity/syslog-logs 2>/dev/null || true + cscli parsers install crowdsecurity/http-logs 2>/dev/null || true + cscli parsers install crowdsecurity/nginx-logs 2>/dev/null || true + + # Run uci-defaults + /etc/uci-defaults/99-secubox-app-crowdsec-custom 2>/dev/null || true + + # Restart CrowdSec to load new configs + /etc/init.d/crowdsec restart 2>/dev/null || true + sleep 2 + + # Restart bouncer + if [ -f /etc/init.d/crowdsec-firewall-bouncer ]; then + /etc/init.d/crowdsec-firewall-bouncer restart 2>/dev/null || true + fi + + echo "" + echo "SecuBox CrowdSec protection installed!" + echo "Protected paths: /secubox/, /cgi-bin/luci, /ubus" + echo "" + echo "Useful commands:" + echo " cscli metrics - View detection metrics" + echo " cscli alerts list - View security alerts" + echo " cscli decisions list - View active bans" +} +exit 0 +endef + +define Package/secubox-app-crowdsec-custom/postrm +#!/bin/sh +[ -n "$${IPKG_INSTROOT}" ] || { + # Restart CrowdSec to unload configs + /etc/init.d/crowdsec restart 2>/dev/null || true + echo "SecuBox CrowdSec custom configs removed" +} +exit 0 +endef + +$(eval $(call BuildPackage,secubox-app-crowdsec-custom)) diff --git a/package/secubox/secubox-app-crowdsec-custom/files/99-secubox-app-crowdsec-custom b/package/secubox/secubox-app-crowdsec-custom/files/99-secubox-app-crowdsec-custom new file mode 100644 index 0000000..d9dc4e4 --- /dev/null +++ b/package/secubox/secubox-app-crowdsec-custom/files/99-secubox-app-crowdsec-custom @@ -0,0 +1,36 @@ +#!/bin/sh +# SecuBox CrowdSec Custom - First boot setup +# Configures logging for CrowdSec monitoring + +# Enable uhttpd syslog logging +if command -v uci >/dev/null 2>&1; then + uci set uhttpd.main.syslog='1' 2>/dev/null + uci commit uhttpd 2>/dev/null +fi + +# Ensure syslog writes to file for CrowdSec +if [ -f /etc/config/system ]; then + uci set system.@system[0].log_file='/var/log/messages' 2>/dev/null + uci set system.@system[0].log_size='512' 2>/dev/null + uci commit system 2>/dev/null +fi + +# Restart logging service +/etc/init.d/log restart 2>/dev/null || true + +# Restart uhttpd to apply logging changes +/etc/init.d/uhttpd restart 2>/dev/null || true + +# Register firewall bouncer if not already registered +if [ -f /etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml ]; then + if command -v cscli >/dev/null 2>&1; then + if ! cscli bouncers list 2>/dev/null | grep -q "firewall-bouncer"; then + API_KEY=$(cscli bouncers add firewall-bouncer -o raw 2>/dev/null) + if [ -n "$API_KEY" ]; then + sed -i "s/^api_key:.*/api_key: $API_KEY/" /etc/crowdsec/bouncers/crowdsec-firewall-bouncer.yaml + fi + fi + fi +fi + +exit 0 diff --git a/package/secubox/secubox-app-crowdsec-custom/files/acquis.d/secubox-auth.yaml b/package/secubox/secubox-app-crowdsec-custom/files/acquis.d/secubox-auth.yaml new file mode 100644 index 0000000..f8b13a0 --- /dev/null +++ b/package/secubox/secubox-app-crowdsec-custom/files/acquis.d/secubox-auth.yaml @@ -0,0 +1,17 @@ +# CrowdSec acquisition for SecuBox/LuCI authentication +# Monitors syslog for auth failures + +# Monitor OpenWrt syslog +source: file +filenames: + - /var/log/messages + - /tmp/log/messages +labels: + type: syslog +--- +# Monitor auth.log if available +source: file +filenames: + - /var/log/auth.log +labels: + type: syslog diff --git a/package/secubox/secubox-app-crowdsec-custom/files/acquis.d/secubox-nginx.yaml b/package/secubox/secubox-app-crowdsec-custom/files/acquis.d/secubox-nginx.yaml new file mode 100644 index 0000000..98d6727 --- /dev/null +++ b/package/secubox/secubox-app-crowdsec-custom/files/acquis.d/secubox-nginx.yaml @@ -0,0 +1,9 @@ +# CrowdSec acquisition for nginx reverse proxy (if used) +# Monitors nginx logs for web attacks + +filenames: + - /var/log/nginx/access.log + - /var/log/nginx/error.log + - /var/log/nginx/*access*.log +labels: + type: nginx diff --git a/package/secubox/secubox-app-crowdsec-custom/files/acquis.d/secubox-uhttpd.yaml b/package/secubox/secubox-app-crowdsec-custom/files/acquis.d/secubox-uhttpd.yaml new file mode 100644 index 0000000..c5c24be --- /dev/null +++ b/package/secubox/secubox-app-crowdsec-custom/files/acquis.d/secubox-uhttpd.yaml @@ -0,0 +1,8 @@ +# CrowdSec acquisition for SecuBox web interface (uhttpd) +# Monitors uhttpd logs for web attacks + +filenames: + - /var/log/uhttpd.log + - /tmp/log/uhttpd.log +labels: + type: syslog diff --git a/package/secubox/secubox-app-crowdsec-custom/files/parsers/s01-parse/secubox-luci-auth.yaml b/package/secubox/secubox-app-crowdsec-custom/files/parsers/s01-parse/secubox-luci-auth.yaml new file mode 100644 index 0000000..cd1f985 --- /dev/null +++ b/package/secubox/secubox-app-crowdsec-custom/files/parsers/s01-parse/secubox-luci-auth.yaml @@ -0,0 +1,43 @@ +# CrowdSec parser for SecuBox/LuCI authentication logs +# Parses authentication events from uhttpd, luci, and rpcd + +onsuccess: next_stage +name: secubox/luci-auth-logs +description: "Parse SecuBox/LuCI authentication events" +filter: "evt.Parsed.program == 'uhttpd' || evt.Parsed.program == 'luci' || evt.Parsed.program == 'rpcd'" +grok: + pattern: "%{GREEDYDATA:message}" + apply_on: message +statics: + - meta: log_type + value: luci_auth + - meta: service + value: secubox +--- +# Parse LuCI login failures +onsuccess: next_stage +name: secubox/luci-auth-failure +description: "Parse LuCI authentication failures" +filter: "evt.Parsed.program == 'luci' && evt.Parsed.message contains 'auth'" +grok: + pattern: "luci: %{WORD:action} from %{IP:source_ip}.*(?:failed|denied|invalid)" + apply_on: message +statics: + - meta: auth_success + value: "false" + - meta: source_ip + expression: evt.Parsed.source_ip +--- +# Parse uhttpd/rpcd auth attempts +onsuccess: next_stage +name: secubox/uhttpd-auth +description: "Parse uhttpd authentication events" +filter: "evt.Parsed.program == 'uhttpd' || evt.Parsed.program == 'rpcd'" +grok: + pattern: "%{IP:source_ip}.*(?:login|auth|session).*(?:failed|denied|invalid|error)" + apply_on: message +statics: + - meta: auth_success + value: "false" + - meta: log_type + value: luci_auth diff --git a/package/secubox/secubox-app-crowdsec-custom/files/parsers/s02-enrich/secubox-whitelist.yaml b/package/secubox/secubox-app-crowdsec-custom/files/parsers/s02-enrich/secubox-whitelist.yaml new file mode 100644 index 0000000..55918db --- /dev/null +++ b/package/secubox/secubox-app-crowdsec-custom/files/parsers/s02-enrich/secubox-whitelist.yaml @@ -0,0 +1,18 @@ +# CrowdSec whitelist for SecuBox trusted networks +# Prevents banning of internal/trusted IPs + +name: crowdsecurity/secubox-whitelist +description: "Whitelist trusted IPs for SecuBox admin access" +whitelist: + reason: "SecuBox trusted network" + ip: + # Localhost + - "127.0.0.1" + - "::1" + cidr: + # Private networks (RFC1918) + - "192.168.0.0/16" + - "172.16.0.0/12" + - "10.0.0.0/8" + # Add custom admin IPs here if needed + # - "YOUR_ADMIN_IP/32" diff --git a/package/secubox/secubox-app-crowdsec-custom/files/scenarios/secubox-auth-bruteforce.yaml b/package/secubox/secubox-app-crowdsec-custom/files/scenarios/secubox-auth-bruteforce.yaml new file mode 100644 index 0000000..b0a19c4 --- /dev/null +++ b/package/secubox/secubox-app-crowdsec-custom/files/scenarios/secubox-auth-bruteforce.yaml @@ -0,0 +1,15 @@ +# CrowdSec scenario for SecuBox/LuCI authentication bruteforce +# Detects repeated authentication failures + +type: leaky +name: secubox/luci-auth-bruteforce +description: "Detect bruteforce attempts on SecuBox/LuCI web interface" +filter: "evt.Meta.log_type == 'luci_auth' && evt.Meta.auth_success == 'false'" +groupby: evt.Meta.source_ip +capacity: 5 +leakspeed: 30s +blackhole: 5m +labels: + service: secubox + type: bruteforce + remediation: true diff --git a/package/secubox/secubox-app-crowdsec-custom/files/scenarios/secubox-http-bruteforce.yaml b/package/secubox/secubox-app-crowdsec-custom/files/scenarios/secubox-http-bruteforce.yaml new file mode 100644 index 0000000..dd6896c --- /dev/null +++ b/package/secubox/secubox-app-crowdsec-custom/files/scenarios/secubox-http-bruteforce.yaml @@ -0,0 +1,39 @@ +# CrowdSec scenario for SecuBox HTTP authentication bruteforce +# Detects repeated 401/403 errors indicating auth failures + +type: leaky +name: secubox/http-auth-bruteforce +description: "Detect HTTP authentication bruteforce on SecuBox web interface" +filter: | + evt.Meta.http_status in ['401', '403'] && + evt.Parsed.request contains '/cgi-bin/luci' || + evt.Parsed.request contains '/secubox/' || + evt.Parsed.request contains '/ubus' +groupby: evt.Meta.source_ip +capacity: 5 +leakspeed: 30s +blackhole: 5m +labels: + service: secubox + type: http_bruteforce + remediation: true +--- +# Detect path scanning/enumeration +type: leaky +name: secubox/path-scanning +description: "Detect path scanning on SecuBox web interface" +filter: | + evt.Meta.http_status == '404' && + (evt.Parsed.request contains '/secubox/' || + evt.Parsed.request contains '/cgi-bin/' || + evt.Parsed.request contains '/admin' || + evt.Parsed.request contains '/wp-' || + evt.Parsed.request contains '.php') +groupby: evt.Meta.source_ip +capacity: 20 +leakspeed: 10s +blackhole: 10m +labels: + service: secubox + type: path_scan + remediation: true diff --git a/package/secubox/secubox-app-lyrion/files/etc/config/lyrion b/package/secubox/secubox-app-lyrion/files/etc/config/lyrion index 393d394..3e12742 100644 --- a/package/secubox/secubox-app-lyrion/files/etc/config/lyrion +++ b/package/secubox/secubox-app-lyrion/files/etc/config/lyrion @@ -1,7 +1,7 @@ config lyrion 'main' option enabled '0' option runtime 'auto' - option image 'ghcr.io/lyrion/lyrion:latest' + option image 'ghcr.io/lms-community/lyrionmusicserver:stable' option data_path '/srv/lyrion' option media_path '/srv/media' option port '9000' diff --git a/package/secubox/secubox-app-lyrion/files/usr/sbin/lyrionctl b/package/secubox/secubox-app-lyrion/files/usr/sbin/lyrionctl index 270df70..6446fc4 100755 --- a/package/secubox/secubox-app-lyrion/files/usr/sbin/lyrionctl +++ b/package/secubox/secubox-app-lyrion/files/usr/sbin/lyrionctl @@ -49,7 +49,7 @@ uci_set() { uci set ${CONFIG}.main.$1="$2" && uci commit ${CONFIG}; } # Load configuration with defaults load_config() { runtime="$(uci_get runtime || echo auto)" - image="$(uci_get image || echo ghcr.io/lyrion/lyrion:latest)" + image="$(uci_get image || echo ghcr.io/lms-community/lyrionmusicserver:stable)" data_path="$(uci_get data_path || echo /srv/lyrion)" media_path="$(uci_get media_path || echo /srv/media)" port="$(uci_get port || echo 9000)"