Skip to main content
RunBook Academy

OPNsenseXXIV · PKI and CertificatesPKI and certificate management

Importing certificates and distributing the trust anchor

Intermediate⏱ ~14 min🧪 Lab requiredopensslcurlssh

What you'll learn

  • Import a CA certificate and an intermediate into the OPNsense trust store
  • Import a leaf certificate and pair it with its private key
  • Assign a certificate to a specific OPNsense service (GUI, IPsec, OpenVPN)
  • Distribute the CA certificate to verifiers that need to trust the chain
  • Diagnose chain-not-trusted failures using openssl and the trust store

Prerequisites

Verified against OPNsense 25.x · FreeBSD 14.x · PF (FreeBSD packet filter) FreeBSD 14.x · Unbound 1.20+ · Kea DHCP OPNsense 25.x plugin · WireGuard in-kernel + OPNsense plugin · strongSwan (IPsec plugin) OPNsense 25.x plugin · OpenVPN 2.6.x · Suricata 7.x · 2026-08-14

Not yet marked complete on this device.

A certificate is useless until it reaches two places: the service that uses it (so the service can present it during a TLS handshake) and the verifier that needs to trust it (so the verifier can complete the chain). The CA certificate must reach the verifier’s trust store. The leaf certificate and its private key must reach the service.

This lesson covers how to import certificates and CA chains into OPNsense, how to pair a leaf certificate with its private key, how to assign certificates to specific services, how to distribute the CA certificate to verifiers, and how to diagnose the chain-not-trusted failure when it appears despite all of this being done.

Importing a CA certificate

OPNsense stores trusted CAs under System → Trust → Authorities. A CA certificate can be imported in two shapes:

  • Self-signed root. The CA certificate is its own issuer (subject equals issuer). The certificate is a trust anchor.
  • Intermediate. The CA certificate is signed by another CA. The intermediate is not a trust anchor on its own; the parent root must also be in the trust store.

To import:

  1. Open System → Trust → Authorities.
  2. Click Import.
  3. Paste the PEM-encoded CA certificate into the Certificate data field. If the intermediate has been signed by a parent CA, paste the full chain (intermediate + root, in that order) into the same field.
  4. Set a descriptive name (e.g. Example Internal Root CA).
  5. Click Save.

OPNsense parses the PEM, identifies the certificates, and adds them to the trust store. The descriptive name is what subsequent certificate-issuance operations will reference.

Read-only / Safechain bundle
$ openssl crl2pkcs7 -nocrl -certfile example-internal-intermediate.crt -certfile example-internal-root.crt | openssl pkcs7 -print_certs -noout
subject=/O=Example Org/CN=Example Internal Intermediate CA
issuer=/O=Example Org/CN=Example Internal Root CA
subject=/O=Example Org/CN=Example Internal Root CA
issuer=/O=Example Org/CN=Example Internal Root CA

Illustrative output

Importing a leaf certificate

Leaf certificates (and their private keys) live under System → Trust → Certificates. To import a leaf that was signed by an external CA:

  1. Open System → Trust → Certificates.
  2. Click Import.
  3. Paste the PEM-encoded leaf certificate into the Certificate data field.
  4. Paste the PEM-encoded private key into the Private key data field. The private key must match the public key in the certificate — see the previous lesson on verifying the match.
  5. If you have the CA chain (intermediate and root), paste it into the Certificate authority field. OPNsense stores it alongside the leaf for services that need it.
  6. Set a descriptive name (e.g. fw.example.com cert).
  7. Click Save.

OPNsense verifies that the private key matches the public key in the certificate. A mismatch is rejected at import time.

Assigning certificates to services

Once a certificate is imported, it can be assigned to the services that need it. The assignment lives in each service’s configuration screen.

  • GUI: System → Settings → Administration → SSL Certificate — select the certificate for the web UI.
  • IPsec: VPN → IPsec → Tunnel → Child SA → Local Certificate — select the certificate presented by the firewall as the IPsec endpoint.
  • OpenVPN: VPN → OpenVPN → Servers → Cryptographic Settings → Server Certificate — select the certificate for the OpenVPN server.
  • Captive portal: Services → Captive Portal → [zone] → SSL Certificate — select the certificate for the captive portal HTTPS listener.
  • HAProxy / reverse proxy: select the certificate per frontend.

After assigning, the service must be reloaded or restarted. OPNsense offers an Apply action that triggers the reload.

Read-only / Safeverify GUI cert
$ openssl s_client -connect fw.example.com:443 -servername fw.example.com </dev/null 2>/dev/null | openssl x509 -noout -subject -issuer -ext subjectAltName
subject=CN = fw.example.com
issuer=O = Example Org, CN = Example Internal Intermediate CA
X509v3 Subject Alternative Name:
  DNS:fw.example.com, DNS:fw.internal.example.com

Illustrative output

Distributing the trust anchor to verifiers

The CA certificate must reach every verifier that needs to trust the chain. The distribution depends on the verifier platform.

  • Browser on operator workstation: deploy via Group Policy (Windows), MDM (macOS), or update-ca-certificates (Linux).
  • curl or wget: point to the CA file with --cacert or set the SSL_CERT_FILE environment variable, or place the CA in the system trust store.
  • Java applications: import into the JVM trust store ($JAVA_HOME/lib/security/cacerts) using keytool.
  • Python requests: set REQUESTS_CA_BUNDLE or place the CA in the system trust store.
  • OPNsense verifying an upstream service: import the upstream CA into System → Trust → Authorities so OPNsense trusts it.

Diagnosing chain-not-trusted failures

The chain-not-trusted failure is the most common certificate problem in production. The TLS handshake fails because the verifier cannot complete the chain to a trusted root. The diagnostic procedure:

  1. Confirm what the server is presenting. Use openssl s_client -showcerts to dump the full chain. The output should contain the leaf, any intermediates the server is sending, and the root should be the last certificate (subject equals issuer).
  2. Confirm what the verifier has in its trust store. The verifier’s root CAs must include the issuer of the intermediate the server is sending.
  3. Walk the chain by hand. Use openssl verify -CAfile to verify the chain against an explicit trust anchor.
  4. Check expiry and revocation. A chain can be perfect and still fail if any certificate in the chain is expired or revoked.
Read-only / Safeopenssl verify
$ openssl verify -CAfile example-internal-root.crt -untrusted example-internal-intermediate.crt fw.example.com.crt
fw.example.com.crt: OK

Illustrative output

If openssl verify reports OK but the browser still shows untrusted, the issue is the verifier’s trust store, not the certificate. The browser has not received the CA certificate. Distribution is the failure, not the chain.

Summary

  • Import CA certificates into System → Trust → Authorities. Paste the full chain (intermediate + root) when importing an intermediate.
  • Import leaf certificates into System → Trust → Certificates. OPNsense verifies the private key matches the certificate.
  • Assign certificates to services (GUI, IPsec, OpenVPN, captive portal, HAProxy) in each service’s configuration.
  • Distribute the CA certificate to verifiers that need to trust the chain. Each platform has its own trust-store mechanism.
  • Diagnose chain failures with openssl s_client -showcerts and openssl verify. A chain that verifies with openssl but fails in the browser is a distribution problem, not a chain problem.

Knowledge check · 4 questions

  1. Q1. You import an intermediate CA certificate into OPNsense but not the parent root. A leaf certificate signed by the intermediate chains to the root in openssl, but the OPNsense trust store cannot complete the chain. What is the fix?

  2. Q2. A certificate that openssl verify reports as OK can still fail in a browser because the browser has a different trust store.

  3. Q3. When importing a leaf certificate into OPNsense, which of the following checks does OPNsense perform automatically? Select all that apply.

  4. Q4. After assigning a new certificate to the OPNsense GUI and clicking Apply, openssl s_client still shows the old certificate. What is the next step?

Passing score: 75%. Answers are checked in this browser.