feat: smart zomboid traffic filtering with packet-size detection

Replace per-IP hashlimit with smarter filtering that distinguishes
legitimate players from scanner bots based on packet behavior:
- Players send varied packet sizes (53, 37, 1472 bytes)
- Scanners only send 53-byte query packets

New firewall rule chain:
- Priority 2: Mark + ACCEPT non-query packets (verifies player)
- Priority 3: ACCEPT queries from verified IPs (1 hour TTL)
- Priority 4: LOG rate-limited queries from unverified IPs
- Priority 5: DROP rate-limited queries (2 burst, then 1/hour)

Also includes:
- Fail2ban zomboid jail with tighter thresholds (5 retries/4h, 1w ban)
- Graylog streams for zomboid-connections, zomboid-ratelimit, fail2ban
- GeoIP pipeline enrichment for zomboid traffic
- Fluent-bit inputs for ratelimit logs and fail2ban events
- Remove Legendary Katana mod (Workshop 3418366499) - removed from Steam
- Bump Immich to v2.5.0
- Fix fulfillr config (nil → null)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Bastian de Byl
2026-01-27 15:09:26 -05:00
parent 33eceff1fe
commit 9d562c7188
11 changed files with 325 additions and 6 deletions

View File

@@ -56,6 +56,30 @@ graylog_streams:
type: 1
inverted: false
- title: "zomboid-connections"
description: "Zomboid game server connection logs"
rules:
- field: "log_type"
value: "zomboid_connection"
type: 1
inverted: false
- title: "zomboid-ratelimit"
description: "Zomboid rate-limited connection attempts"
rules:
- field: "log_type"
value: "zomboid_ratelimit"
type: 1
inverted: false
- title: "fail2ban-actions"
description: "Fail2ban ban and unban events"
rules:
- field: "source"
value: "fail2ban"
type: 1
inverted: false
# Pipeline definitions
graylog_pipelines:
- title: "GeoIP Enrichment"
@@ -65,6 +89,7 @@ graylog_pipelines:
match: "EITHER"
rules:
- "geoip_caddy_access"
- "geoip_zomboid"
- title: "Debyltech Event Classification"
description: "Categorize debyltech-api events"
@@ -98,6 +123,20 @@ graylog_pipeline_rules:
set_field("geo_coordinates", geo["coordinates"]);
end
- title: "geoip_zomboid"
description: "GeoIP lookup for Zomboid connection logs"
source: |
rule "GeoIP for Zomboid"
when
has_field("src_ip")
then
let ip = to_string($message.src_ip);
let geo = lookup("geoip-lookup", ip);
set_field("geo_country", geo["country"].iso_code);
set_field("geo_city", geo["city"].names.en);
set_field("geo_coordinates", geo["coordinates"]);
end
- title: "classify_order_events"
description: "Classify order events"
source: |
@@ -164,6 +203,8 @@ graylog_pipeline_connections:
streams:
- "caddy-access"
- "caddy-fulfillr"
- "zomboid-connections"
- "zomboid-ratelimit"
- pipeline: "Debyltech Event Classification"
streams: