4 Getting Started
Robin edited this page 2026-08-26 21:01:02 +00:00

Getting started

The controller runs on one machine — usually not one it protects, though it may share a machine with an agent — and the agents connect to it. This page takes an empty machine to a console with its first enrolled server.

Install

On Debian and its derivatives, the APT repository (the same one as the agent's; add it on this machine too, it is not there by itself):

curl -fsSL https://repo.lrob.net/apt/shieldlist/shieldlist.gpg -o /usr/share/keyrings/shieldlist.gpg
echo "deb [signed-by=/usr/share/keyrings/shieldlist.gpg] https://repo.lrob.net/apt/shieldlist stable main" > /etc/apt/sources.list.d/shieldlist.list
apt update && apt install shieldlist-controller

The repository is signed with the Shieldlist key, fingerprint B528 0C88 7016 8A94 40A9 05C4 3BB5 8113 CFAB 6DC5 (gpg --show-keys shieldlist.gpg); dev in place of stable gets prereleases and development builds. The same .deb sits on the release page, one per architecture, for apt install ./file.deb.

The package creates the shieldlist system user, writes a starter tree under /etc/shieldlist/controller when there is none (local listeners, no rules yet), installs the unit and starts the service. Elsewhere, or without packages, see Installing — the binary, the user, the tree, the unit, by hand.

Requirements

  • Linux with systemd; one static binary, no database daemon (the store is SQLite in /var/lib/shieldlist/controller).
  • A name and a certificate for the console, if anyone opens it from elsewhere: the API and console listen on 127.0.0.1:17454 and expect a reverse proxy with TLS in front (below).
  • Port 17453 reachable by the agents — the controller mints its own certificate for it, agents pin its fingerprint; nothing else to set up.

Where it listens

/etc/shieldlist/controller/controller.yaml:

listen:
  agents: 0.0.0.0:17453      # the agents; TLS the controller signs itself
  api: 127.0.0.1:17454       # the API and the console; put nginx in front

With nginx and Let's Encrypt on the same machine:

server {
    server_name console.example.net;
    location / {
        proxy_pass http://127.0.0.1:17454;
        proxy_http_version 1.1;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

certbot --nginx -d console.example.net --redirect does the rest. The controller believes X-Forwarded-* from a loopback peer only.

The first person

sudo -u shieldlist shieldlist-controller account -name you    # asks for a password twice

Sign in at the console with that name and password. Later, under Settings → Accounts, add people; a one-time code can be enrolled per account. For scripts and for shield from your desk:

sudo -u shieldlist shieldlist-controller api-token -name deploy

Console commands open the store directly, hence sudo -u shieldlist.

Give it rules

The tree is an agent's tree — parsers/, rules/, policies/, reports/, exemptions.yaml at the root (what every machine gets), the same four directories under packs/<name>/ for each pack (a set given to machines by name) — plus controller.yaml and one agents/<hostname>.yaml per machine: its packs, what makes it differ. The starter tree has no rules: create packs from the console (Rules → New pack…, then rules and patterns in it), copy a working machine's /etc/shieldlist language into packs/<something>/ (minus agent.yaml and secrets.yaml, which stay on the machine), or start from the agent's example pack (/usr/share/shieldlist-agent/examples/ssh/ where the agent is installed). Then:

sudo -u shieldlist shieldlist-controller -t     # validates the tree AND every machine's assembly
systemctl reload shieldlist-controller          # SIGHUP: loaded whole or refused whole, pushed to the agents

-t says, per declared machine, what it would receive and where it differs from the defaults. A machine runs the root and the packs its declaration names — give it packs in the console (Servers → the server → Rules) or packs: [...] in its file. See Configuration for packs, levels, overrides and per-machine switches.

Enrol the first machine

On the controller:

sudo -u shieldlist shieldlist-controller token      # a join token: one use, valid a day

On the machine, running the agent (0.0.4 or newer):

# /etc/shieldlist/agent.yaml
mode: enrolled
controller: https://console.example.net:17453     # or the address, port 17453 either way
shieldlist-agent -t && systemctl restart shieldlist-agent
shield enrol <join-token>

Within seconds the machine appears under Servers with the revision it holds, its bans and detections start arriving, and shield status on the machine shows controller_sync. The machine keeps its own agent.yaml, secrets and local exemptions; the rule language now comes from the controller. Fallback at any time: mode: local, restart — the local files were never touched.

Then

  • The Console: the feed, the map, the panel, bans by hand.
  • Configuration: what each machine runs (levels, overrides, offer/enforce, who may lift), published exemption sources, geolocation, retention, updates.
  • The API, and shield -controller URL -token T for the fleet from any machine.

Report offenders to AbuseIPDB

Reporting is one switch and one key: Settings → Reporting in the console (or abuseipdb: in the controller's secrets.yamlkey, daily_limit, enabled). The controller reports for every server whose declaration says reporting: controller (the default); a server saying reporting: agent reports with the key in its own secrets.yaml.

  • One report per ban, composed from the rule's preset — categories and named fields only, never the raw log line. Recidivism is reported once per episode. Test bans are never reported.
  • The daily limit is your plan's: leave it on auto and the first answer of the day teaches it, or set a number of your own — deliberately below the plan when several machines share one account.
  • Two counts on the page, kept apart on purpose: what this controller sent today, and what AbuseIPDB says is left on the whole account. On a shared account the second moves faster than the first — every machine and tool reporting with the key draws on it.
  • Off keeps the key and sends nothing until it is turned back on. A server reporting with its own key follows its own secrets.yaml (enabled: false there).