// guides

Safeline WAF install guide

15 Aug 2026 · 8 min read
homelabsafelinewafwafsecurityreverse proxy
▶ Watch the companion video
This article pairs with a full hands-on video on the channel.

Covers both installation methods (the official one-line script and manual Docker Compose), initial configuration, and what you actually get out of running it.


1. What SafeLine Is, Briefly

SafeLine is an open-source Web Application Firewall (WAF) from Chaitin Tech, sitting as a reverse proxy in front of your web apps. Instead of relying purely on regex/signature matching like older WAFs (e.g. ModSecurity), its core detection engine does semantic analysis of requests — looking at the actual structure and intent of a payload rather than just pattern-matching known attack strings. In practice this means fewer false positives and better detection of attack variants that don't match a known signature.

It ships as a Community Edition (free, self-hosted) and a paid Pro tier that unlocks some additional features (see Section 5).


2. Requirements

Minimum
OS Linux (this guide: Ubuntu)
Architecture x86_64 (ARM64 supported, but Pro licence required — Community Edition doesn't run on ARM)
Docker v20.10.14+
Docker Compose v2.0.0+
CPU 1 core
RAM 1 GB
Disk 5 GB free

Check your system meets this before starting:

uname -m                              # architecture
docker version                        # Docker version (if already installed)
docker compose version                # Compose version
cat /proc/cpuinfo | grep "processor"  # CPU core count
free -h                                # memory
df -h                                  # disk space
lscpu | grep ssse3                     # confirm SSSE3 instruction support (required)

For anything beyond a toy/test deployment, give it more headroom than the bare minimum — 2 vCPU / 2-4GB RAM is a more realistic comfortable baseline if you're actually proxying live traffic.


3. Method 1 — The Official Install Script (Recommended, Fastest)

This is Chaitin's own automated installer. It handles the Docker install (if missing), directory setup, compose file, and environment config in one go.

Step 1: Run the installer

As root (or with sudo):

bash -c "$(curl -fsSLk https://waf.chaitin.com/release/latest/manager.sh)" -- --en

The --en flag sets the installer's language to English. If you want the LTS release track instead of latest, add --lts:

bash -c "$(curl -fsSLk https://waf.chaitin.com/release/latest/manager.sh)" -- --en --lts

The script will: - Install Docker if it isn't already present - Create the SafeLine data directory (default /data/safeline) - Download the compose file and generate a .env with sensible defaults, including a randomly generated Postgres password - Pull images and bring the stack up

Step 2: Get your admin credentials

Once the script finishes, retrieve the auto-generated admin login:

docker exec safeline-mgt resetadmin

This prints the admin username and password to the terminal — copy them somewhere safe immediately, this is the only time they're shown in plain text this way.

Step 3: Log in

Open a browser to:

https://<your-server-ip>:9443

You'll hit a self-signed cert warning on first access — that's expected, SafeLine issues its own cert for the management console. Accept it and log in with the credentials from Step 2.

That's it for a working install. Skip to Section 4 for configuration.


4. Method 2 — Manual Docker Compose Deployment

Use this if you want more visibility/control over what's being deployed, you're integrating it into an existing Compose-based stack, or you just prefer not to run someone else's install script as root (a completely reasonable instinct).

Step 1: Install Docker (skip if already installed)

sudo apt update && sudo apt upgrade -y
sudo apt install -y ca-certificates curl gnupg lsb-release
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo systemctl enable --now docker

Step 2: Create the SafeLine directory

sudo mkdir -p /data/safeline
cd /data/safeline

(You can use a different path — just be consistent with SAFELINE_DIR in the .env file below.)

Step 3: Download the Compose file

sudo wget "https://waf.chaitin.com/release/latest/compose.yaml"

Step 4: Create and populate the .env file

sudo touch .env
sudo nano .env

Paste in:

SAFELINE_DIR=/data/safeline
IMAGE_TAG=latest
MGT_PORT=9443
POSTGRES_PASSWORD={your-strong-password-here}
SUBNET_PREFIX=172.22.222
IMAGE_PREFIX=chaitin
ARCH_SUFFIX=
RELEASE=
REGION=-g
MGT_PROXY=0

Notes on the fields that actually matter to you: - POSTGRES_PASSWORD — set this yourself to something strong, don't leave it as a placeholder - MGT_PORT — the port you'll access the web UI on; change if 9443 clashes with something else on your host - SUBNET_PREFIX — the internal Docker network range SafeLine's containers use; only worth changing if it collides with an existing network on your host - ARCH_SUFFIX — leave blank for x86_64; set to -arm if deploying on ARM (and remember: ARM requires a Pro licence, Community Edition won't run) - RELEASE — leave blank for the latest rolling release, or set to -lts if you want the LTS track for stability over bleeding-edge features - MGT_PROXY — leave at 0 unless you're putting the management console itself behind another reverse proxy layer

Step 5: Bring it up

sudo docker compose up -d

Step 6: Get admin credentials and log in

Same as Method 1:

sudo docker exec safeline-mgt resetadmin

Then browse to https://<your-server-ip>:9443 and log in.


5. Initial Configuration

Once you're into the dashboard, here's the practical setup order.

5.1 Add your first protected application

Applications → Add Application: - Website Name — a label for yourself - Domain — the public domain/hostname this app answers on - Upstream — the actual backend address SafeLine forwards traffic to once it's passed inspection (e.g. 192.168.1.100:3000) - SSL — see below

5.2 SSL / certificates

SafeLine terminates SSL itself, so you don't need a separate reverse proxy handling TLS in front of it. Options: - Auto (Let's Encrypt) — SafeLine requests and renews certs automatically, provided the domain correctly resolves to this server and port 80/443 are reachable for the ACME challenge - Custom cert — upload your own if you're using an internal CA, a wildcard cert, or a cert from another provider - Wildcard domains are supported either way

5.3 Protection mode

Three modes, set per-application:

Mode Behaviour When to use
Monitor Logs suspicious/matching traffic but doesn't block anything Rolling out to a new app — run in Monitor first so you can see what would have been blocked before you risk false positives on real traffic
Balanced Blocks clear attacks, tuned for a reasonable false-positive rate Default for most production use
Strict Maximum detection sensitivity Higher-risk targets (admin panels, auth endpoints) where you'd rather over-block than under-block — expect to tune exceptions

Practical tip: don't deploy straight into Strict on a live app. Start in Monitor, watch the logs for a few days, move to Balanced, then only push specific applications to Strict once you've confirmed legitimate traffic isn't getting caught.

5.4 Rate limiting (HTTP Flood settings)

Configurable globally or per-application, with three limiting types: - Access Limiting — general request frequency caps - Attack Limiting — thresholds specifically on requests that match attack patterns (e.g. block an IP for 30 minutes after 5 detected SQLi attempts in 60 seconds) - Error Limiting — caps on repeated error responses (403/404/500), useful for catching scanners/enumeration attempts

Actions available: hard block, or trigger an anti-bot challenge instead of an outright block — useful when you want friction rather than a full lockout for borderline cases.

5.5 Anti-bot / challenge features

  • Anti-Bot Challenge — a JavaScript proof-of-work challenge that real browsers solve transparently in the background but headless scrapers and simple scripts fail
  • Authentication Challenge — a separate gate (password prompt) you can put in front of specific paths, e.g. an admin panel or staging environment, to hide it from casual scanning even before someone gets to a login form
  • Dynamic HTML/JS encryption — obfuscates client-side identifiers per request, making it harder for scrapers and credential-stuffing tools to reliably target form fields

5.6 Geo-blocking

Block by country where your application has no legitimate business outside a specific region — a blunt but effective tool for cutting a large chunk of opportunistic scanning/attack traffic if your user base is genuinely geographically limited.


6. Benefits — What You Actually Get

  • Semantic detection over pure signature-matching — better at catching attack variants that don't exactly match a known pattern, generally with fewer false positives than older regex-based WAFs
  • Self-hosted, full data control — nothing routes through a third-party edge/CDN; all inspection happens on infrastructure you control
  • Free tier is genuinely usable — Community Edition covers core WAF protection, rate limiting, and the dashboard; you're not crippled without Pro
  • SSL termination built in — one less moving part; you don't need a separate reverse proxy purely for cert handling
  • Virtual waiting room — for legitimate traffic spikes (not just attacks), SafeLine can queue and gradually release users rather than letting the backend fall over
  • Real operational dashboard — logging and analytics that are actually usable day-to-day, not just a raw log dump
  • Active development — frequent releases; recent changes include per-path rate limiting policies and expanded custom rule matching conditions (response body, full request/response headers)

Worth knowing before you commit

  • Origin/jurisdiction — Chaitin Tech is a China-based company; if outbound telemetry/update traffic matters to your threat model, it's worth checking what the container communicates with (a simple tcpdump/Wireshark capture on the host will show you)
  • ARM support requires Pro — Community Edition is x86_64 only
  • Some features are Pro-gated — verify current gating against SafeLine's pricing page directly, as this has shifted between releases; don't rely on older reviews for what's free today

7. Quick Reference — Useful Commands

# Get/reset admin credentials
docker exec safeline-mgt resetadmin

# Check container status
docker compose ps

# View logs
docker compose logs -f

# Update to latest version (manual Compose method)
cd /data/safeline
mv compose.yaml compose.yaml.old
wget "https://waf.chaitin.com/release/latest/compose.yaml"
docker compose pull
docker compose up -d

# Update via the manager script (works regardless of install method)
bash -c "$(curl -fsSLk https://waf.chaitin.com/release/latest/manager.sh)" -- --en

8. Which Method Should You Actually Use?

  • Script method — genuinely fine for most homelab/personal use. It's Chaitin's own tooling, it's what most of the write-ups you'll find online use, and it gets you running in under 5 minutes.
  • Manual Compose — better if you want to see exactly what's being deployed before it touches your system, you're folding this into an existing Compose-managed stack, or you're the sort of person who reads scripts before piping them into bash (no judgement — that instinct is correct).

Either way you land on the same Docker Compose stack underneath — the script just automates steps 1-6 of the manual method for you.

← All guides posts Subscribe on YouTube →