Skip to main content
Levelrail can manage allow and deny rules for the control plane host’s own ufw firewall (ufw is the firewall front end that ships with Ubuntu). You declare rules as records (a port, a protocol, an optional source, an action), and a reconciler changes ufw to match them. Edit the record and the host follows, like everything else on the platform. This is opt-in and narrow. If you never add a rule, nothing on the host changes.

What it does and does not touch

  • Only tagged rules: every rule the platform creates carries a ufw comment prefix derived from the brand short name (levelrail: by default, see White-labeling). Sync only adds and removes rules carrying that prefix. Rules you created yourself with ufw are never changed or deleted.
  • Enables the firewall only when you ask: nothing is switched on automatically. Use Settings, Firewall, Turn on firewall (or levelrail-cli firewall enable) and the platform allows SSH first, then the control plane ports and HTTP/3, and only then runs ufw --force enable. It never changes the default policy by itself, and if any allow step fails, the firewall stays off. If ufw is installed but inactive, rules are stored but not applied until you turn it on.
  • Only ufw, only the local host: if ufw is not installed (you use firewalld, nftables, iptables or a cloud security group), nothing is applied and the reconciler reports that as informational, not a failure. Rules are stored for the control plane host. Per-node rules for remote nodes are not supported yet, and a rule pinned to a remote node would be skipped and logged.
  • Not the installer’s firewall step: install.sh can allow SSH, 80 and 443 once with LEVELRAIL_CONFIGURE_UFW=1 (see Installing). That is a one-time script action. This page covers the ongoing, managed rules.

The lockout guard

Levelrail refuses a deny rule, or an allow rule restricted to a source CIDR, on a port the control plane itself needs. The protected ports are the ones this instance is actually configured to use:
  • the management API address (APP_HTTP_ADDR),
  • the agent gRPC address (APP_AGENT_ADDR),
  • the ingress HTTP address (APP_INGRESS_HTTP_ADDR),
  • the ingress HTTPS address (APP_INGRESS_HTTPS_ADDR).
With defaults these are 8080, 9443, 80 and 443. An unrestricted allow on a protected port is accepted. The check runs when you create the rule (the API returns a validation error) and again in the reconciler as a second line of defense. A control plane that has locked itself out cannot reopen itself, so this is always refused.

Turn the firewall on or off

The switch needs the root ability and is audit logged. Turning it on first shows the exact commands, then runs them in order: SSH, the management, agent and ingress ports, and 443/udp for HTTP/3, followed by ufw --force enable. The onboarding Server check offers the same button, so a new server never needs a command pasted into a terminal. SSH is assumed to be on port 22. If yours is not, set APP_FIREWALL_SSH_PORTS (comma separated) on the control plane before turning the firewall on.
The API is GET /api/v1/firewall/host, POST /api/v1/firewall/host/enable and POST /api/v1/firewall/host/disable, where both POSTs accept {"dry_run": true}.

Add and remove rules

Open Settings, then Firewall. The page lists each rule with its action, port, protocol, source and label, and shows the host’s firewall preflight result from the system doctor. Use the add action to create a rule. Creating a deny rule, or an allow rule restricted to a source, shows a confirmation that explains it will close or narrow a port.
A source CIDR must parse as a valid CIDR. A source of 0.0.0.0/0 is treated the same as no source (any source).

How rules are applied

Creating or deleting a rule nudges the reconciler, which reads every stored rule, re-validates each against the protected ports, and syncs ufw: it adds tagged rules that are missing and removes tagged rules that no longer have a record. Each applied rule’s comment is the prefix plus rule:<id>, so you can match a ufw status line back to its record. The reconciler reports one of these outcomes as the firewall controller’s status:

Published container ports

ufw does not cover ports Docker publishes: they skip the INPUT chain. The Exposure audit lists which of your containers are reachable from outside and can restrict them with DOCKER-USER rules.

Security overview

Fresh-box hardening checklist and the doctor’s firewall check.

Domains and ingress

Ports 80 and 443 for ingress and ACME.
Last modified on October 12, 2026