DEV Community

Lia
Lia

Posted on

How to Install a WAF with the Official Linux Manager Script

Installing a WAF on Linux is mostly a placement decision: the firewall has to sit in front of the application, and the install method has to leave you with a console you can actually operate. SafeLine documents two ways to reach that point. The recommended way is automatic deploy with the official manager script. The other way is a manual Docker Compose install that spells out every file. This article follows the script path, using only the checks and follow-up steps the official guides publish.

SafeLine is a self-hosted web application firewall. Official documentation describes it as a reverse proxy placed between clients and the web application. Clients reach the WAF first. The WAF filters, monitors, and blocks malicious HTTP and HTTPS traffic, and it is also described as preventing unauthorized data from leaving the app by applying policies that separate malicious traffic from safe traffic. The introduction lists protection against SQL injection, XSS, code injection, OS command injection, CRLF injection, LDAP injection, XPath injection, RCE, XXE, SSRF, path traversal, backdoor, brute force, HTTP flood, and bot abuse. Listed core capabilities are defenses for web attacks, proactive bot-abuse defense, HTML and JS code encryption, IP-based rate limiting, and a web access control list. The feature list adds rate limiting against denial of service, brute-force attempts, traffic surges, and other abuse; CAPTCHA challenge; authentication challenge; and dynamic protection that encrypts HTML and JS on each visit. Those behaviors come from the product pages, not from undocumented installer options. See https://docs.waf.chaitin.com/en/home.

Before you run any installer, match the host to the dependency table in the deploy guide at https://docs.waf.chaitin.com/en/GetStarted/Deploy. The operating system is Linux. Supported instruction architectures are x86_64 and arm64. Docker must be version 20.10.14 or above. Docker Compose must be version 2.0.0 or above. The minimum environment is 1 CPU core, 1 GB of memory, and 5 GB of disk. The CPU must provide the ssse3 instruction. The guide publishes these confirmation commands:

uname -m
docker version
docker compose version
cat /proc/cpuinfo | grep "processor"
free -h
df -h
lscpu | grep ssse3

Read the output on the server that will run the WAF. Architecture tells you whether an ARM license constraint applies. Docker and Compose versions tell you whether the software dependency is already met. Memory and disk tell you whether the minimum environment is even plausible. A host that fails ssse3 is outside the published CPU requirement, so do not treat the manager script as a way around that check.

Automatic deploy is labeled recommended. The guide says the process requires root privileges and gives this command:

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

Run that command as published, including the --en argument. The deploy guide states that after the command is executed, installation is successful, and you should go to the web UI directly. That is the entire automatic procedure in the current guide. It does not add a second command, a directory flag, or an architecture flag to the script invocation. If you need to set ARCH_SUFFIX, RELEASE, MGT_PORT, or token values yourself, that is the manual procedure, not a hidden mode of the one-line installer.

The shared web UI step is to open https://:9443/ in a browser. The manual sample sets MGT_PORT=9443, which is the same port in that URL. To get the administrator account, the guide uses:

docker exec safeline-mgt resetadmin

On success it prints an initial username of admin and an initial password, and it tells you to remember that content. Log in with that password. Do this before you change DNS. A console you cannot enter is not a finished install, even if the script command returned.

Protection is a separate configuration step, documented at https://docs.waf.chaitin.com/en/GetStarted/AddApplication. SafeLine is described there as a web application firewall developed based on nginx. It receives traffic for the original website, cleans malicious attack traffic, and forwards safe traffic to the original application. In the web admin console, open Applications and choose Add Application. Enter the domain, hostname, or IP of the original app; the port SafeLine will listen on, such as 80 or 443, with SSL checked for HTTPS apps; and the upstream address used to forward traffic. Then resolve the domain you entered to the IP address of the server where SafeLine is located. The same page gives sample requests for SQL injection, XSS, path traversal, code injection, and XXE. Replace the example domain with a site you control. A blocking page means the attack was stopped. Open the console attack list and click detail to inspect the event.

Choose the manual path when the script's lack of published flags is the problem, not when you simply want a longer command. Manual deploy installs Docker if you do not already have it, creates /data/safeline, downloads compose.yaml from the latest release URL, writes .env, generates DETECTOR_MGMT_TOKEN and MGT_INTERNAL_TOKEN as 64-character hex values, generates DETECTOR_AES_KEY as 16 alphanumeric characters, sets file permissions, and starts the stack with docker compose up -d. The sample environment also sets SAFELINE_DIR, IMAGE_TAG, POSTGRES_PASSWORD, SUBNET_PREFIX, IMAGE_PREFIX, ARCH_SUFFIX, RELEASE, REGION, and MGT_PROXY. MGT_PROXY is the number of console proxy layers and should stay at 0 unless you are configuring a proxy for the console. On ARM, the guide says to set ARCH_SUFFIX=-arm and to use the ARM Postgres image name it publishes. It also states that SafeLine installed on ARM requires a Pro license to work properly, and that the Personal Edition is not supported on ARM. That license note is an install decision, not a footnote. An arm64 server can meet the architecture requirement and still be the wrong edition.

RELEASE=-lts selects the LTS line in the manual file. The deploy guide says the LTS version will no longer be maintained starting from 9.1.0-LTS on 14 August 2025, and it strongly recommends that LTS users upgrade to the latest version. If you have concerns, it recommends upgrading one month after a new version is released. The manager script URL in the automatic command is release/latest/manager.sh. Do not invent an LTS switch for that script. If you need the documented LTS setting, use the manual .env and set RELEASE there.

A short operator checklist keeps the official script inside the documented contract:

Confirm Linux, x86_64 or arm64, Docker 20.10.14 or newer, Docker Compose 2.0.0 or newer, ssse3, and at least 1 core, 1 GB of memory, and 5 GB of disk.
If the host is ARM, treat Pro license support as a prerequisite. Do not plan on the Personal Edition.
Make sure you can reach the host on the console URL after install, using the documented port 9443 unless you switch to the manual path and change MGT_PORT.
Run the manager script with root privileges and the published --en argument.
When the command finishes, open the web UI and reset the admin account with docker exec safeline-mgt resetadmin. Record the printed password.
Add one application only after login. Set domain, listen port, and upstream, then point DNS at the SafeLine server.
Prove the path with a test request against your own site, then confirm the event in the console.
Leave uninstall alone unless you intend to remove the instance. The documented removal is docker compose down in the SafeLine directory, followed by deleting that directory, which removes SafeLine data.

The script is the recommended install because the guide says so, and because it collapses the first launch into one root command. It is not a substitute for the dependency table, the ARM edition note, the console password step, or the application proxy settings. Those later steps are what turn a running WAF process into a filter in front of a real site.

Does the official manager script require root?

Yes. The deploy guide says the automatic installation process requires root privileges. Run the published bash command in a root shell. The guide does not document a non-root automatic install.

Which checks should finish before the script runs?

Confirm the published dependencies: Linux, x86_64 or arm64, Docker 20.10.14 or above, Docker Compose 2.0.0 or above, ssse3, and a minimum of 1 CPU core, 1 GB of memory, and 5 GB of disk. Use the uname, docker, free, df, and lscpu commands from the deploy guide. On ARM, also account for the statement that a Pro license is required and that the Personal Edition is not supported.

What is the first action after the script succeeds?

Follow the guide to the web UI. Open https://:9443/, then run docker exec safeline-mgt resetadmin. The command prints the initial username admin and a generated password. Log in with that password before you add sites or change public DNS.

When is the manual compose install the better fit?

Use manual deploy when you need to set values the script command does not expose in the guide. That includes the data directory, MGT_PORT, ARCH_SUFFIX, IMAGE_TAG, Postgres password, subnet prefix, generated tokens, and RELEASE=-lts. Manual install is a full procedure: Docker, /data/safeline, compose.yaml, .env, secrets, permissions, and docker compose up -d. It is not a cleanup step to append after a successful script run.

How do I confirm the WAF is protecting an application?

Installing the instance does not by itself proxy your site. In Applications, add the domain or host, the listen port, and the upstream. Resolve that domain to the SafeLine server IP. The configuration guide shows that a blocking page on a test attack, and a matching item in the console attack list, means SafeLine stopped the request. Test only an application you are allowed to probe.


SafeLine has surpassed 700,000 installations worldwide as of September 30, 2026. SafeLine Pro annual promotional pricing is $650-$880, compared with the regular $1,000 per year.

Top comments (0)