Skip to content

Configuration 0x

AbdullahArmiyao edited this page Aug 15, 2026 · 1 revision

Configuration (0.x)

For the 0.x line, which ended at 0.5.5. The detection tuning flags added in 1.x are not available here. Running 1.x or later? See Configuration.

There are three places settings live: the Stage 1 service unit, the dashboard, and a few JSON files in stage2/.

Stage 1 Sensor

The sensor is configured by its command line, written into the systemd unit at /etc/systemd/system/ddos-stage1.service. Edit the ExecStart line, then:

sudo systemctl daemon-reload
sudo systemctl restart ddos-stage1
Flag Default What it does
--interface <IFACE> required Ingress interface to capture on
--egress-interface <IFACE> none Second interface, enables drop rate measurement
--victim-ips <IPs> none Comma separated protected hosts
--victim-subnet <CIDR> none Protect a range instead of a list
--k <FLOAT> 2.0 Anomaly sensitivity multiplier
--alpha <FLOAT> 0.125 Rate smoothing factor
--socket <PATH> /run/ddos_stage1/stage1.sock IPC socket
--baseline-path <PATH> /var/lib/ddos_stage1/baselines.json Where the learned baseline is saved
--baseline-ttl-secs <N> 3600 Reject a saved baseline older than this
--no-filter off Capture everything, for testing only
--log-file <PATH> none Also write logs to a file

Set RUST_LOG=debug in the unit's environment for per window detail.

The k Multiplier

This is the main sensitivity control. The sensor flags a window when the rate exceeds mean + k * sigma, or entropy falls below mean - k * sigma.

A smaller k puts the boundary closer to the average, so more windows are flagged. A larger k demands a bigger deviation before anything fires.

Raise it if you are seeing anomalies on traffic you know is normal. Lower it if attacks are getting through. Change it in steps of half a point and watch the journal before changing it again.

Training Mode

To capture labelled data for retraining the classifier:

--train-csv /path/to/output.csv --label 0

Labels are 0 for normal, 1 for flash crowd, 2 for DDoS. In this mode every post warm up window is written to the CSV, not just the anomalous ones. Run one session per traffic class, then train with stage2/train.py.

Enforcement Tuning

These live in stage2/enforcement_config.json and are editable from the dashboard's firewall page. Anything not present in the file falls back to its default, so an older file keeps working after an update.

Setting Default Meaning
dominant_ip_ratio_block_threshold 0.40 How concentrated traffic must be on one source before that source alone justifies a block
dominant_ip_ratio_extreme_threshold 0.75 Above this, the window is classified as an attack regardless of entropy
block_rate_floor_pps 300.0 A source must exceed this to be blocked, whatever the learned baseline says
ratelimit_rate_floor_pps 50.0 The same floor for the softer rate limit tier
block_sigma_multiplier 10.0 How far above baseline a single source must sit to be blocked
block_hysteresis_windows 2 Consecutive attack windows required before a hard block
block_duration_seconds 3600 How long a block lasts
ratelimit_duration_seconds 3600 How long a rate limit lasts
ratelimit_hashlimit_pps 50 The packets per second cap enforced on rate limited sources

The two floors exist to stop a near idle host producing an absurdly low bar. If a protected host normally receives two packets per second, its learned baseline would otherwise let ten packets per second look like a flood.

block_hysteresis_windows applies only to hard blocks. Rate limiting is not gated by it, on the reasoning that throttling a legitimate source is recoverable and blocking one is not.

Changing ratelimit_hashlimit_pps rewrites the live iptables rule, since the cap is part of the rule itself and cannot be edited in place.

Enforcement Tiers

Understanding what fires when makes the settings above easier to reason about.

Tier 1, dominant source. One source is carrying most of the traffic and is sending far above baseline. Blocked outright.

Tier 2, per source escalation. Individual sources above their own threshold are blocked, after the hysteresis window count.

Tier 3, soft rate limit. Sources over the rate limit floor are throttled rather than blocked.

Tier 4, aggregate fallback. The window is clearly an attack but no individual source stands out. Everything contributing is rate limited, nothing is blocked.

The progression is deliberate. Blocking is only used where attribution is confident.

Protected Hosts

Managed from the dashboard's targets page, stored in stage2/victims.json.

Adding a host here tells Stage 2 which addresses to track and report on. It does not change the sensor's capture filter, which comes from the service unit. If you add a target that the sensor is not filtering for, no traffic to it will ever be seen. Keep the two in step.

Whitelist

Addresses on the whitelist are never blocked and never rate limited, at any tier. Stored in stage2/whitelist.json, managed from the firewall page.

Put your own management address here before you do anything else. Blocking yourself out of the gateway is the most common self inflicted problem, and recovering means console access to flush the ipset by hand.

Shared and NAT Addresses

Stored in stage2/shared_ips.json.

An address marked as shared fronts many hosts, so dropping it entirely would cut off every legitimate user behind it. When enforcement decides to block an address on this list, it rate limits instead. The attacker's share is capped and everyone else keeps working.

Mark your NAT and CGNAT egress points here. FLOD cannot detect them on its own, because from the outside a NAT gateway and a single busy host look identical.

Alerts

Configured on the dashboard's alerts page, stored in stage2/alerts_config.json with owner only permissions.

Discord needs a webhook URL from your server's channel settings.

Email uses SMTP with STARTTLS. For Gmail you need an app password, not your account password, which requires two factor authentication to be enabled on the account first.

Alerts fire on classification changes into and out of an attack state, and on hard blocks, with repeats for the same address suppressed for as long as the block lasts. Soft rate limits do not alert, since under load they would be constant.

There is a test button for each channel so you can confirm delivery without waiting for a real attack.

Alert failures are logged and swallowed. A broken webhook will never interfere with enforcement.

File Locations

Path Contents
stage2/stage2.db Accounts, incident log, metrics history
stage2/victims.json Protected hosts
stage2/whitelist.json Never enforced against
stage2/shared_ips.json NAT egress points
stage2/enforcement_config.json Tuning above
stage2/alerts_config.json Webhook and SMTP settings
/var/lib/ddos_stage1/baselines.json Learned baseline, survives restart
/run/ddos_stage1/stage1.sock IPC socket
/etc/ddos_stage2/tls/ Certificate and key

The files holding credentials or secrets are owner only. They protect against other local accounts, not against root, and both services run as root.

Clone this wiki locally