Skip to content

Installation

DevInBlack001 edited this page Sep 18, 2026 · 4 revisions

Installation

For the 1.x line. Running 0.5.5 or earlier? See Installation 0.x.

Requirements

Operating system. Linux. Stage 1 uses libpcap for raw capture and Stage 2 shells out to iptables and ipset, so neither works on macOS or Windows. The installer supports apt and dnf based distributions and installs systemd units.

Privileges. Root, for packet capture and firewall control.

Hardware. Modest. The sensor is a few threads doing arithmetic. What matters is that the machine sits on the traffic path.

The installer handles the package dependencies itself, but for reference:

Component Needs
Stage 1 Rust toolchain, libpcap headers
Stage 2 Python 3, pip, venv
Enforcement iptables, ipset, the kernel hashlimit module
TLS openssl, optional but recommended
Kernel capture LLVM and clang, optional

The last row is for the kernel level capture backend. The installer sets it up when the pieces are available, choosing versions that match what your distribution ships. If they are not, the sensor still installs and runs using the standard capture path, and the installer says so rather than failing.

Network Placement

This is the part that most often goes wrong, so read it before installing.

FLOD only sees traffic that is routed through it. If the traffic source and the protected host sit on the same bridge and the same subnet, they talk directly at Layer 2. The virtual switch forwards frames between their ports and the gateway never sees a single packet, even if it is configured as their default gateway.

The working layout puts them in different subnets with the gateway routing between:

[ Traffic source ]            [ FLOD gateway ]           [ Protected host ]
   Subnet A                    routes A to B                 Subnet B
      |                             |                            |
   [bridge 1] <-------------> [ingress iface]                    |
                              [egress iface] <-----------> [bridge 2]

Because the two ends are on different subnets, traffic is forced through the gateway. Capture runs on the ingress interface, where traffic first arrives.

The egress interface is optional. Configuring it lets FLOD compare what arrived against what was forwarded, which is how it measures the drop rate its own enforcement is achieving.

Install

Clone the repository and run the installer:

git clone https://github.com/DevInBlack001/ddos-reduction-system.git
cd ddos-reduction-system
sudo bash scripts/install.sh --interface ens19 --victim-ips 10.0.0.3,10.0.0.4

Replace the interface with your ingress interface and the addresses with the hosts you are protecting.

To protect a whole subnet instead of a list:

sudo bash scripts/install.sh --interface ens19 --victim-subnet 10.0.0.0/24
Option Purpose
--interface <IFACE> Ingress interface to capture on
--victim-ips <IPs> Comma separated list of protected hosts
--victim-subnet <CIDR> Protect an entire range instead
--no-service Skip systemd unit installation

The installer builds Stage 1 in release mode, which takes a few minutes on first run.

What It Does

  1. Installs system packages
  2. Installs the Rust toolchain into the invoking user's own ~/.cargo, not root's, and builds Stage 1 as that user rather than as root
  3. Installs the built binary to /usr/local/bin/ddos_stage1
  4. Copies Stage 2's code and creates its Python virtual environment under /opt/flod/stage2, root owned, not left in the checkout: the account that ran git clone should not be able to modify the code or the venv the root owned service later trusts and executes
  5. Creates /var/lib/flod, also root owned, for the database, the trained models, and Stage 2's JSON configuration
  6. Generates a self signed TLS certificate in /etc/ddos_stage2/tls
  7. Writes systemd units for both services

The checkout itself is left as source only after this. Stage 2 runs from /opt/flod/stage2, never from the directory you cloned into.

Create the Administrator Account

There is no default password. The account must be created before the dashboard will let anyone in. install.sh already does this as its last step, but to do it again later, run it the same way the installer does, against the installed copy, not the checkout:

sudo DB_PATH=/var/lib/flod/stage2.db /opt/flod/stage2/venv/bin/python3 /opt/flod/stage2/setup_admin.py

It prompts for a username and password, and will generate a strong password if you press Enter at the prompt. Write it down; it is stored only as a bcrypt hash.

Start the Services

sudo systemctl enable --now ddos-stage2
sudo systemctl enable --now ddos-stage1

Start Stage 2 first. It owns the socket that Stage 1 connects to.

Check both came up:

systemctl status ddos-stage1 ddos-stage2

Log In

Open https://<gateway-ip>:8000 in a browser.

The certificate the installer generates is self signed, so the browser will warn on first connect. That is expected. Click through, or replace /etc/ddos_stage2/tls/cert.pem and key.pem with a certificate issued for that host.

If no certificate exists, Stage 2 refuses to start rather than fall back to plain HTTP, since credentials and session cookies would otherwise travel unencrypted. Setting FLOD_ALLOW_INSECURE_HTTP=1 opts back into plain HTTP explicitly, for a trusted lab network or local testing only.

Verify It Is Working

Watch the sensor:

journalctl -fu ddos-stage1

Every few seconds it prints a capture status line:

Capture: status | interface=ens19 | raw_captured=23535 | timeouts=0 |
parse_failed=0 | non_ip=0 | truncated=0 | forwarded=23535

raw_captured climbing means packets are arriving. forwarded should track it closely; that is the count reaching analysis. If raw_captured stays at zero, traffic is not reaching the interface, and the network placement section above is where to look.

On --capture-mode kernel the equivalent line reads:

Kernel: status | interface=ens19 | ingress=23535 | egress=23180 |
sources=412 (0.6% of map) | flows=88 | drains=20 | errors=0

The sensor then spends a warm up period learning your baseline before it will flag anything. Until it finishes, no enforcement happens by design.

Optional: Calibrate The Detection

The defaults work, and the sensor relearns your traffic baseline on its own, so this is not a required step. If ordinary traffic starts getting flagged, let the system measure your network rather than guessing at values:

sudo python3 scripts/calibrate.py --auto-debug --apply

It samples 1000 ordinary windows per protected host, roughly 8 to 17 minutes, and writes what it finds to /etc/ddos_stage1/tuning.env. Run it without --apply to see the numbers first, and --reset to undo it. Configuration covers the options.

Updating

sudo bash scripts/update.sh

Rebuilds Stage 1, copies the updated Stage 2 code into /opt/flod/stage2, updates Python dependencies there, migrates the database, and restarts both services. Runtime state, the database, the whitelist, the target list, and the saved configuration, lives in /var/lib/flod, separate from the code, so re-running the installer or the updater does not touch your accounts or history.

If you sync your own checkout to the machine before running the installer or updater (rather than cloning directly on it), exclude your local build artifacts and virtual environment so they are not copied somewhere they do not belong:

rsync -avh --exclude="venv" --exclude="target" --exclude=".git" \
      --exclude="*.db*" --exclude="*.log" --exclude="__pycache__" \
      ddos-reduction-system user@host:~/

That copies source only. The installer or updater still does the real work of putting Stage 2 into /opt/flod/stage2 and its state into /var/lib/flod on the target machine.

Uninstalling

sudo bash scripts/uninstall.sh

Removes binaries, the virtual environment, service units, and the socket. Add --remove-build to clear the build cache, and --remove-rust to remove the toolchain as well.

Clone this wiki locally