Shieldlist

Install the controller

The controller is one static binary with a SQLite store; it runs on any Linux with systemd. Pick a machine that the servers can reach on port 17453 — usually not one you protect, though it can share a machine with an agent.

Install the package

On Debian and its derivatives:

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

stable carries the releases. There is also a dev suite with our development builds: ahead of the releases, and expected to break.

The package creates the shieldlist system user, writes a starter tree under /etc/shieldlist/controller, installs the unit and starts the service. For other systems, or by hand, see Installing.

One machine only? You may not need a controller at all: see the standalone agent. The agent protects a machine by itself, and enrolling it later keeps its configuration.

Put the Web UI behind TLS

The API and the Web UI listen on 127.0.0.1:17454 and expect a reverse proxy with a certificate in front; the agents' port, :17453, needs nothing — the controller signs its own certificate and the agents pin it.

nginx and certbot's nginx plugin first, if they are not there — without the plugin, --nginx is not a flag certbot knows:

apt install nginx certbot python3-certbot-nginx      # Debian, Ubuntu
dnf install nginx certbot python3-certbot-nginx      # Red Hat and its family

Then the vhost, in /etc/nginx/sites-available/shield.example.net.conf on Debian and Ubuntu, or /etc/nginx/conf.d/shield.example.net.conf on Red Hat and its family, where there is no symlink to make:

server {
    server_name shield.example.net;
    listen 80;
    listen [::]:80;
    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;
        proxy_read_timeout 300s;
    }
}

proxy_read_timeout matters: the Web UI holds long requests, and nginx's default of sixty seconds cuts them.

ln -s /etc/nginx/sites-available/shield.example.net.conf /etc/nginx/sites-enabled/
nginx -t && systemctl reload nginx
certbot --nginx -d shield.example.net --redirect

certbot adds the certificate, the listen 443 ssl lines and the redirection from 80 in place, and renews on its own. The name must already resolve to this machine: certbot proves you own it over the port 80 you have just opened.

Through a firewall: the agents' port must be reachable from every protected machine to this controller — outbound from the agent, inbound here. Nothing goes the other way: the controller never opens a connection to an agent, so an agent behind NAT with no inbound rule at all works. The console's port (443 through your proxy) is for people, not agents.

Create the first account

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

Twelve characters at least, and there is a reason it is strict: an account is never locked out, however many times its password is refused. Locking accounts would hand an attacker a way to lock you out; the refusals are logged instead, and a rule of your own can ban whoever collects them. A short password with no lockout behind it is the one combination that does not work.

Open https://shield.example.net, sign in. The Web UI is empty: no server yet. It tells you what to do next — a join token, and a command to run on the first machine. That is the next page.

Details — listeners, retention, geolocation, updates, who may lift a ban: Controller → Configuration.