Skip to content

Plan your deployment

Day 0 is everything you decide before the first firewall connects. Most choices are easy to change later. Three are not: the hostname agents dial, the token pepper, and whether you use NATS TLS. Decide those now.

Browsers reach the web UI over HTTPS. Firewalls connect outbound to NATS on port 24222 and to HTTPS once for enrollment. The server reaches PostgreSQL and, optionally, an SMTP relay. your server network Admins' browsers office, VPN, anywhere pfSense + agent one per site Reverse proxy TLS for the web UI pfCentral server :2808 UI, API, /enroll :24222 NATS for agents state dir: keys, CA, creds Postgres :5432 SMTP optional HTTPS 443 NATS 24222, outbound, TLS HTTPS once: enroll + CA ✕ nothing connects in to a firewall
fig. — network flows for a typical install
FromToPortWhenNotes
Admins’ browsersReverse proxy443AlwaysHTTPS for the web UI and API
Reverse proxypfCentral2808AlwaysPlain HTTP on a private network
FirewallspfCentral24222AlwaysNATS. One long-lived TCP connection per firewall
FirewallsReverse proxy443At enrollmentPOST /enroll and, with TLS, GET /nats-ca.crt
FirewallsGitHub443At install and upgradeDownloads the package and agent. See offline installs.
pfCentralPostgreSQL5432Always
pfCentralSMTP relay or email API587, 465 or 443OptionalOnly with email delivery

Nothing connects to a firewall.

OptionGood for
Docker Compose on one VMMost installs
Kubernetes with one replicaTeams that already run Kubernetes
Kubernetes with several replicasHigh availability. Needs an external NATS broker.

The server is a single Go binary. It needs little CPU or memory: most of its work is passing small messages. PostgreSQL can be a managed service or a container.

Agents store two addresses: the NATS URL (for example tls://pf.example.com:24222) and the enroll URL (https://pf.example.com/enroll). Changing them later means touching every firewall. Use a DNS name you control, not an IP address.

If firewalls reach the server across the internet, publish port 24222 on a public address. If they reach it over a VPN or MPLS, use the internal name.

Agents talk to NATS in plain text unless you turn on TLS. Turn it on for any link you do not fully trust, including site-to-site VPNs you do not run. You need to list every name agents dial in PFCENTRAL_NATS_TLS_HOSTS before the first start with TLS. See TLS for the agent link.

The server speaks plain HTTP only. Put a reverse proxy (Caddy, nginx, Traefik, a cloud load balancer) in front for HTTPS. See HTTPS for the web UI.

Generate these once and store them in your secret manager:

SecretGenerate withNotes
Token pepperopenssl rand -hex 32Set PFCENTRAL_TOKEN_PEPPER_CURRENT and PFCENTRAL_TOKEN_PEPPER_VERSIONS to the same value. Never change it without the rotation procedure.
Database passwordyour usual toolGoes in PFCENTRAL_DATABASE_URL.
Email encryption keyopenssl rand -base64 32Only with email delivery.
First owner passwordyour usual toolOnly for headless installs with PFCENTRAL_SUPERUSER_*.

Two ways:

  • Interactive (default): the server prints a one-time setup link on first start. Open it and create the owner.
  • Headless: set PFCENTRAL_SUPERUSER_EMAIL and PFCENTRAL_SUPERUSER_PASSWORD (12 characters or more). The server creates the owner on first start and prints no link. Good for Terraform or Ansible.

Plan backups of the database and the state volume together from the start. See Back up and restore.

pfCentral serves Prometheus metrics for every firewall at /metrics. Decide whether you will scrape it. See Watch fleet health.

Embedded (default) External
┌───────────────────────────┐ ┌───────────────┐ ┌────────────────────┐
│ pfCentral │ │ pfCentral ×N │────▶│ your NATS cluster │
│ ├ web UI + API │ │ (stateless) │ │ or Synadia Cloud │
│ └ NATS broker :24222 ◀───┼── agents └───────────────┘ └─────────▲──────────┘
└───────────────────────────┘ └── agents
EmbeddedExternal
SetupNothing to doYou provision an account, keys and creds with nsc or your provider
ReplicasOneMany
TLSBuilt-in, self-signed CAYour broker’s TLS
Online detectionInstant on disconnect, 15 s on loss15 s (no $SYS access)

Start with embedded unless you already run NATS or need more than one server replica.