Bring your own NATS
By default pfCentral runs its own NATS broker and sets it up on first start. In external mode it connects to an operator-mode NATS broker that you run, such as a self-hosted cluster or Synadia Cloud. Use it when:
- your team already operates NATS and wants one broker;
- you need several pfCentral replicas for high availability (Kubernetes);
- agents should connect to a broker in a different place from the web server.
If none of these apply, keep the embedded broker. It needs no setup.
New to NATS terms? Read NATS for firewall admins first.
What changes
Section titled “What changes” Embedded External pfCentral creates the operator, You create one account and its keys. accounts, keys and TLS on first start. pfCentral creates nothing on the broker.
agents ──▶ pfCentral :24222 agents ──▶ your broker ◀── pfCentral (×N) │ ▲ └──────┘ auth callout to pfCentral- pfCentral connects with three creds files and signs device passes with a delegated signing key you give it.
- Its JetStream data (the
TELEMETRYstream, thedevice-stateanddevice-presencebuckets) lives in its own account. - It has no access to
$SYS, so offline detection relies on heartbeats only: a cleanly stopped agent shows offline after about 15 seconds instead of at once. - The device flow is the same. Agents enroll over HTTPS, then connect to the broker; the broker asks pfCentral to approve each connection.
Provision the broker
Section titled “Provision the broker”You need one regular (not system) account for this pfCentral install.
-
Create the account with JetStream enabled (memory and disk storage, streams and consumers).
-
Add a scoped signing key for agents. Register it as a user scope with role
agentand this template:Subjects Publish allow pfsense.{{tag(device_id)}}.>,$SRV.>,pf.presence.{{tag(device_id)}},_INBOX.>Subscribe allow _INBOX.>,pfsense.{{tag(device_id)}}.>,$SRV.>pfCentral tags each device pass with
device_id:<uuid>, so{{tag(device_id)}}fences each device to its own subjects. Agents must publish to_INBOX.>because they reply to the server’s requests in the same account. -
Create three users and their creds files:
User Purpose Auth user? app pfCentral’s own connection Yes callout the authorization callout service Yes sentinel the shared login agents knock with No -
Turn on the authorization callout for the account, with the callout user’s and app user’s public keys, and allow only this account. The app and callout users must be listed as auth users so their own connections skip the callout. The sentinel must not be, so agent connections trigger it.
-
Give pfCentral the three creds files and the seed (
.nk) of the signing key from step 2.
With nsc on a self-hosted broker this is roughly nsc add account, nsc edit account --js-mem-storage -1 --js-disk-storage -1 …, nsc edit account --sk generate with a scope, nsc add user three times, nsc generate creds, and pushing the account to your resolver. On Synadia Cloud you do the same steps in the control plane.
Configure pfCentral
Section titled “Configure pfCentral”| Variable | Value |
|---|---|
PFCENTRAL_NATS_MODE | external |
PFCENTRAL_NATS_URL | Broker URL, tls://nats.example.com:4222 |
PFCENTRAL_NATS_CREDS_FILE | app creds |
PFCENTRAL_NATS_CALLOUT_CREDS_FILE | callout creds |
PFCENTRAL_NATS_SENTINEL_CREDS_FILE | sentinel creds |
PFCENTRAL_NATS_SIGNING_KEY_PATH | agent signing key seed |
PFCENTRAL_NATS_RESOURCE_PREFIX | Optional. Prefix for stream and bucket names if two installs share one account. Prefer one account per install. |
pfCentral stops at start if a file is missing, if the creds belong to different accounts, or if one has expired. The first start registers the account in the database; later starts reuse it.
Agents get the sentinel creds when they enroll, as in embedded mode. Point their NATS URL at your broker.
Rotating the signing key
Section titled “Rotating the signing key”Register a new scoped key on the account, update PFCENTRAL_NATS_SIGNING_KEY_PATH, and restart pfCentral. Passes signed with the old key expire within an hour; remove the old key from the account after that.