The Handbook

    Theme
    • Guides
        • Check a system before installing FreeBSD
        • Orient a Linux administrator on FreeBSD
        • Supported FreeBSD releases
        • Choose a FreeBSD documentation and support channel
        • Move files safely without GNU mv -t
        • Update, upgrade, or update packages?
        • Upgrade 14.4 or 15.0 to FreeBSD 15.1
        • Choose packages, ports, or poudriere
        • Choose the quarterly or latest package branch
        • Choose a FreeBSD download or package mirror
        • Make a system setting persistent
        • Configure locale, keyboard, and time zone
        • Configure a serial console for recovery
        • Choose a custom kernel, module, or loader setting
        • Run a Linux binary with the compatibility layer
        • Check desktop and laptop hardware before installation
        • Choose and check a graphics driver
        • Choose Xorg or Wayland
        • Build a maintainable desktop baseline
        • Install and check a desktop browser
        • Check laptop Wi-Fi, power, and suspend
        • Check multimedia readiness
        • Choose and configure a printing stack
        • Run Windows applications with Wine
        • Snapshot and replicate a ZFS dataset
        • Choose a filesystem and storage layout
        • Operate ZFS without losing the recovery path
        • Restore files from a ZFS snapshot
        • Read ZFS pool health and run a scrub
        • Replace a failed device in a ZFS mirror
        • Replicate a ZFS dataset over SSH
        • Change PF safely on a remote host
        • Configure a narrow WireGuard tunnel
        • Plan a FreeBSD home server
        • Choose a mail server or an outgoing relay
        • Publish a network service safely
        • Choose a jail network model
        • Choose native jails or a jail manager
        • Choose a jail or a bhyve virtual machine
        • Establish a FreeBSD security baseline
        • Choose a MAC policy
        • Audit security-relevant activity
        • Start a DTrace performance investigation
    • Integrations
        • Create a first jail with Bastille
        • Compare jail managers and OCI tooling
        • Publish a Bastille service through PF
        • Mount a ZFS dataset in a Bastille jail
        • Update and upgrade Bastille jails
        • Back up and restore a Bastille jail
        • Prepare bhyve and vm-bhyve
        • Choose NFS or Samba for file sharing
        • Choose ZFS backup automation
        • Operate a signed poudriere repository
        • Manage FreeBSD configuration with Ansible or Salt
        • Run Motion with webcamd on FreeBSD
        • Design a reverse proxy, certificates, and monitoring
    • FAQ
      • Troubleshooting
          • Recover an interrupted freebsd-update run
          • Resolve a package repository or ABI mismatch
          • Diagnose the FreeBSD boot path
          • Recover with a ZFS boot environment
          • Diagnose DNS, routing, and firewall paths
          • Diagnose network mbuf exhaustion
          • Bind a service to a low port without running it as root
          • Diagnose audio output or input
          • Diagnose webcamd, cuse, and a webcam
          • Fix USB device permissions without opening every device
      • About this handbook
      • Synopsis
      • Keep the public boundary narrow
      • Choose Caddy or nginx by ownership model
      • Qualify one upstream before adding more
      • Treat certificate renewal as production work
      • Establish minimum actionable monitoring
      • Protect logs and application data
      • Make proxy failure recoverable
      • Primary references

      Design a reverse proxy, certificates, and monitoring

      Last reviewed
      13 August 2026
      Applies to
      15.1-RELEASE, 15.0-RELEASE, 14.4-RELEASE

      Synopsis #

      A reverse proxy can give several internal web applications one controlled Internet-facing boundary. It centralizes public listeners, TLS certificates, request limits, and access logs, but it also becomes a shared dependency. Certificate automation and monitoring must be designed with the proxy rather than added after services are published.

      This guide defines an architecture and qualification sequence for a home or small server. It is not a universal Caddy or nginx configuration. Application protocols, authentication, uploaded data, and WebSocket or streaming behavior determine the final directives.

      The upstream application should first satisfy the network-service publication checklist . A reverse proxy changes the public entry point; it does not assume ownership of the application’s updates, secrets, durable data, authentication, or recovery.

      Keep the public boundary narrow #

      The usual design has four layers:

      LayerResponsibility
      DNS and network edgeSend each public name to the intended address and permit only required ports
      Reverse proxyTerminate TLS, select a virtual host, and forward to one reviewed upstream
      Application boundaryListen on a private address, loopback address, Unix socket, or isolated jail network
      Monitoring pathTest from outside the host and deliver alerts through an independent channel

      Do not publish an application’s administrative port merely because its web interface is convenient. Bind the application to the narrowest reachable address and publish only the proxy. A jailed application can remain behind the host firewall using the principles in publish a Bastille service through PF .

      The reverse proxy is not an authentication system unless an explicitly designed authentication component is integrated. Forwarded identity headers must be stripped from untrusted clients and set only by the trusted proxy path.

      Choose Caddy or nginx by ownership model #

      RequirementCaddynginx
      Integrated public certificate automationBuilt-in automatic HTTPSUse a separate ACME client or certificate workflow
      Small declarative reverse-proxy configurationStrong fitStrong fit with more explicit directives
      Existing nginx operational knowledge and templatesPossible migration costStrong fit
      Fine-grained established HTTP feature configurationCapable; confirm required moduleBroad nginx directive ecosystem
      Certificate private-key ownershipCaddy-managed storageExternal client and nginx file permissions

      Caddy documentation states that Automatic HTTPS obtains and renews certificates for qualifying site addresses and redirects HTTP to HTTPS. The behavior still depends on correct DNS, reachable ACME challenges, writable certificate storage, and a successful reload path.

      nginx terminates HTTPS from configured certificate and private-key files. Certificate issuance and renewal remain a separate component, including a hook that validates and reloads nginx after renewal. Private keys must be readable by the required master process and inaccessible to application accounts.

      Choose one owner for certificate storage and renewal. Running two ACME clients for the same names creates conflicting state and can exhaust issuance limits without improving availability.

      Qualify one upstream before adding more #

      Start with a noncritical application and record:

      • public hostname and expected redirects;
      • upstream address, port, protocol, and certificate trust if HTTPS is used internally;
      • required request size and timeouts;
      • WebSocket, streaming, or long-poll behavior;
      • application expectation for Host and forwarded client information;
      • health endpoint that does not modify data;
      • access-log retention and sensitive fields.

      Keep an upstream on plain HTTP only when its private network boundary is trusted and documented. When proxying to an HTTPS upstream, validate its certificate against an explicit trust source. Disabling upstream TLS verification preserves encryption without authenticating the upstream and should not be presented as a secure fix.

      Validate configuration before every reload. Then test the public hostname, certificate chain, redirect behavior, a representative authenticated action, upload limits, and application-generated absolute URLs.

      Treat certificate renewal as production work #

      Certificate automation needs more than a timer. It needs:

      1. an issuance method compatible with DNS and inbound firewall policy;
      2. persistent state backed up according to the tool’s documentation;
      3. restricted private-key access;
      4. a staging or dry-run path where the ACME client provides one;
      5. configuration validation and service reload after renewal;
      6. an external expiry alert that remains useful when renewal stops.

      DNS challenge credentials can often modify an entire zone. Restrict them to the narrowest supported scope and keep them outside application jails and source repositories. HTTP challenge handling should expose only the required path and should not bypass application authorization rules more broadly.

      Monitor certificate validity from outside the server. A local file can be current while DNS points elsewhere or the proxy serves a different virtual host.

      Establish minimum actionable monitoring #

      A small deployment does not require a large observability stack, but it does require independent answers to the following questions:

      CheckFailure represented
      External HTTPS request by hostnameDNS, routing, firewall, TLS, proxy, and basic application path
      Certificate expiry and hostname matchRenewal or virtual-host failure before browsers reject it
      Application-specific health checkA running proxy with an unusable upstream
      Disk and ZFS pool capacityImpending write failure and uncontrolled snapshot or log growth
      zpool status healthDevice or data-integrity degradation
      Backup age and last restore testLost recovery capability despite healthy production
      Package vulnerability and update statusKnown exposure and maintenance backlog
      Authentication and error-rate summaryAbuse, brute-force activity, or application regression

      Every check needs an owner, threshold, alert destination, and response note. Alerts stored only on the failed host are not alerts. Rate-limit repetitive failures so a network outage does not bury the first useful event.

      Use service, sockstat, logs, and application health endpoints to diagnose local failures. Process existence alone is insufficient: a service can run while returning errors or pointing to an unavailable database.

      Protect logs and application data #

      Proxy logs can contain client addresses, query strings, user agents, and application paths. Avoid logging authorization headers and sensitive query parameters. Set rotation, retention, and permissions deliberately; unbounded logs can take down every proxied service by filling the filesystem.

      Keep application data in separate datasets or filesystems with independent capacity and backup policy. A reverse proxy configuration backup cannot restore an application database. Plan a FreeBSD home server covers failure domains, and choose NFS or Samba covers a separate file-sharing boundary.

      Make proxy failure recoverable #

      Retain the last validated proxy configuration and the package version that accepted it. Test rollback before the proxy carries several services. A failed change should restore the last configuration, validate it, reload the service, and re-run the external health check.

      Avoid coupling all maintenance actions. Proxy package upgrades, certificate-client upgrades, application upgrades, DNS changes, and firewall changes should not occur in one unreviewable event. Configuration management can stage these changes using the Ansible or Salt operating guide .

      Primary references #

      • Caddy automatic HTTPS
      • Caddy reverse_proxy directive
      • nginx reverse-proxy module
      • nginx HTTPS configuration
      • service(8)
      • sockstat(1)
      • newsyslog.conf(5)
      • zpool-status(8)

      Independent documentation. Not affiliated with or endorsed by the FreeBSD Project or the FreeBSD Foundation.

      Report a bug
      • Synopsis
      • Keep the public boundary narrow
      • Choose Caddy or nginx by ownership model
      • Qualify one upstream before adding more
      • Treat certificate renewal as production work
      • Establish minimum actionable monitoring
      • Protect logs and application data
      • Make proxy failure recoverable
      • Primary references