Documentation

CloudFirewall Docs

Everything you need to deploy the control plane, install agents on your servers, manage firewall rules, and keep your fleet secure.

Getting Started

CloudFirewall has two components: a dashboard (Nuxt 4 control plane with Postgres) and a lightweight Go agent that runs on each Linux host you want to protect.

The typical workflow is:

  1. Deploy the dashboard and database.
  2. Create an account through the setup wizard.
  3. Generate an install token in the dashboard.
  4. Run the install script on each target server.
  5. Define firewall rules — agents pull and enforce them automatically.

Prerequisites

Control Plane

  • Docker & Docker Compose (for the recommended setup)
  • Or: Node.js 20+ and a PostgreSQL 15+ instance

Agent Hosts

  • Linux (x86_64)
  • curl for the install script
  • systemd for service management
  • nftables / nft binary (required when applying firewall rules)

Deploy the Control Plane

The fastest way to get running is with Docker Compose. Clone the repository and start the stack:

git clone https://github.com/your-org/CloudFirewall.git
cd CloudFirewall
docker compose up -d

This starts a Postgres database (with the schema from deploy/postgres/init.sql) and the Nuxt dashboard.

Open the dashboard in your browser and complete the setup wizard to create your account.

Manual Setup

If you prefer running outside Docker:

# Start Postgres and apply the schema
psql -f deploy/postgres/init.sql

# Install dashboard dependencies
cd dashboard
npm install

# Set your DATABASE_URL
export DATABASE_URL="postgresql://user:pass@localhost:5432/cloudfirewall"

# Start the dashboard
npm run dev

Install the Agent

Once your dashboard is running, go to Tokens in the sidebar and generate a new install token. Then run the install script on each target host:

curl -fsSL https://your-dashboard-url/install-agent.sh | \
  DASHBOARD_URL=https://your-dashboard-url \
  INSTALL_TOKEN=your-token-here \
  sudo bash

The install script will:

  1. Download the agent binary to /opt/cloudfirewall/.
  2. Write an environment file to /etc/cloudfirewall/agent.env.
  3. Create and start a systemd service (cloudfirewall-agent.service).
  4. Register the agent with the dashboard (consuming the install token).

The script is idempotent — running it again updates the binary and restarts the service without losing existing state.

Default Firewall Mode

During installation, you'll be asked whether CloudFirewall should become the default firewall for the host. Answering yes will:

  • Disable ufw and firewalld if present.
  • Enable AGENT_APPLY_FIREWALL and AGENT_DEFAULT_FIREWALL.
  • Install nftables input/forward/output hooks in the cloudfirewall table.

These hooks keep a default accept policy. They let CloudFirewall evaluate inbound and outbound rules first, but unmatched traffic is still allowed unless you add a deny rule.

You can also pre-set this non-interactively:

curl -fsSL https://your-dashboard-url/install-agent.sh | \
  DASHBOARD_URL=https://your-dashboard-url \
  INSTALL_TOKEN=your-token-here \
  DEFAULT_FIREWALL=true \
  sudo bash

Enable Default Firewall After Installation

If you skipped default firewall mode during installation and want to enable it later, follow these manual steps:

# 1. Disable conflicting firewalls
sudo systemctl disable --now ufw.service 2>/dev/null || true
sudo systemctl disable --now firewalld.service 2>/dev/null || true

# 2. Enable both flags in the agent environment file
sudo sed -i 's/^AGENT_APPLY_FIREWALL=.*/AGENT_APPLY_FIREWALL=true/' /etc/cloudfirewall/agent.env
sudo sed -i 's/^AGENT_DEFAULT_FIREWALL=.*/AGENT_DEFAULT_FIREWALL=true/' /etc/cloudfirewall/agent.env

# 3. Restart the agent to apply the changes
sudo systemctl restart cloudfirewall-agent

After restarting, the agent will create the cloudfirewall nftables table with input, forward, and output hooks and begin enforcing your inbound and outbound rules. Unmatched traffic remains allowed until you add a catch-all deny rule.

To verify the hooks are active:

sudo nft list table inet cloudfirewall

Verify the Installation

# Check service status
systemctl status cloudfirewall-agent

# View agent logs
journalctl -u cloudfirewall-agent -f

# The agent should appear in the dashboard within seconds

Configuration

Agent configuration lives in /etc/cloudfirewall/agent.env. Key environment variables:

VariableDescriptionDefault
DASHBOARD_URLURL of the CloudFirewall dashboardrequired
INSTALL_TOKEN One-time token for initial registration required on first run
AGENT_STATE_PATHPath to the local state file/var/lib/cloudfirewall/state.json
AGENT_APPLY_FIREWALL Actually apply nftables rules (dry-run if false) false
AGENT_DEFAULT_FIREWALL Install nftables input/output/forward hooks managed by CloudFirewall while keeping default-accept policies false

After changing the environment file, restart the agent:

sudo systemctl restart cloudfirewall-agent

Managing Rules

Firewall rules are created in the dashboard under Rules and are scoped to individual agents. The dashboard supports two rule types:

ACL Rules

Access Control List rules allow or deny traffic based on protocol, port, and source/destination CIDR. Each rule has a priority that determines its order in the generated nftables ruleset.

Rate Limit Rules

Rate limiting rules restrict the number of new connections matching a given filter within a time window.

How Rules Are Applied

  1. You create or update a rule in the dashboard.
  2. The agent fetches its desired config on the next heartbeat (every 5 seconds).
  3. If the config version changed, the agent renders and applies the new nftables ruleset.
  4. The agent reports per-rule telemetry (packet counts) back on heartbeat.

If AGENT_APPLY_FIREWALL is false, the agent logs what it would apply but makes no changes to the host firewall.

The dashboard also includes a dedicated Rules → Test tab for validating a live rule with packet-counter deltas from the agent's next heartbeat.

Testing Rulesets

Use the dashboard's Rules → Test tab when you want to confirm that a specific allow, deny, or rate-limit rule is doing what you expect on a live host.

  1. Select the target agent and choose the rule to test.
  2. Click Capture baseline so the dashboard stores the current packet counters for every enabled rule.
  3. Run the generated probe command from a client that matches the rule's direction plus source and destination CIDRs.
  4. Wait for the next heartbeat, then click Refresh results.
  5. Review the verdict and the observed deltas to see whether the selected rule allowed, blocked, or rate-limited the probe as expected.

What Success Looks Like

  • Allow rule: the probe succeeds and the rule's allowed counter increases.
  • Deny rule: the probe fails or times out and the rule's filtered counter increases.
  • Rate limit: initial packets may be allowed, but repeated probes should eventually increase filtered once the burst or rate cap is hit.

CLI Cross-Check

If you want to validate the host directly while watching the dashboard, keep these commands handy on the agent host:

# Inspect the currently rendered nftables ruleset
sudo nft list table inet cloudfirewall

# Watch the agent pull and apply config updates
sudo journalctl -u cloudfirewall-agent -f

Uninstall the Agent

To completely remove the CloudFirewall agent from a host:

# Stop and remove the service
sudo systemctl stop cloudfirewall-agent
sudo systemctl disable cloudfirewall-agent
sudo rm /etc/systemd/system/cloudfirewall-agent.service
sudo systemctl daemon-reload

# Remove the agent binary and data
sudo rm -rf /opt/cloudfirewall
sudo rm -rf /var/lib/cloudfirewall
sudo rm -rf /etc/cloudfirewall

# If CloudFirewall was your default firewall, flush its nftables table
sudo nft delete table inet cloudfirewall 2>/dev/null || true

# If DNS filtering was enabled, restore the system DNS resolver
sudo resolvectl revert 2>/dev/null || true
# If systemd-resolved is not in use, verify /etc/resolv.conf manually:
cat /etc/resolv.conf

If DNS filtering was active, the nftables dns_redirect chain is removed with the table above. However, if your system's /etc/resolv.conf was modified during install, you may need to restore it to point at your network's default DNS (e.g. nameserver 192.168.1.1 or nameserver 1.1.1.1).

After uninstalling, you can delete the agent from the dashboard on the Devices page to clean up its registration.

Troubleshooting

Agent won't register

  • Check that DASHBOARD_URL is reachable from the host.
  • Verify the install token hasn't already been used — each token is single-use.
  • Check agent logs: journalctl -u cloudfirewall-agent -f

Agent shows as offline

  • Confirm the service is running: systemctl status cloudfirewall-agent
  • Check for network connectivity between agent and dashboard.
  • If the agent was re-registered, it may need a fresh install token if the old identity was invalidated.

Rules not being applied

  • Ensure AGENT_APPLY_FIREWALL=true in the agent environment file.
  • Verify nft is installed and accessible: which nft
  • Check if the agent is in sync — the dashboard shows drift status per device.
  • Use Rules → Test to capture a baseline, run a probe, and verify whether any matching rule counters move.

Agent self-heals on 401/404

If the dashboard returns 401 or 404 on heartbeat or config fetch, the agent automatically clears its local identity and re-registers using the install token (if still set in the environment file). This handles cases where the dashboard database was reset or the agent record was deleted.