From 6dd5bbc2cea4b419887cc7f43eab8b30c128d0c7 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 21 Jul 2026 12:36:02 +0000 Subject: [PATCH 1/2] Include the check/unban commands directly in CrowdSec ntfy alerts Confirmed live: a legitimate SIP device on a CGNAT ISP (Starlink, T-Mobile home internet) got collaterally banned by crowdsecurity/asterisk_bf alongside actual bad actors sharing the same carrier IP. The alert now includes the exact commands (with the banned IP substituted in) instead of just naming the ban, so recovering from this doesn't require remembering or looking up cscli syntax. --- services/crowdsec.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/services/crowdsec.sh b/services/crowdsec.sh index f1e90f1..aeb451f 100644 --- a/services/crowdsec.sh +++ b/services/crowdsec.sh @@ -284,6 +284,8 @@ format: | {{range . -}} {{range .Decisions -}} {{.Value}} banned: {{.Scenario}} for {{.Duration}} + Check all bans: sudo cscli decisions list + Unban this IP: sudo cscli decisions delete --ip {{.Value}} {{end -}} {{end -}} url: $CS_NTFY_URL From c2d74f95206d182a223c86553c37209562a3fd1f Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 21 Jul 2026 12:47:48 +0000 Subject: [PATCH 2/2] Add optional ASN-exempt Asterisk brute-force scenarios to crowdsec.sh MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Confirmed live: a phone roaming WiFi<->mobile on a CGNAT carrier (Starlink, T-Mobile home internet) got banned by crowdsecurity/asterisk_bf, either from its own re-registration burst or collaterally from another customer sharing the same rotating public IP. Forks asterisk_bf and asterisk_user_enum locally with an ASN exclusion added to their filter, disabling the hub originals so events aren't double-processed. Scoped narrowly to Asterisk auth-failure detection only — SSH, web scanning, and the geo-allowlist scenario are all unaffected, so this doesn't broadly exempt the carrier from every protection on the box. --- services/crowdsec.sh | 92 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/services/crowdsec.sh b/services/crowdsec.sh index aeb451f..f21165f 100644 --- a/services/crowdsec.sh +++ b/services/crowdsec.sh @@ -185,6 +185,85 @@ labels: else echo " ✓ Asterisk acquisition already exists" fi + + # ── 5c. Optional: exempt specific carrier ASNs from Asterisk + # brute-force bans only (SSH/web/geo protection stays normal). Confirmed + # live: a phone on a CGNAT mobile/satellite carrier (Starlink, T-Mobile + # home internet) shares one public IP across many customers and rotates + # it — a device roaming WiFi<->mobile can get banned for someone else's + # brute-force attempt on that same shared IP, or for its own + # re-registration burst looking like one. This forks + # crowdsecurity/asterisk_bf and crowdsecurity/asterisk_user_enum + # locally with an ASN exclusion added to their filter, then disables + # the hub originals so there's no double-processing of the same events. + echo "" + local ASN_EXEMPT="" + prompt_yn "Exempt specific carrier ASNs from Asterisk brute-force bans only? (y/n):" "n" ASN_EXEMPT + if [ "$ASN_EXEMPT" = "y" ] || [ "$ASN_EXEMPT" = "Y" ]; then + sudo cscli collections install crowdsecurity/geoip-enrich 2>/dev/null || true + echo " ASNs observed live: T-Mobile 21928, Starlink 14593. A carrier can operate" + echo " more than one ASN — if the same carrier bans you again later under a" + echo " different number, check the AS column in 'cscli decisions list' and add it." + local ASN_LIST="" + prompt_text " ASN numbers to exempt, space-separated:" "21928 14593" ASN_LIST + if [ -n "$ASN_LIST" ]; then + local _asn_expr + _asn_expr="$(printf "%s, " $ASN_LIST)" + _asn_expr="${_asn_expr%, }" + + sudo mkdir -p /etc/crowdsec/scenarios + sudo tee /etc/crowdsec/scenarios/local-asterisk_bf.yaml > /dev/null << ASTBF +type: leaky +name: local/asterisk_bf +description: "Detect Asterisk user bruteforce (ASN-exempt fork of crowdsecurity/asterisk_bf)" +filter: "evt.Meta.log_type == 'asterisk_failed_auth' && !(evt.Enriched.ASNNumber in [${_asn_expr}])" +groupby: evt.Meta.source_ip +leakspeed: 10s +capacity: 5 +blackhole: 1m +labels: + service: asterisk + confidence: 3 + spoofable: 0 + classification: + - attack.T1110 + behavior: "sip:bruteforce" + label: "Asterisk Bruteforce" + remediation: true +ASTBF + + sudo tee /etc/crowdsec/scenarios/local-asterisk_user_enum.yaml > /dev/null << ASTENUM +type: leaky +name: local/asterisk_user_enum +description: "Detect Asterisk user enumeration bruteforce (ASN-exempt fork of crowdsecurity/asterisk_user_enum)" +filter: "evt.Meta.log_type == 'asterisk_failed_auth' && !(evt.Enriched.ASNNumber in [${_asn_expr}])" +groupby: evt.Meta.source_ip +distinct: evt.Meta.target_user +leakspeed: 10s +capacity: 5 +blackhole: 1m +labels: + service: asterisk + confidence: 3 + spoofable: 0 + classification: + - attack.T1087 + - attack.T1589.001 + - attack.T1110 + behavior: "sip:bruteforce" + label: "Asterisk User Enumeration" + remediation: true +ASTENUM + + # Disable the hub originals so they don't double-process the + # same events alongside the ASN-exempt forks written above. + sudo cscli scenarios remove crowdsecurity/asterisk_bf crowdsecurity/asterisk_user_enum 2>/dev/null || true + echo " ✓ Wrote ASN-exempt local forks; disabled the hub originals" + echo " ℹ Exempted ASNs: $ASN_LIST — SSH/web/geo-allowlist scenarios are unaffected" + echo " ℹ Edit /etc/crowdsec/scenarios/local-asterisk_*.yaml to add/remove ASNs later" + echo " (then: sudo systemctl restart crowdsec)" + fi + fi fi # ── 6. Geo-blocking + reputation (the capability fail2ban/Authelia lack) ─ @@ -457,6 +536,19 @@ sudo cscli collections list # installed detection collections list directly in that file, then `sudo systemctl restart crowdsec`. This can block Let's Encrypt's out-of-region ACME validation checks; if a cert renewal fails mysteriously, check here first. +- ASN-exempt Asterisk brute-force scenarios (if enabled, asterisk-digital-ocean + only): `/etc/crowdsec/scenarios/local-asterisk_bf.yaml` and + `local-asterisk_user_enum.yaml` — local forks of the stock hub scenarios with + specific carrier ASNs excluded from their filter (the hub originals get + disabled so events aren't double-processed). Exists because CGNAT mobile/ + satellite carriers (Starlink, T-Mobile home internet) share one public IP + across many customers, so a phone roaming WiFi↔mobile can get banned for + someone else's brute-force attempt on that same shared IP. SSH, web, and the + geo-allowlist are all unaffected — this only loosens Asterisk auth-failure + detection for the listed ASNs. Edit the `filter:` line in both files to + add/remove ASNs, then `sudo systemctl restart crowdsec`. Check the AS column + in `cscli decisions list` if the same carrier bans you again under a + different ASN later. ## Service control