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):

Variable Purpose
PROXMOX_NODE Proxmox host (management reachability)
ARRAY_FW_CTID LXC ID for array-firewall
ARRAY_FW_IP Container management IP on LAN (eth0)
ARRAY_FW_LAB_CIDR Lab / bench client subnet on eth1 (e.g. 198.51.100.1/24)
Item Example (RFC 5737 documentation space)
Proxmox ${PROXMOX_NODE}
Container CT ${ARRAY_FW_CTID}
Management ${ARRAY_FW_IP} (eth0)
Lab / clients ${ARRAY_FW_LAB_CIDR} (eth1 → lab bridge)
Dashboard http://${ARRAY_FW_IP}:8090/
Sentinel http://${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:

Feature What it does
Instant sync on block Every peer block refreshes UDP confusion peers, nft probe rules, and shield peer sets
Live cheater counter Running session tally + spike detection (blocks in last N seconds)
Pre-burst shield Blocks peers with identical bursts ≥4 and fixed size spread before full threshold
Adaptive UDP echo Per-attacker IP modes: mutate-echo, jitter-drop, why-only, silent-drop
TCP persona stickiness Honeypot sink rotates http/ssh/ftp/rdp/generic banners per IP
Download desync boost Auto-applies download buffer assist when probe pressure ≥ threshold (not only jitter)
Mesh /24 blocks Lowered clique thresholds for automatic subnet blocks
Auto abuse reports Generates provider abuse reports for repeat VPS/tiny-packet offenders
Fleet push Exports blocklist bundle after probe blocks (when fleet_sync_enabled)
Evidence export One-click zip/json bundle per session (postmortem, playback, logs)

Active countermeasure services:

Unit Role
array-firewall-probe-sink TCP honeypot (port 39217) — fake banners, 12s tarpit, auto-block
array-firewall-probe-udp-confusion UDP 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)

Method Path Description
GET /api/v1/gaming/probe-ops/live Live cheater count, spike flag, recent probe IPs
GET /api/v1/gaming/probe-ops/health Probe sink services, DNAT rule, UDP sink self-test
GET /api/v1/gaming/probe-ops/metrics Combined live + health + confusion + abuse stats
POST /api/v1/gaming/probe-ops/export { "session_hex": "..." } → evidence zip path
POST /api/v1/gaming/probe-ops/fleet-push Force fleet blocklist export/push
GET /api/v1/gaming/probe-confusion UDP/TCP confusion countermeasure status
POST /api/v1/gaming/probe-confusion/ensure Sync peers + restart sink services
GET /api/v1/gaming/session-audit/all Audit index (all sessions, cheater counts)
POST /api/v1/gaming/session-audit/batch Batch re-audit up to N sessions
GET /api/v1/gaming/sessions/{hex}/postmortem Full post-mortem JSON
GET /api/v1/gaming/sessions/{hex}/playback Session playback JSON or ?format=text
GET /api/v1/gaming/sessions/{hex}/evidence Evidence bundle (zip + directory)
POST /api/v1/gaming/mitigate Closed-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)

Method Path Description
GET /api/health Service health (no auth)
GET /api/v1/devices List devices + allow status
POST /api/v1/devices/{mac}/allow Grant internet
POST /api/v1/devices/{mac}/deny Revoke internet
POST /api/v1/firewall/discover Rescan DHCP/ARP + reload rules
POST /api/v1/firewall/reload Re-apply nft rules
GET /api/v1/firewall/status NAT, shield, allowlist summary
POST /api/v1/shield/enable { "level": "normal" }
POST /api/v1/shield/relax Disable packet shield
GET /api/v1/gaming/match-cockpit Unified 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