OPNsenseXXXII · TLS Inspection and Content FilteringTLS inspection concepts
Internal CA for TLS intercept — issuing the certificate the proxy will forge
What you'll learn
- Create a dedicated intercept CA that is separate from any production CA
- Issue a long-lived intercept certificate the proxy will use to sign forged server certificates
- Distribute the intercept CA root to client devices via the right mechanism for each platform
- Monitor intercept CA expiry and plan renewal before the trust anchor expires
- Recognise why a compromise of the intercept CA does not compromise production certificates
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
The TLS interception layer needs a certificate to present to clients. That certificate must be signed by a CA whose root is in every client trust store the estate operates — workstations, mobile devices, BYOD where consent applies, and the firewall itself. The CA that signs the intercept certificate is the most sensitive piece of the interception deployment, because anyone with the CA’s private key can intercept any TLS session for any estate user. This lesson covers how to create and operate that CA properly — separate from production, with the right lifetime, distributed to the right places, and renewed on time.
Why the intercept CA is separate
A production CA issues certificates for production services. Its private key is protected, its issuing path is short, its CRL is published, and its OCSP responder is reachable. A compromise of that CA would let an attacker forge certificates for production services — the firewall GUI, internal APIs, IPsec endpoints. Every verifier in the estate would trust those forgeries.
The intercept CA is different. It issues one certificate (or a small number), used only by the TLS interception proxy. Its private key is protected, but its blast radius is different: a compromise lets an attacker forge certificates for any HTTPS destination on behalf of any client behind the firewall. The attacker cannot impersonate production services outside the firewall — only intercept client traffic inside the perimeter.
Keeping the two CAs separate means:
- A compromise of the intercept CA does not affect production certificates.
- The intercept CA can have a shorter lifetime and looser issuance discipline.
- The intercept CA can be revoked quickly by removing it from client trust stores.
- The intercept CA’s CRL and OCSP responder do not need to be reachable from the public Internet.
Creating the intercept CA
OPNsense’s System → Trust → Authorities page creates CAs. For an intercept CA:
- Pick a descriptive subject —
CN=OPNsense TLS Intercept CA, O=Estate Internal— and a method (Create internal CA). - Choose a key type and size that match or exceed production. RSA 4096 or ECDSA P-384 is the modern floor.
- Set a lifetime that gives years of operation. The CA root lifetime drives every certificate the CA signs. A 10-year CA means re-distributing the root in 10 years, not sooner.
- Set a digest that the clients’ trust stores will accept. SHA-256 is universally supported; SHA-1 is deprecated.
- Set the CRL distribution and OCSP responder if they will be reachable from clients. For an internal-only CA, both can point at internal services.
$ openssl req -x509 -newkey rsa:4096 -sha256 -days 3650 -nodes \
-keyout /etc/ssl/intercept-ca.key \
-out /etc/ssl/intercept-ca.crt \
-subj '/CN=OPNsense TLS Intercept CA/O=Estate Internal' \
-addext 'basicConstraints=critical,CA:TRUE' \
-addext 'keyUsage=critical,keyCertSign,cRLSign'Generating a RSA private key
.............................................................................++++
writing new private key to '/etc/ssl/intercept-ca.key'
-----
Illustrative output
Issuing the intercept certificate
The interception proxy uses one certificate (or a small number, if it presents different identities for different destinations). The certificate is issued by the intercept CA. The proxy presents it during the client-side TLS handshake.
The certificate lifetime matters. A short-lived intercept certificate (90 days) requires the proxy to renew frequently and risks expiry incidents. A long-lived certificate (5+ years) keeps the proxy running but ties the certificate to the original key. The right answer depends on the rotation discipline the operator can maintain — most production estates run 1 to 3 years.
$ openssl x509 -in /etc/ssl/intercept-ca.crt -noout -text | grep -E 'Subject:|Issuer:|Not Before|Not After|Public-Key|Signature Algorithm' Subject: CN = OPNsense TLS Intercept CA, O = Estate Internal
Issuer: CN = OPNsense TLS Intercept CA, O = Estate Internal
Validity
Not Before: Aug 14 12:00:00 2026 GMT
Not After : Aug 9 12:00:00 2036 GMT
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (4096 bit)
Signature Algorithm: sha256WithRSAEncryption
Illustrative output
Distributing the trust anchor
The intercept CA root must reach every device that will have its TLS intercepted. Distribution mechanisms by platform:
| Platform | Mechanism | Notes |
|---|---|---|
| Windows (AD-joined) | Group Policy → Trusted Root Certification Authorities | Automatic, auditable |
| Windows (standalone) | Manual install or MDM | Per-device |
| macOS | MDM profile or keychain | Per-device or fleet |
| iOS | MDM profile (Configuration Profile) | Required for managed devices |
| Android | MDM or per-device install | User install is fragile |
| Linux | update-ca-certificates or NSS database | Distribution-dependent |
| Firefox (all OS) | NSS database (certutil) | Separate from OS trust |
| BYOD | Consent and manual install | Operators should not force |
Group Policy for AD-joined Windows machines is the most reliable distribution. The CA certificate is published to Computer Configuration → Policies → Windows Settings → Security Settings → Public Key Policies → Trusted Root Certification Authorities, and every domain-joined machine picks it up on next policy refresh (typically 90 minutes, plus reboot).
Certificate lifecycle
The intercept CA has three lifetimes to manage:
- CA root certificate — typically 10 to 20 years. Distributing a new root is a project; the operator wants to do it rarely.
- CA private key — should be rotated before the certificate expires, ideally on a 2 to 5 year cycle. Rotation requires re-issuing every certificate the CA has signed.
- OCSP responder / CRL — the CRL has its own lifetime (days to weeks), renewed automatically. The OCSP responder certificate has a longer lifetime (months to years).
Monitoring is essential. The intercept CA expiry is a known date; the operator should be alerted at 90 days, 30 days, 14 days, and 7 days before expiry. The alert fires on the CA certificate, not on the certificates the CA has signed — those will all expire when the root does.
Verifying the deployment
The verification check is straightforward: from a client that has the intercept CA in its trust store, visit a site that is intercepted. The browser should connect without warnings, and the certificate presented should chain to the intercept CA. From a client that does not have the CA, the same visit should produce a certificate warning.
$ openssl s_client -connect example.com:443 -servername example.com -CAfile /etc/ssl/intercept-ca.crt 2>&1 | grep -E 'subject=|issuer=|verify return'subject=CN = example.com
issuer=CN = OPNsense TLS Intercept CA, O = Estate Internal
verify return:1
Illustrative output
Summary
- The intercept CA is a separate CA from production. Different key, different subject, different blast radius.
- A 4096-bit RSA or stronger key, SHA-256 digest, 10-year lifetime matches modern production discipline.
- The trust anchor must reach every platform that will be intercepted — including Firefox’s NSS store, which is independent of the OS.
- CA expiry is the operator’s responsibility. Alert at 90/30/14/7 days.
- A compromise of the intercept CA is recoverable; a compromise of the production CA is not. This is why the two must never share a key.
Knowledge check · 3 questions
Q1. The operator wants to issue the intercept certificate from the production CA so clients already trust the chain. What is the main problem?
Q2. A CA certificate distributed via Windows Group Policy is automatically trusted by Firefox on the same machine.
Q3. Which of the following are valid reasons to use a separate CA for TLS interception rather than reusing the production CA? Select all that apply.
Passing score: 75%. Answers are checked in this browser.