03 / operations

One line in. Text out.

voidgatectl talks to /run/voidgate.sock. Prometheus, if metrics_port > 0, binds 127.0.0.1:9105/metrics.

voidgatectl

Command Effect
status state, armed, rx_pps, rx_bps, drop count, iface
stats XDP counters: rx_pkts, passed, dropped, non_ip, map_full, parse_err
drops installed prefixes with reason and age
arm cfg.armed = 1; re-baseline remote rate snapshots
disarm flush drop_*, cfg.armed = 0, back to IDLE
drop <cidr> manual insert; forces ACTIVE. Reason 1. Not auto-expired.
undrop <cidr> remove one prefix from the drop tree
reload re-read the config file; replace allow/local maps and ports

Drop reasons: 1 manual, 2 policy, 3 aggregate.

Config

Key=value. Empty local_networks means auto-detect from the interface. A non-empty allow_networks replaces the built-in list (metadata, localhost, link-local).

configs/voidgate.conf
interface = eth0
xdp_mode = auto

# IDLE watchdog (aggregate NIC / coarse XDP counters)
wake_pps = 20000
wake_mbps = 1000
idle_poll_ms = 1000
clear_seconds = 30

# ACTIVE policy
threshold_pps = 20000
threshold_mbps = 1000
ban_time = 1900
aggregate_k = 8

local_networks =
allow_networks = 169.254.169.254/32, 127.0.0.0/8, ::1/128, fe80::/10, ff02::/16
allow_ports = 22

remote_map_size = 262144
drop_map_size = 65536
metrics_port = 9105
Key Role
wake_pps / wake_mbps NIC is on fire → arm the gate
threshold_pps / threshold_mbps this remote is part of the attack → install a drop
clear_seconds quiet time required (with empty drop tree) to return IDLE
ban_time seconds a policy/aggregate drop lives; manuals stay
aggregate_k dropped hosts in a /24 or /64 before aggregating
allow_ports TCP ports on the local side (default 22)
metrics_port 0 disables HTTP; otherwise localhost only

Prometheus

When metrics_port is positive, the daemon listens on localhost and serves GET /metrics:

/metrics
# TYPE voidgate_armed gauge
voidgate_armed 0
# TYPE voidgate_rx_packets_total counter
voidgate_rx_packets_total 0
# TYPE voidgate_rx_bytes_total counter
voidgate_rx_bytes_total 0
# TYPE voidgate_dropped_packets_total counter
voidgate_dropped_packets_total 0
# TYPE voidgate_map_full_total counter
voidgate_map_full_total 0
# TYPE voidgate_drop_prefixes gauge
voidgate_drop_prefixes 0
# TYPE voidgate_rx_pps gauge
voidgate_rx_pps 0

ACTIVE policy, short

Each tick, remotes over threshold become /32 or /128. Dense clusters become /24 or /64. Userspace will not install a prefix that covers the VM itself or the allow list. On disarm, remote_* stays; the next arm re-baselines snapshots so leftover counters are not a phantom flood.