HTTPS for the web UI
The pfCentral server listens on plain HTTP, port 2808. It expects a reverse proxy to handle HTTPS. Agents use the same HTTPS address once, to enroll and to download the NATS CA.
What the proxy must do
Section titled “What the proxy must do”- Terminate TLS for your public name, for example
pf.example.com. - Forward every path to
http://<pfcentral>:2808, keeping theHostheader. - Not buffer responses. The UI keeps server-sent event streams open for live updates. Buffering makes pages look frozen.
- Allow long-lived requests: an idle or read timeout of at least one hour.
- Set
X-Forwarded-Proto: https. pfCentral uses it to build invite links.
Then set on pfCentral:
PFCENTRAL_SERVER_BASE_URL=https://pf.example.comPFCENTRAL_TRUSTED_ORIGINS=https://pf.example.com# PFCENTRAL_COOKIE_SECURE stays at its default, trueExamples
Section titled “Examples”pf.example.com { reverse_proxy 127.0.0.1:2808 { flush_interval -1 }}Caddy gets and renews a public certificate automatically. For an internal CA, add tls /path/cert.pem /path/key.pem.
server { listen 443 ssl; http2 on; server_name pf.example.com;
ssl_certificate /etc/ssl/pf.example.com.crt; ssl_certificate_key /etc/ssl/pf.example.com.key;
location / { proxy_pass http://127.0.0.1:2808; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Connection ""; proxy_buffering off; proxy_read_timeout 1h; }}labels: - traefik.enable=true - traefik.http.routers.pfc.rule=Host(`pf.example.com`) - traefik.http.routers.pfc.entrypoints=websecure - traefik.http.routers.pfc.tls.certresolver=letsencrypt - traefik.http.services.pfc.loadbalancer.server.port=2808Traefik streams server-sent events without extra settings. Raise the entry point’s respondingTimeouts.readTimeout if you set a short one.
Restrict the public paths
Section titled “Restrict the public paths”These paths answer without a login. Decide who may reach them:
| Path | Needed by | Advice |
|---|---|---|
/login, /setup, /invite, /reset, /forgot-password | People | Allow |
/enroll | Agents, once | Allow from firewalls |
/nats-ca.crt | Agents, at enrollment | Allow; it is a public certificate |
/metrics | Your Prometheus | Restrict to the scraper |
/docs, /openapi.json, /openapi.yaml | API users | Restrict to your network if you prefer |
Check it
Section titled “Check it”curl -sI https://pf.example.com/login | head -1 # HTTP/2 200curl -sI https://pf.example.com/ | grep -i location # location: /loginSign in. If the sign-in page reloads with no error, the cookie or origin settings are wrong: see Troubleshooting.