Skip to content

Repository files navigation

array-firewall on Proxmox

Custom network exit firewall — Firewalla-class protection (default deny, NAT, device approval, unsolicited blocked) with full customization via dashboard + API.

Target: replace the legacy gateway as the house exit. Now: lab mode on a secondary NIC for safe testing.

See docs/CUTOVER.md for the full gateway cutover procedure (preflight → wiring → cutover → verify → rollback).

./scripts/cutover-preflight.sh # checks only
FORCE_CUTOVER=1 ./scripts/cutover-gateway.sh # go live
./scripts/cutover-rollback.sh # undo

Deployment reference

Set these in your environment (or a local secrets file — never commit site-specific values):

VariablePurpose
PROXMOX_NODEProxmox host (management reachability)
ARRAY_FW_CTIDLXC ID for array-firewall
ARRAY_FW_IPContainer management IP on LAN (eth0)
ARRAY_FW_LAB_CIDRLab / bench client subnet on eth1 (e.g. 198.51.100.1/24)
ItemExample (RFC 5737 documentation space)
Proxmox${PROXMOX_NODE}
ContainerCT ${ARRAY_FW_CTID}
Management${ARRAY_FW_IP} (eth0)
Lab / clients${ARRAY_FW_LAB_CIDR} (eth1 → lab bridge)
Dashboardhttp://${ARRAY_FW_IP}:8090/
Sentinelhttp://${ARRAY_FW_IP}:8098/

Security model

  • Forward + input: drop by default; only established/related + explicit allows
  • Internet (lab → uplink): only MACs in allowlist (admin laptop pre-approved)
  • NAT: masquerade lab CIDR → uplink
  • Unsolicited inbound: denied on lab/WAN interface
  • New devices: discovered via DHCP/ARP, denied until allowed in dashboard

Deploy

# Set your laptop MAC (recommended)echo'ADMIN_LAPTOP_MAC=aa:bb:cc:dd:ee:ff'> /root/.secrets/array-firewall.env
export PROXMOX_NODE=pve-primary.example
export ARRAY_FW_CTID=100
export ARRAY_FW_IP=192.0.2.10
cd /path/to/array-firewall
./deploy.sh

Token after deploy: ssh root@${ARRAY_FW_IP} cat /etc/array-firewall/api.token

Gaming & probe defense

When co-hosted with Warzone Lobby Sentinel, array-firewall runs a closed-loop stack: Sentinel telemetry → mitigation → nft shield / blocklists → learning → optional fleet sync.

What “cheaters” means here

Session audit cheater counts are network probe attackers targeting your Xbox (tiny-packet floods, VPS mesh, abnormal CoD roles) — not in-game player slots or aimbot/wallhack identification. Infrastructure peers (LAN gateways, mesh APs, CoD backends, private IPs) are excluded from counts.

Probe countermeasures (probe_ops)

Central orchestration in api/lib/probe_ops.py, configured under gaming.mitigation.probe_ops in policies.json:

FeatureWhat it does
Instant sync on blockEvery peer block refreshes UDP confusion peers, nft probe rules, and shield peer sets
Live cheater counterRunning session tally + spike detection (blocks in last N seconds)
Pre-burst shieldBlocks peers with identical bursts ≥4 and fixed size spread before full threshold
Adaptive UDP echoPer-attacker IP modes: mutate-echo, jitter-drop, why-only, silent-drop
TCP persona stickinessHoneypot sink rotates http/ssh/ftp/rdp/generic banners per IP
Download desync boostAuto-applies download buffer assist when probe pressure ≥ threshold (not only jitter)
Mesh /24 blocksLowered clique thresholds for automatic subnet blocks
Auto abuse reportsGenerates provider abuse reports for repeat VPS/tiny-packet offenders
Fleet pushExports blocklist bundle after probe blocks (when fleet_sync_enabled)
Evidence exportOne-click zip/json bundle per session (postmortem, playback, logs)

Active countermeasure services:

UnitRole
array-firewall-probe-sinkTCP honeypot (port 39217) — fake banners, 12s tarpit, auto-block
array-firewall-probe-udp-confusionUDP sink (port 39218) — DNAT’d tiny probes get mutated echoes + why??

Session audit & playback

Post-mortem reports for every gaming session under /var/lib/array-firewall/session-reports/:

  • Batch audit all saved sessions for probe source counts
  • PROBE HEAVY / MODERATE / LIGHT synthetic lobby verdict when AI verdict data is missing (instead of misleading CLEAN)
  • Killcam correlation — links game killcam block events to probe forensics in the report
  • Playback — timeline of probe detections and shield actions during the session

CLI helpers (on the appliance):

shield-failsafe.sh audit-all-sessions # batch audit index
shield-failsafe.sh playback-session HEX # session playback text

Gaming API (Bearer token)

MethodPathDescription
GET/api/v1/gaming/probe-ops/liveLive cheater count, spike flag, recent probe IPs
GET/api/v1/gaming/probe-ops/healthProbe sink services, DNAT rule, UDP sink self-test
GET/api/v1/gaming/probe-ops/metricsCombined live + health + confusion + abuse stats
POST/api/v1/gaming/probe-ops/export{ "session_hex": "..." } → evidence zip path
POST/api/v1/gaming/probe-ops/fleet-pushForce fleet blocklist export/push
GET/api/v1/gaming/probe-confusionUDP/TCP confusion countermeasure status
POST/api/v1/gaming/probe-confusion/ensureSync peers + restart sink services
GET/api/v1/gaming/session-audit/allAudit index (all sessions, cheater counts)
POST/api/v1/gaming/session-audit/batchBatch re-audit up to N sessions
GET/api/v1/gaming/sessions/{hex}/postmortemFull post-mortem JSON
GET/api/v1/gaming/sessions/{hex}/playbackSession playback JSON or ?format=text
GET/api/v1/gaming/sessions/{hex}/evidenceEvidence bundle (zip + directory)
POST/api/v1/gaming/mitigateClosed-loop mitigation from Sentinel payload

Dashboard: Gaming Ops tab → Probe countermeasures panel (live count, health check, fleet push).

See also docs/ARCHITECTURE.md for the full gaming stack topology.

API (Bearer token)

MethodPathDescription
GET/api/healthService health (no auth)
GET/api/v1/devicesList devices + allow status
POST/api/v1/devices/{mac}/allowGrant internet
POST/api/v1/devices/{mac}/denyRevoke internet
POST/api/v1/firewall/discoverRescan DHCP/ARP + reload rules
POST/api/v1/firewall/reloadRe-apply nft rules
GET/api/v1/firewall/statusNAT, shield, allowlist summary
POST/api/v1/shield/enable{ "level": "normal" }
POST/api/v1/shield/relaxDisable packet shield
GET/api/v1/gaming/match-cockpitUnified Sentinel + autopilot + probe_ops snapshot

Testing

  1. Plug a device into the lab NIC — gets a DHCP address on the lab subnet, no internet until allowed
  2. Open dashboard — allow device with one click
  3. Admin laptop MAC (from secrets) has internet from first boot

Files

/opt/array-firewall/api/ # Python API + dashboard
/opt/array-firewall/gaming-tools/ # probe-sink-listener, probe-udp-confusion, packet-shield-nft.sh
/var/lib/array-firewall/devices.json
/var/lib/array-firewall/session-reports/ # post-mortem JSON per session
/var/lib/array-firewall/session-evidence/ # exported evidence bundles
/var/lib/array-firewall/probe-live-stats.json
/var/lib/array-firewall/probe-attacker-profiles.json # per-IP persona + echo modes
/var/lib/array-firewall/ruleset.nft
/etc/array-firewall/api.token
/etc/dnsmasq.d/array-firewall.conf

About

Custom network exit firewall — NAT, device approval, zone barrier, gaming packet shield

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages