Documentation

Flood & recon protection

Two layers with a shared blocklist: pf handles rates and floods, Suricata handles signatures, and one rule at the top of the ruleset drops what either one flags.

This is the layer that needs no model and no network. It is modeled on Palo Alto's zone protection profile — flood protection measured in new connections per second, and reconnaissance protection with an interval, a threshold and an action — and it is always on, with sensible defaults pre-filled.

Division of labor

Protection is delivered by two layers that complement each other rather than duplicating each other.

ThreatEnforced byHow
SYN floodpfsynproxy state — the firewall answers SYNs on the host's behalf, so half-open floods never reach it
Per-source connection floodspfmax-src-states and max-src-conn-rate; offenders overload into the blocklist table
Fast port scanspfA high connection rate from one source trips the same rate limit and lands it in the blocklist
Signature scans and host sweepsSuricataA rate filter over the scan ruleset, with the action you choose
Known-bad sourcespfOne block drop quick rule at the very top of the ruleset

The blocklist table is shared. A pf overload and a Suricata block-ip action both land a source in the same table, and a single rule drops everything in it. Entries are bounded by a configurable lifetime, so nothing accumulates forever and nothing needs manual cleanup.

What it renders to

A published service protected by flood limits produces something like this. Note the rule label: it is the rule's own name from the console, which is what makes a live pf log filterable down to one row.

table <rubix_blocklist> persist
block drop quick from <rubix_blocklist>
...
pass in quick on igb0 inet proto tcp from any \
    to <addr_web-server> port 443 \
    synproxy state (max-src-states 500, \
      max-src-conn-rate 100/10, \
      overload <rubix_blocklist> flush global) \
    log label "wan-to-dmz-web"

Reconnaissance actions

The action vocabulary mirrors Palo Alto's, deliberately, because operators already know what these words mean:

  • allow — score it, do nothing.
  • alert — record and surface it.
  • block — drop the offending traffic.
  • block-ip — drop it and add the source to the shared blocklist for the configured duration.

Source exclusions list the addresses that are never scored — your vulnerability scanners, your monitoring, your own probes. Without that list, the tooling you use to check the perimeter spends its life inside the blocklist.

Threat feeds and GeoIP

External blocklists — IP, domain and URL — refresh on a schedule into pf tables and an on-box reputation index, and country matching is available per rule when a GeoIP database is supplied. Feeds carry a role, and the role is the important part:

  • Block feeds are high confidence. A match can drop, and it is a strong signal to the AI layer's confidence model.
  • Suspect feeds are grey. A match raises a score and can lead to throttling, but on its own it never causes an outright block.

Only feeds whose license terms permit redistribution on an appliance ship enabled by default. Others are listed, disabled, with a note — including GeoIP, which stays off until you supply your own MaxMind key.

Status: feedd is shipping. IP EDLs land in pf tables; GeoIP and classify-only feeds are included. Priority updates and threat feeds are a Home+ license. Build status.

Where it lives in the console

Security ▸ DoS Protection holds two panels — flood (SYN proxy toggle, connection-rate thresholds, per-source limits) and reconnaissance (scan and sweep interval, threshold, action) — plus the live blocklist with one-click unblock. Security ▸ Threat Feeds holds the feeds and their roles, and Security ▸ Exclusions the sources that are never scored.