Compare commits
2 Commits
bc26fcd1f9
...
9d562c7188
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9d562c7188 | ||
|
|
33eceff1fe |
@@ -12,7 +12,8 @@ deps:
|
||||
python-docker,
|
||||
]
|
||||
|
||||
fail2ban_jails: [sshd.local]
|
||||
fail2ban_jails: [sshd.local, zomboid.local]
|
||||
fail2ban_filters: [zomboid.conf]
|
||||
|
||||
services:
|
||||
- crond
|
||||
|
||||
5
ansible/roles/common/files/fail2ban/filters/zomboid.conf
Normal file
5
ansible/roles/common/files/fail2ban/filters/zomboid.conf
Normal file
@@ -0,0 +1,5 @@
|
||||
[Definition]
|
||||
# Match ZOMBOID_RATELIMIT firewall log entries
|
||||
# Example: ZOMBOID_RATELIMIT: IN=eth0 OUT= MAC=... SRC=1.2.3.4 DST=...
|
||||
failregex = ZOMBOID_RATELIMIT:.*SRC=<HOST>
|
||||
ignoreregex =
|
||||
9
ansible/roles/common/files/fail2ban/jails/zomboid.local
Normal file
9
ansible/roles/common/files/fail2ban/jails/zomboid.local
Normal file
@@ -0,0 +1,9 @@
|
||||
[zomboid]
|
||||
enabled = true
|
||||
filter = zomboid
|
||||
banaction = iptables-allports
|
||||
backend = systemd
|
||||
maxretry = 5
|
||||
findtime = 4h
|
||||
bantime = 1w
|
||||
ignoreip = 127.0.0.1/32 192.168.1.0/24
|
||||
@@ -21,6 +21,16 @@
|
||||
notify: restart_sshd
|
||||
tags: security
|
||||
|
||||
- name: setup fail2ban filters
|
||||
become: true
|
||||
ansible.builtin.copy:
|
||||
src: files/fail2ban/filters/{{ item }}
|
||||
dest: /etc/fail2ban/filter.d/{{ item }}
|
||||
mode: 0644
|
||||
loop: "{{ fail2ban_filters }}"
|
||||
notify: restart_fail2ban
|
||||
tags: security
|
||||
|
||||
- name: setup fail2ban jails
|
||||
become: true
|
||||
ansible.builtin.copy:
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -15,6 +15,7 @@ partkeepr_path: "{{ podman_volumes }}/partkeepr"
|
||||
partsy_path: "{{ podman_volumes }}/partsy"
|
||||
photos_path: "{{ podman_volumes }}/photos"
|
||||
uptime_kuma_path: "{{ podman_volumes }}/uptime-kuma"
|
||||
uptime_kuma_personal_path: "{{ podman_volumes }}/uptime-kuma-personal"
|
||||
zomboid_path: "{{ podman_volumes }}/zomboid"
|
||||
|
||||
# Zomboid server mode: 'vanilla', 'modded', or 'b42revamp'
|
||||
@@ -50,10 +51,10 @@ zomboid_mods:
|
||||
# Added: LogCabin (3653045510) - player connect/disconnect logging
|
||||
zomboid_mods_b42revamp:
|
||||
workshop_items: >-
|
||||
3402491515;2529746725;3378285185;3171167894;3635394848;3411888105;3616536783;3635591071;3636241120;3629835761;3618427553;3543229299;3622163276;3634921455;3626823538;2335368829;3580577925;3401134276;3418366499;3586216562;3452711271;2757712197;3330403100;2686624983;3409143790;3439305933;3378304610;2503622437;2896041179;2625625421;3590632059;3097650043;2366717227;3077900375;3596827035;3508537032;3630693325;3631572046;2463184726;2447729538;2142622992;3566868353;3539691958;3504401781;3570973322;3614034284;2900580391;3478633453;3001592312;3041122351;3315443103;2799152995;3248388837;2897390033;3379334330;2409333430;3110913021;3287727378;2846036306;3435796523;3447272250;2932547723;3110911330;2971246021;3005903549;3320947974;2942793445;3008795514;2870394916;2952802178;2805630347;3490370700;2772575623;3428008364;2566953935;3413704851;3152529790;2811383142;3592777775;3418252689;3404737883;3631989559;2969343830;3366300557;2962175696;3596903773;3226885926;2937786633;3601417745;2886832936;2932549988;3088951320;3611100835;3409472393;3623784989;3625020432;3138387399;3119788162;2286124931;2866258937;3623919908;2714198296;3628835042;3429790870;3431734923;3577903007;3398874593;2950902979;3420581050;3538760023;3423984426;3396446795;3618557184;2840805724;3437629766;3632610172;3633882960;3307376332;3453676250;3431256608;3475347500;3404956403;3451167732;3281755175;3252451158;3162566044;2684285534;3424309174;3199474685;3483407987;3387222454;3614959302;3351207258;2699828474;3461263912;3322066592;2972289937;2948824747;3624268336;2857762294;2920899878;3572556874;3470426196;3470422050;3432928943;3430172149;3637373250;3044705007;2705406713;3554424111;3412105017;3554048011;3635228703;2940354599;3414634809;3627047348;3442862183;2990322197;3394044313;3617854007;3388867450;3532685233;3411695932;3643808082;3413150945;3531611692;3653045510
|
||||
3402491515;2529746725;3378285185;3171167894;3635394848;3411888105;3616536783;3635591071;3636241120;3629835761;3618427553;3543229299;3622163276;3634921455;3626823538;2335368829;3580577925;3401134276;3586216562;3452711271;2757712197;3330403100;2686624983;3409143790;3439305933;3378304610;2503622437;2896041179;2625625421;3590632059;3097650043;2366717227;3077900375;3596827035;3508537032;3630693325;3631572046;2463184726;2447729538;2142622992;3566868353;3539691958;3504401781;3570973322;3614034284;2900580391;3478633453;3001592312;3041122351;3315443103;2799152995;3248388837;2897390033;3379334330;2409333430;3110913021;3287727378;2846036306;3435796523;3447272250;2932547723;3110911330;2971246021;3005903549;3320947974;2942793445;3008795514;2870394916;2952802178;2805630347;3490370700;2772575623;3428008364;2566953935;3413704851;3152529790;2811383142;3592777775;3418252689;3404737883;3631989559;2969343830;3366300557;2962175696;3596903773;3226885926;2937786633;3601417745;2886832936;2932549988;3088951320;3611100835;3409472393;3623784989;3625020432;3138387399;3119788162;2286124931;2866258937;3623919908;2714198296;3628835042;3429790870;3431734923;3577903007;3398874593;2950902979;3420581050;3538760023;3423984426;3396446795;3618557184;2840805724;3437629766;3632610172;3633882960;3307376332;3453676250;3431256608;3475347500;3404956403;3451167732;3281755175;3252451158;3162566044;2684285534;3424309174;3199474685;3483407987;3387222454;3614959302;3351207258;2699828474;3461263912;3322066592;2972289937;2948824747;3624268336;2857762294;2920899878;3572556874;3470426196;3470422050;3432928943;3430172149;3637373250;3044705007;2705406713;3554424111;3412105017;3554048011;3635228703;2940354599;3414634809;3627047348;3442862183;2990322197;3394044313;3617854007;3388867450;3532685233;3411695932;3643808082;3413150945;3531611692;3653045510
|
||||
# Load order from Steam collection (UpgradeableStorage removed for MP compatibility, LogCabin added)
|
||||
mod_ids: >-
|
||||
\MoodleFramework;\NeatUI_Framework;\Optimal;\SPNCC;\SPNCCDetails;\SPNCCDetailsHD;\TombBodyTexNUDE;\Authentic Z - Current;\PROJECTRVInterior42;\RVInteriorExpansion;\RVInteriorExpansionPart2;\RVmilitaryaddon;\damnlib;\04vwTouran;\49powerWagon;\59meteor;\63beetle;\63Type2Van;\65banshee;\66pontiacLeMans;\69charger;\69mini;\69mini_ItalianJob;\69mini_MrBean;\69mini_PitbullSpecial;\73fordFalcon;\73fordFalconPS;\78amgeneralM35A2;\78amgeneralM35A2extra;\78amgeneralM49A2C;\78amgeneralM50A3;\78amgeneralM62;\80manKat1;\82firebird;\82firebirdKITT;\82porsche911;\83amgeneralM923;\83amgeneralM923extra;\84buickElectra;\84cadillacDeVille;\84merc;\84oldsmobile98;\85buickLeSabre;\85chevyCaprice;\85chevyStepVan;\85chevyStepVanexpanded;\86chevyCUCV;\86fordE150;\86fordE150dnd;\86fordE150expanded;\86fordE150mm;\86fordE150pd;\86oshkoshP19A;\87buickRegal;\87fordB700;\88chevyS10;\88toyotaHilux;\89defender;\89trooper;\90bmwE30;\90fordF350ambulance;\90pierceArrow;\91fordLTD;\91fordRanger;\91geoMetro;\91nissan240sx;\91range;\92fordCVPI;\92jeepYJ;\92jeepYJJP18;\92nissanGTR;\93chevySuburban;\93chevySuburbanExpanded;\93fordElgin;\93fordTaurus;\93mustangSSP;\93townCar;\97bushmaster;\98stagea;\99fordCVPI;\KI5trailers;\CargoTrailer_BubbysVariants;\ECTO1;\isoContainers;\tsarslib;\LIAZ 300;\Military_Tool_Kit;\RotatorsLib;\rSemiTruck;\U.S. M998 Humvee by Papa_Chad;\2920899878/ReloadAllMagazines;\BB_WhereAmI;\Buttstroke;\CleanHotBar;\CleanUI;\ClientModsToServer;\CombatText;\ContextMenuIconsCore;\DG_MIVehicles;\EffortlessTowing;\EQUIPMENT_UI;\EURY_BUGS;\FixBlowTorchPropaneTank;\flipvehicleplustrailer;\ForceSync42;\FWOBenchPress&Treadmill;\FWOFitnessWorkoutOverhaul;\GenRange;\HereGoesTheSun;\hf_point_blank;\HideDebugMenu;\HNDLBR_Preppers;\LongStandingMetalConstructions;\MBFTiming;\MiniHealthPanel;\ModernStatus;\ModLoadOrderSorter_b42;\ChuckleberryFinnAlertSystem;\ModManager;\MoreDescriptionForTraits4213;\NoLighterNeeded;\OCsPacking;\phunlib;\phunzones;\ProgressiveMultihit;\ProgressiveMultihit42.13patch;\RealisticDash;\REORDER_CONTAINERS;\StarlitLibrary;\RepairableWindows;\SleepWithFriends;\SmokingSoundsOverhaul;\errorMagnifier;\SwapIt;\TMRRemoveMumble42;\trunk_organizer;\TVRadio_ReInvented;\UdderlyUpToDate_B42.13;\UnseasonalWeather;\VehicleRepairOverhaul;\VehicleSalvageOverhaulB42;\ArcheryNexus;\EFTBP;\FH;\GanydeBielovzki's Frockin Shirts n Ties;\GanydeBielovzki's Frockin Splendor! Vol.2;\GanydeBielovzki's Frockin Splendor! Vol.3;\GanydeBielovzki's Frockin Splendor! Vol.4;\GanydeBielovzki's Frockin Splendor! Vol.5;\GanydeBielovzki's Frockin Wiseguys;\H_E_C_U;\KATTAJ1_ClothesCore;\SapphCooking_B42;\SpnCloth;\TombBody;\TombWardrobeALT;\VanillaGearExpanded;\zReApoModernArmorB42;\B42RainsFirearmsAndGunPartsExpanded4213;\AatheomEMVFSM;\amclub;\FunctionalGutters;\GanydeBielovzki's Frockin Splendor!;\grasslands;\HGOEXP;\KATTAJ1_Military;\Ladders42131;\LKB42;\LNB42;\LongHammer;\MoreDamagedObjects;\N&CsNarcotics;\phunsprinters;\phunsprintersui;\Project_Seasons_B41;\RebalancedPropMoving;\RepairAnyClothes;\RET_LethalStealth;\RiskyInspectWeapon;\ShelterHold_Beehive;\SimpleOverhaulTraitsAndOccupations;\SkillRecoveryJournal;\SPNCCFaces;\SpnHair;\TrueMoozic;\TMMMB42.13+;\TombBodyCompat;\TombBodyCustom;\TrueMusicJukebox;\TrueMusicRadio42;\TrueSmoking;\VanillaFoodsExpanded;\VanillaVehiclesAnimated;\WorkshopUpdateCheck;\zReBetterLockpickingb42mp;\CACustomWoodWeight;\LogCabin
|
||||
\MoodleFramework;\NeatUI_Framework;\Optimal;\SPNCC;\SPNCCDetails;\SPNCCDetailsHD;\TombBodyTexNUDE;\Authentic Z - Current;\PROJECTRVInterior42;\RVInteriorExpansion;\RVInteriorExpansionPart2;\RVmilitaryaddon;\damnlib;\04vwTouran;\49powerWagon;\59meteor;\63beetle;\63Type2Van;\65banshee;\66pontiacLeMans;\69charger;\69mini;\69mini_ItalianJob;\69mini_MrBean;\69mini_PitbullSpecial;\73fordFalcon;\73fordFalconPS;\78amgeneralM35A2;\78amgeneralM35A2extra;\78amgeneralM49A2C;\78amgeneralM50A3;\78amgeneralM62;\80manKat1;\82firebird;\82firebirdKITT;\82porsche911;\83amgeneralM923;\83amgeneralM923extra;\84buickElectra;\84cadillacDeVille;\84merc;\84oldsmobile98;\85buickLeSabre;\85chevyCaprice;\85chevyStepVan;\85chevyStepVanexpanded;\86chevyCUCV;\86fordE150;\86fordE150dnd;\86fordE150expanded;\86fordE150mm;\86fordE150pd;\86oshkoshP19A;\87buickRegal;\87fordB700;\88chevyS10;\88toyotaHilux;\89defender;\89trooper;\90bmwE30;\90fordF350ambulance;\90pierceArrow;\91fordLTD;\91fordRanger;\91geoMetro;\91nissan240sx;\91range;\92fordCVPI;\92jeepYJ;\92jeepYJJP18;\92nissanGTR;\93chevySuburban;\93chevySuburbanExpanded;\93fordElgin;\93fordTaurus;\93mustangSSP;\93townCar;\97bushmaster;\98stagea;\99fordCVPI;\KI5trailers;\CargoTrailer_BubbysVariants;\ECTO1;\isoContainers;\tsarslib;\LIAZ 300;\Military_Tool_Kit;\RotatorsLib;\rSemiTruck;\U.S. M998 Humvee by Papa_Chad;\2920899878/ReloadAllMagazines;\BB_WhereAmI;\Buttstroke;\CleanHotBar;\CleanUI;\ClientModsToServer;\CombatText;\ContextMenuIconsCore;\DG_MIVehicles;\EffortlessTowing;\EQUIPMENT_UI;\EURY_BUGS;\FixBlowTorchPropaneTank;\flipvehicleplustrailer;\ForceSync42;\FWOBenchPress&Treadmill;\FWOFitnessWorkoutOverhaul;\GenRange;\HereGoesTheSun;\hf_point_blank;\HideDebugMenu;\HNDLBR_Preppers;\LongStandingMetalConstructions;\MBFTiming;\MiniHealthPanel;\ModernStatus;\ModLoadOrderSorter_b42;\ChuckleberryFinnAlertSystem;\ModManager;\MoreDescriptionForTraits4213;\NoLighterNeeded;\OCsPacking;\phunlib;\phunzones;\ProgressiveMultihit;\ProgressiveMultihit42.13patch;\RealisticDash;\REORDER_CONTAINERS;\StarlitLibrary;\RepairableWindows;\SleepWithFriends;\SmokingSoundsOverhaul;\errorMagnifier;\SwapIt;\TMRRemoveMumble42;\trunk_organizer;\TVRadio_ReInvented;\UdderlyUpToDate_B42.13;\UnseasonalWeather;\VehicleRepairOverhaul;\VehicleSalvageOverhaulB42;\ArcheryNexus;\EFTBP;\FH;\GanydeBielovzki's Frockin Shirts n Ties;\GanydeBielovzki's Frockin Splendor! Vol.2;\GanydeBielovzki's Frockin Splendor! Vol.3;\GanydeBielovzki's Frockin Splendor! Vol.4;\GanydeBielovzki's Frockin Splendor! Vol.5;\GanydeBielovzki's Frockin Wiseguys;\H_E_C_U;\KATTAJ1_ClothesCore;\SapphCooking_B42;\SpnCloth;\TombBody;\TombWardrobeALT;\VanillaGearExpanded;\zReApoModernArmorB42;\B42RainsFirearmsAndGunPartsExpanded4213;\AatheomEMVFSM;\amclub;\FunctionalGutters;\GanydeBielovzki's Frockin Splendor!;\grasslands;\HGOEXP;\KATTAJ1_Military;\Ladders42131;\LNB42;\LongHammer;\MoreDamagedObjects;\N&CsNarcotics;\phunsprinters;\phunsprintersui;\Project_Seasons_B41;\RebalancedPropMoving;\RepairAnyClothes;\RET_LethalStealth;\RiskyInspectWeapon;\ShelterHold_Beehive;\SimpleOverhaulTraitsAndOccupations;\SkillRecoveryJournal;\SPNCCFaces;\SpnHair;\TrueMoozic;\TMMMB42.13+;\TombBodyCompat;\TombBodyCustom;\TrueMusicJukebox;\TrueMusicRadio42;\TrueSmoking;\VanillaFoodsExpanded;\VanillaVehiclesAnimated;\WorkshopUpdateCheck;\zReBetterLockpickingb42mp;\CACustomWoodWeight;\LogCabin
|
||||
|
||||
# Map configuration per server mode
|
||||
zomboid_maps:
|
||||
@@ -78,6 +79,7 @@ cloud_skudak_server_name: cloud.skudakrennsport.com
|
||||
fulfillr_server_name: fulfillr.debyltech.com
|
||||
home_server_name: home.bdebyl.net
|
||||
uptime_kuma_server_name: uptime.debyltech.com
|
||||
uptime_kuma_personal_server_name: uptime.debyl.io
|
||||
parts_server_name: parts.bdebyl.net
|
||||
photos_server_name: photos.bdebyl.net
|
||||
|
||||
@@ -146,6 +148,7 @@ caddy_log_names:
|
||||
- assistant
|
||||
- parts
|
||||
- uptime-kuma
|
||||
- uptime-kuma-personal
|
||||
- graylog
|
||||
- cloud
|
||||
- cloud-skudak
|
||||
|
||||
38
ansible/roles/podman/tasks/containers/home/uptime-kuma.yml
Normal file
38
ansible/roles/podman/tasks/containers/home/uptime-kuma.yml
Normal file
@@ -0,0 +1,38 @@
|
||||
---
|
||||
- name: create uptime-kuma-personal host directory volumes
|
||||
become: true
|
||||
ansible.builtin.file:
|
||||
path: "{{ item }}"
|
||||
state: directory
|
||||
owner: "{{ podman_user }}"
|
||||
group: "{{ podman_user }}"
|
||||
mode: 0755
|
||||
notify: restorecon podman
|
||||
loop:
|
||||
- "{{ uptime_kuma_personal_path }}/data"
|
||||
|
||||
- name: flush handlers
|
||||
ansible.builtin.meta: flush_handlers
|
||||
|
||||
- import_tasks: podman/podman-check.yml
|
||||
vars:
|
||||
container_name: uptime-kuma-personal
|
||||
container_image: "{{ image }}"
|
||||
|
||||
- name: create uptime-kuma-personal container
|
||||
become: true
|
||||
become_user: "{{ podman_user }}"
|
||||
containers.podman.podman_container:
|
||||
name: uptime-kuma-personal
|
||||
image: "{{ image }}"
|
||||
restart_policy: on-failure:3
|
||||
log_driver: journald
|
||||
volumes:
|
||||
- "{{ uptime_kuma_personal_path }}/data:/app/data"
|
||||
ports:
|
||||
- "3002:3001/tcp"
|
||||
|
||||
- name: create systemd startup job for uptime-kuma-personal
|
||||
include_tasks: podman/systemd-generate.yml
|
||||
vars:
|
||||
container_name: uptime-kuma-personal
|
||||
@@ -291,6 +291,7 @@
|
||||
changed_when: "'already' not in firewall_result.stderr"
|
||||
failed_when: false
|
||||
notify: restart firewalld
|
||||
tags: firewall
|
||||
|
||||
- name: add firewall rule to log zomboid connections (runtime)
|
||||
become: true
|
||||
@@ -300,6 +301,209 @@
|
||||
-j LOG --log-prefix "ZOMBOID_CONN: " --log-level 4
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
tags: firewall
|
||||
|
||||
# =============================================================================
|
||||
# Add logging for port 16262 (mirrors existing 16261 logging)
|
||||
# =============================================================================
|
||||
- name: add firewall rule to log zomboid connections on 16262
|
||||
become: true
|
||||
ansible.builtin.command: >
|
||||
firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT 0
|
||||
-p udp --dport 16262 -m conntrack --ctstate NEW
|
||||
-j LOG --log-prefix "ZOMBOID_CONN: " --log-level 4
|
||||
register: firewall_result_16262
|
||||
changed_when: "'already' not in firewall_result_16262.stderr"
|
||||
failed_when: false
|
||||
notify: restart firewalld
|
||||
tags: firewall
|
||||
|
||||
- name: add firewall rule to log zomboid connections on 16262 (runtime)
|
||||
become: true
|
||||
ansible.builtin.command: >
|
||||
firewall-cmd --direct --add-rule ipv4 filter INPUT 0
|
||||
-p udp --dport 16262 -m conntrack --ctstate NEW
|
||||
-j LOG --log-prefix "ZOMBOID_CONN: " --log-level 4
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
tags: firewall
|
||||
|
||||
# =============================================================================
|
||||
# Zomboid Rate Limiting and Query Flood Protection
|
||||
# =============================================================================
|
||||
# These rules mitigate Steam server query floods while allowing legitimate play.
|
||||
# Query packets are typically 53 bytes; game traffic is larger and sustained.
|
||||
#
|
||||
# Rule priority: 0=logging (existing), 1=allow established, 2=rate limit queries
|
||||
|
||||
# Allow established/related connections without rate limiting
|
||||
# This ensures active players aren't affected by query rate limits
|
||||
- name: allow established zomboid connections on 16261
|
||||
become: true
|
||||
ansible.builtin.command: >
|
||||
firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT 1
|
||||
-p udp --dport 16261 -m conntrack --ctstate ESTABLISHED,RELATED
|
||||
-j ACCEPT
|
||||
register: established_result
|
||||
changed_when: "'already' not in established_result.stderr"
|
||||
failed_when: false
|
||||
notify: restart firewalld
|
||||
tags: firewall
|
||||
|
||||
- name: allow established zomboid connections on 16262
|
||||
become: true
|
||||
ansible.builtin.command: >
|
||||
firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT 1
|
||||
-p udp --dport 16262 -m conntrack --ctstate ESTABLISHED,RELATED
|
||||
-j ACCEPT
|
||||
register: established_result_16262
|
||||
changed_when: "'already' not in established_result_16262.stderr"
|
||||
failed_when: false
|
||||
notify: restart firewalld
|
||||
tags: firewall
|
||||
|
||||
# =============================================================================
|
||||
# Smart Zomboid Traffic Filtering (Packet-Size Based)
|
||||
# =============================================================================
|
||||
# Distinguishes legitimate players from scanner bots:
|
||||
# - Players send varied packet sizes (53, 37, 1472 bytes)
|
||||
# - Scanners only send 53-byte query packets
|
||||
#
|
||||
# Rule priority:
|
||||
# 0 = LOG all (existing above)
|
||||
# 1 = ACCEPT established (existing above)
|
||||
# 2 = Mark + ACCEPT non-query packets (verifies player)
|
||||
# 3 = ACCEPT queries from verified IPs
|
||||
# 4 = LOG rate-limited queries from unverified IPs
|
||||
# 5 = DROP rate-limited queries from unverified IPs
|
||||
|
||||
# Priority 2: Mark IPs sending non-query packets as verified (1 hour TTL)
|
||||
# Any packet NOT 53 bytes proves actual connection attempt
|
||||
- name: mark verified players on 16261 (non-query packets)
|
||||
become: true
|
||||
ansible.builtin.command: >
|
||||
firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT 2
|
||||
-p udp --dport 16261 -m conntrack --ctstate NEW
|
||||
-m length ! --length 53
|
||||
-m recent --name zomboid_verified --set
|
||||
-j ACCEPT
|
||||
register: verify_result
|
||||
changed_when: "'already' not in verify_result.stderr"
|
||||
failed_when: false
|
||||
notify: restart firewalld
|
||||
tags: firewall
|
||||
|
||||
- name: mark verified players on 16262 (non-query packets)
|
||||
become: true
|
||||
ansible.builtin.command: >
|
||||
firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT 2
|
||||
-p udp --dport 16262 -m conntrack --ctstate NEW
|
||||
-m length ! --length 53
|
||||
-m recent --name zomboid_verified --set
|
||||
-j ACCEPT
|
||||
register: verify_result_16262
|
||||
changed_when: "'already' not in verify_result_16262.stderr"
|
||||
failed_when: false
|
||||
notify: restart firewalld
|
||||
tags: firewall
|
||||
|
||||
# Priority 3: Allow queries from verified players (within 1 hour)
|
||||
- name: allow queries from verified players on 16261
|
||||
become: true
|
||||
ansible.builtin.command: >
|
||||
firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT 3
|
||||
-p udp --dport 16261 -m conntrack --ctstate NEW
|
||||
-m length --length 53
|
||||
-m recent --name zomboid_verified --rcheck --seconds 3600
|
||||
-j ACCEPT
|
||||
register: verified_query_result
|
||||
changed_when: "'already' not in verified_query_result.stderr"
|
||||
failed_when: false
|
||||
notify: restart firewalld
|
||||
tags: firewall
|
||||
|
||||
- name: allow queries from verified players on 16262
|
||||
become: true
|
||||
ansible.builtin.command: >
|
||||
firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT 3
|
||||
-p udp --dport 16262 -m conntrack --ctstate NEW
|
||||
-m length --length 53
|
||||
-m recent --name zomboid_verified --rcheck --seconds 3600
|
||||
-j ACCEPT
|
||||
register: verified_query_result_16262
|
||||
changed_when: "'already' not in verified_query_result_16262.stderr"
|
||||
failed_when: false
|
||||
notify: restart firewalld
|
||||
tags: firewall
|
||||
|
||||
# Priority 4: LOG rate-limited queries from unverified IPs
|
||||
# Very aggressive: 2 burst, then 1 per hour
|
||||
# Note: Uses same hashlimit name as DROP rule to share bucket
|
||||
- name: log rate-limited queries from unverified IPs on 16261
|
||||
become: true
|
||||
ansible.builtin.command: >
|
||||
firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT 4
|
||||
-p udp --dport 16261 -m conntrack --ctstate NEW
|
||||
-m length --length 53
|
||||
-m hashlimit --hashlimit-above 1/hour --hashlimit-burst 2
|
||||
--hashlimit-mode srcip --hashlimit-name zomboid_query_16261
|
||||
--hashlimit-htable-expire 3600000
|
||||
-j LOG --log-prefix "ZOMBOID_RATELIMIT: " --log-level 4
|
||||
register: unverified_log_result
|
||||
changed_when: "'already' not in unverified_log_result.stderr"
|
||||
failed_when: false
|
||||
notify: restart firewalld
|
||||
tags: firewall
|
||||
|
||||
- name: log rate-limited queries from unverified IPs on 16262
|
||||
become: true
|
||||
ansible.builtin.command: >
|
||||
firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT 4
|
||||
-p udp --dport 16262 -m conntrack --ctstate NEW
|
||||
-m length --length 53
|
||||
-m hashlimit --hashlimit-above 1/hour --hashlimit-burst 2
|
||||
--hashlimit-mode srcip --hashlimit-name zomboid_query_16262
|
||||
--hashlimit-htable-expire 3600000
|
||||
-j LOG --log-prefix "ZOMBOID_RATELIMIT: " --log-level 4
|
||||
register: unverified_log_result_16262
|
||||
changed_when: "'already' not in unverified_log_result_16262.stderr"
|
||||
failed_when: false
|
||||
notify: restart firewalld
|
||||
tags: firewall
|
||||
|
||||
# Priority 5: DROP rate-limited queries from unverified IPs
|
||||
# Note: Uses same hashlimit name as LOG rule to share bucket
|
||||
- name: drop rate-limited queries from unverified IPs on 16261
|
||||
become: true
|
||||
ansible.builtin.command: >
|
||||
firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT 5
|
||||
-p udp --dport 16261 -m conntrack --ctstate NEW
|
||||
-m length --length 53
|
||||
-m hashlimit --hashlimit-above 1/hour --hashlimit-burst 2
|
||||
--hashlimit-mode srcip --hashlimit-name zomboid_query_16261
|
||||
--hashlimit-htable-expire 3600000
|
||||
-j DROP
|
||||
register: unverified_drop_result
|
||||
changed_when: "'already' not in unverified_drop_result.stderr"
|
||||
failed_when: false
|
||||
notify: restart firewalld
|
||||
tags: firewall
|
||||
|
||||
- name: drop rate-limited queries from unverified IPs on 16262
|
||||
become: true
|
||||
ansible.builtin.command: >
|
||||
firewall-cmd --permanent --direct --add-rule ipv4 filter INPUT 5
|
||||
-p udp --dport 16262 -m conntrack --ctstate NEW
|
||||
-m length --length 53
|
||||
-m hashlimit --hashlimit-above 1/hour --hashlimit-burst 2
|
||||
--hashlimit-mode srcip --hashlimit-name zomboid_query_16262
|
||||
--hashlimit-htable-expire 3600000
|
||||
-j DROP
|
||||
register: unverified_drop_result_16262
|
||||
changed_when: "'already' not in unverified_drop_result_16262.stderr"
|
||||
failed_when: false
|
||||
notify: restart firewalld
|
||||
tags: firewall
|
||||
|
||||
# World reset is now triggered via Discord bot -> systemd path unit
|
||||
# See zomboid-world-reset.path and zomboid-world-reset.service
|
||||
|
||||
@@ -54,9 +54,9 @@
|
||||
- import_tasks: containers/home/photos.yml
|
||||
vars:
|
||||
db_image: docker.io/tensorchord/pgvecto-rs:pg14-v0.2.0@sha256:90724186f0a3517cf6914295b5ab410db9ce23190a2d9d0b9dd6463e3fa298f0
|
||||
ml_image: ghcr.io/immich-app/immich-machine-learning:v2.4.1
|
||||
ml_image: ghcr.io/immich-app/immich-machine-learning:v2.5.0
|
||||
redis_image: docker.io/redis:6.2-alpine@sha256:eaba718fecd1196d88533de7ba49bf903ad33664a92debb24660a922ecd9cac8
|
||||
image: ghcr.io/immich-app/immich-server:v2.4.1
|
||||
image: ghcr.io/immich-app/immich-server:v2.5.0
|
||||
tags: photos
|
||||
|
||||
- import_tasks: containers/home/cloud.yml
|
||||
@@ -78,8 +78,13 @@
|
||||
|
||||
- import_tasks: containers/debyltech/uptime-kuma.yml
|
||||
vars:
|
||||
image: docker.io/louislam/uptime-kuma:1
|
||||
tags: debyltech, uptime-kuma
|
||||
image: docker.io/louislam/uptime-kuma:2.0.2
|
||||
tags: debyltech, uptime-debyltech
|
||||
|
||||
- import_tasks: containers/home/uptime-kuma.yml
|
||||
vars:
|
||||
image: docker.io/louislam/uptime-kuma:2.0.2
|
||||
tags: home, uptime
|
||||
|
||||
- import_tasks: containers/debyltech/geoip.yml
|
||||
tags: debyltech, graylog, geoip
|
||||
@@ -92,7 +97,7 @@
|
||||
|
||||
- import_tasks: containers/home/gregtime.yml
|
||||
vars:
|
||||
image: localhost/greg-time-bot:3.0.1
|
||||
image: localhost/greg-time-bot:3.0.2
|
||||
tags: gregtime
|
||||
|
||||
- import_tasks: containers/home/zomboid.yml
|
||||
|
||||
@@ -164,7 +164,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
# Uptime Kuma - {{ uptime_kuma_server_name }}
|
||||
# Uptime Kuma (Debyltech) - {{ uptime_kuma_server_name }}
|
||||
{{ uptime_kuma_server_name }} {
|
||||
{{ ip_restricted_site() }}
|
||||
|
||||
@@ -182,6 +182,24 @@
|
||||
}
|
||||
}
|
||||
|
||||
# Uptime Kuma (Personal) - {{ uptime_kuma_personal_server_name }}
|
||||
{{ uptime_kuma_personal_server_name }} {
|
||||
{{ ip_restricted_site() }}
|
||||
|
||||
handle @local {
|
||||
import common_headers
|
||||
reverse_proxy localhost:3002 {
|
||||
# WebSocket support for live updates
|
||||
flush_interval -1
|
||||
}
|
||||
}
|
||||
|
||||
log {
|
||||
output file /var/log/caddy/uptime-kuma-personal.log
|
||||
format json
|
||||
}
|
||||
}
|
||||
|
||||
# Graylog Logs - {{ logs_server_name }}
|
||||
{{ logs_server_name }} {
|
||||
# GELF HTTP endpoint - open for Lambda (auth via header)
|
||||
|
||||
@@ -36,6 +36,27 @@
|
||||
Read_From_Tail On
|
||||
Strip_Underscores On
|
||||
|
||||
# =============================================================================
|
||||
# INPUT: Kernel firewall logs for Zomboid rate limiting
|
||||
# =============================================================================
|
||||
# Captures ZOMBOID_RATELIMIT firewall events for fail2ban monitoring
|
||||
[INPUT]
|
||||
Name systemd
|
||||
Tag firewall.zomboid.ratelimit
|
||||
Systemd_Filter _TRANSPORT=kernel
|
||||
Read_From_Tail On
|
||||
Strip_Underscores On
|
||||
|
||||
# =============================================================================
|
||||
# INPUT: Fail2ban actions (ban/unban events)
|
||||
# =============================================================================
|
||||
[INPUT]
|
||||
Name systemd
|
||||
Tag fail2ban.*
|
||||
Systemd_Filter _SYSTEMD_UNIT=fail2ban.service
|
||||
Read_From_Tail On
|
||||
Strip_Underscores On
|
||||
|
||||
# =============================================================================
|
||||
# INPUT: Caddy access logs (JSON format)
|
||||
# =============================================================================
|
||||
@@ -93,6 +114,27 @@
|
||||
Record source firewall
|
||||
Record log_type zomboid_connection
|
||||
|
||||
# Filter kernel logs to only keep ZOMBOID_RATELIMIT messages
|
||||
[FILTER]
|
||||
Name grep
|
||||
Match firewall.zomboid.ratelimit
|
||||
Regex MESSAGE ZOMBOID_RATELIMIT
|
||||
|
||||
[FILTER]
|
||||
Name record_modifier
|
||||
Match firewall.zomboid.ratelimit
|
||||
Record host {{ ansible_hostname }}
|
||||
Record source firewall
|
||||
Record log_type zomboid_ratelimit
|
||||
|
||||
# Fail2ban ban/unban events
|
||||
[FILTER]
|
||||
Name record_modifier
|
||||
Match fail2ban.*
|
||||
Record host {{ ansible_hostname }}
|
||||
Record source fail2ban
|
||||
Record log_type security
|
||||
|
||||
# =============================================================================
|
||||
# OUTPUT: All logs to Graylog GELF UDP
|
||||
# =============================================================================
|
||||
|
||||
@@ -15,3 +15,10 @@
|
||||
Name zomboid_firewall
|
||||
Format regex
|
||||
Regex ZOMBOID_CONN:.*SRC=(?<src_ip>[0-9.]+).*DST=(?<dst_ip>[0-9.]+).*DPT=(?<dst_port>[0-9]+)
|
||||
|
||||
# Parse ZOMBOID_RATELIMIT firewall logs to extract source IP
|
||||
# Example: ZOMBOID_RATELIMIT: IN=enp0s31f6 OUT= MAC=... SRC=45.5.113.90 DST=192.168.1.10 ...
|
||||
[PARSER]
|
||||
Name zomboid_ratelimit
|
||||
Format regex
|
||||
Regex ZOMBOID_RATELIMIT:.*SRC=(?<src_ip>[0-9.]+).*DST=(?<dst_ip>[0-9.]+).*DPT=(?<dst_port>[0-9]+)
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
},
|
||||
"tax": {
|
||||
"ein": "{{ fulfillr_tax_ein }}",
|
||||
"ioss": nil
|
||||
"ioss": null
|
||||
},
|
||||
"sender_address": {
|
||||
"city": "Newbury",
|
||||
|
||||
Reference in New Issue
Block a user