Linux Deployment (systemd)

Install CheeseWAF with the one-line installer or an offline release archive, then configure a public HTTPS management entry and one-time setup token.

This guide covers Linux physical servers, cloud instances, and virtual machines. The online installer selects a language, detects the CPU architecture, downloads the latest stable release, verifies its checksum, installs the systemd service when available, and prints the first-setup URLs. Use the offline path when the target host cannot reach GitHub.

1. One-line installation (recommended)

Copy and paste this command. The installer opens an interactive prompt for language selection and then downloads, verifies, and installs the matching server release:

BASH
curl -fsSL https://github.com/LaokeQwQ/CheeseWAF/releases/latest/download/install-linux.sh | sudo bash

When already running as root, omit sudo:

BASH
curl -fsSL https://github.com/LaokeQwQ/CheeseWAF/releases/latest/download/install-linux.sh | bash

The script reads language, install-root, and entry-name input from /dev/tty, so interactive answers are not consumed as script source. For unattended provisioning, set the documented CHEESEWAF_* environment variables and invoke the downloaded script; never put passwords or setup tokens in shell arguments or history.

To install a specific stable or beta tag, set CHEESEWAF_RELEASE (the v prefix is optional):

BASH
curl -fsSL https://github.com/LaokeQwQ/CheeseWAF/releases/latest/download/install-linux.sh \
  | sudo env CHEESEWAF_RELEASE=v0.4.2-beta bash

During the interactive flow, choose an application install root after selecting the language. Entering /opt/cheesewaf, for example, places the binary, Web assets, runtime configuration, data, and logs under bin/, web/, config/, data/, and logs/ beneath that root. Press Enter to keep the split FHS layout shown below. The systemd unit remains under /etc/systemd/system unless CHEESEWAF_UNIT_DIR is explicitly overridden.

For automation, set CHEESEWAF_INSTALL_DIR before invoking the installer. Individual CHEESEWAF_PREFIX, CHEESEWAF_WEB_DIR, CHEESEWAF_CONFIG_DIR, CHEESEWAF_DATA_DIR, and CHEESEWAF_LOG_DIR values take precedence for their respective paths:

BASH
curl -fsSL https://github.com/LaokeQwQ/CheeseWAF/releases/latest/download/install-linux.sh \
  | sudo env CHEESEWAF_INSTALL_DIR=/opt/cheesewaf bash

Install roots must be absolute dedicated directories whose path components contain only ASCII letters, digits, ., _, or -; shared system directories and paths containing shell metacharacters are rejected.

The installer will:

  1. Ask for 中文 or English and check Linux, architecture, disk space, curl, tar, sha256sum, awk, and od prerequisites.
  2. Download the selected server archive from GitHub Releases and verify its single matching SHA256SUMS entry. A failed verification stops before installation or service startup.
  3. Install the binary, Web Console, runtime configuration, and systemd unit, then create the non-login cheesewaf service account.
  4. Generate an HTTPS management listener, a one-time setup token, and a safe entry path. The entry path accepts ASCII letters and digits only; a random value is generated by default, and a custom value is accepted only when it passes the same validation.
  5. Start the service when systemd is available, check the listener and health state, and print the version, architecture, installation paths, service state, public management URL, detected private management URLs, token lifetime, and next steps. Without systemd, the files are installed but the service is reported as not started.

Save the complete setup URL printed at the end. On an interactive terminal the installer prints the public setup URL and the secure-entry URL; it also prints each detected private-address setup URL. In a non-interactive run, secrets are withheld from stdout and stored in the root-only install-secrets.txt receipt; set CHEESEWAF_SHOW_SECRETS=1 only when the output is protected. The token is short-lived and is revoked immediately after first setup. Do not paste the complete URL into tickets, screenshots, shell history, or logs.

2. First setup and public entry

During initialization, open the https:// URL printed by the installer. The setup URL always uses the fixed /setup path:

TEXT
https://PUBLIC_IP:9443/setup#setup_token=ONE_TIME_TOKEN

ONE_TIME_TOKEN is the one-time bootstrap token. The browser reads the token from the URL fragment, clears it from the address bar, and sends it in the X-CheeseWAF-Setup-Token header. The token is never placed in query parameters, cookies, or localStorage.

After setup completes, open https://PUBLIC_IP:9443/SECURITY_ENTRY. The security entry contains ASCII letters and digits only; it is generated by default or accepted as a validated custom value. The entry endpoint signs an access Cookie and redirects to the login page. Keep the setup route and the post-setup security entry as separate paths.

The management plane uses HTTPS and binds publicly by default for this installation path. The installer writes the detected public host to admin.env; set CHEESEWAF_ADMIN_PUBLIC_HOST when the host has no directly assigned public address (for example, behind NAT or a reverse proxy). Restrict security groups, firewalls, and any reverse proxy to trusted administration networks before exposing port 9443 to the Internet. A locally generated certificate may cause a browser warning on first access; replace it with a trusted certificate for production use.

After setup completes, the bootstrap token is invalid. If the URL is lost before an administrator is created, reset it on the host:

BASH
sudo -u cheesewaf cheesewaf setup token reset

Use the new URL printed by the command. The old URL cannot be recovered.

Running the installer again against an existing configuration performs an upgrade. It keeps the existing listener, TLS settings, sites, policies, and security-entry path; choose the same install root or set the same CHEESEWAF_*_DIR overrides so the intended service is upgraded.

3. Verify the installation

BASH
systemctl status cheesewaf --no-pager
ss -ltnp | grep ':9443'
sudo journalctl -u cheesewaf -n 100 --no-pager

Confirm that the version and architecture match the target host and that the expected process owns the management port. After first setup, add the first protected site and configure the data-plane listener from the Console.

Default FHS paths:

PathPurpose
/usr/local/bin/cheesewafMain binary
/usr/local/bin/waf-cliCLI symlink
/usr/share/cheesewaf/webWeb Console assets
/etc/cheesewaf/cheesewaf.yamlRuntime configuration copy
/var/lib/cheesewafData, certificates, and bootstrap state
/var/log/cheesewafAccess and audit logs

With CHEESEWAF_INSTALL_DIR=/opt/cheesewaf, the corresponding application paths are /opt/cheesewaf/bin/cheesewaf, /opt/cheesewaf/web, /opt/cheesewaf/config/cheesewaf.yaml, /opt/cheesewaf/data, and /opt/cheesewaf/logs.

4. Offline or manual installation

On a connected machine, download the architecture-specific .tar.gz, SHA256SUMS, and (when publishing signatures) signature files from GitHub Releases, then transfer them to the target host. Verify the files in the download directory, extract the archive, and run the installer:

BASH
sha256sum --check SHA256SUMS --ignore-missing
tar -xzf cheesewaf-*-linux-*.tar.gz
cd cheesewaf-*-linux-*
sudo ./install-linux.sh

The offline script still asks for the language and entry path locally, generates the setup token, and starts the service; it does not attempt to download another release. On a host without systemd, copy the binary and web/dist into your process manager’s paths and start the service there. Keep a runtime configuration copy and a dedicated data directory; never edit the tracked configs/cheesewaf.yaml template in place.

Do not use unverified binaries, third-party mirrors, or stale installer scripts. A complete Linux archive contains cheesewaf, Web assets, configuration templates, the systemd unit, and this installer; stop and download the archive again if any item is missing.