Skip to main content
RunBook Academy

OPNsenseXXXII · TLS Inspection and Content FilteringTLS intercept deployment

TLS intercept deployment — putting the proxy between the client and the Internet

Intermediate⏱ ~16 min🧪 Lab requiredopensslcurltcpdumpconfigctl

What you'll learn

  • Enable TLS interception on OPNsense and assign the intercept certificate
  • Build an exemption list for pinned and regulated destinations
  • Configure the firewall rules that route traffic through the interception proxy
  • Verify end-to-end interception from a client using openssl and curl
  • Diagnose the silent-bypass failure when interception is not actually working

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.

The interception CA exists. The intercept certificate is issued. The trust anchor is distributed to client devices. The remaining work is to make OPNsense actually intercept traffic — to put the proxy in the path of HTTPS connections, configure the certificate the proxy presents, build the exemption list for destinations that cannot be intercepted, and verify end to end that interception is happening. This lesson covers the deployment, the rules, and the production checks.

Enabling the proxy

OPNsense bundles a TLS-aware proxy (typically a transparent Squid or a plugin-backed implementation depending on the deployment model). The proxy is enabled in Services → TLS Inspection or via the proxy plugin. The activation has three pieces:

  1. The proxy listens on a port (typically 3128 for explicit proxy, or transparent on 3129 with firewall redirection).
  2. The certificate the proxy presents during the client-side handshake — this is the intercept certificate issued by the intercept CA.
  3. The proxy’s behaviour for HTTPS — terminate, inspect, forward, with the bypass list applied.
[client] --HTTPS--> [firewall PRT] --decrypt+inspect--> [upstream HTTPS] --> [server]
                       ^                                  ^
                       |                                  |
                       intercept cert                    real cert
                       (signed by intercept CA)          (signed by public CA)

In transparent mode, the firewall redirects port 443 traffic from the LAN to the proxy without the client knowing. The client believes it talks directly to the remote server; the firewall intercepts in the middle.

The certificate assignment

The proxy presents the intercept certificate for every destination it intercepts. The certificate is wildcard or per-destination:

  • Wildcard intercept certificate: a single certificate with CN=* or subjectAltName=*.example.com works for any destination under that domain. Simple to manage; common for broad interception.
  • Per-destination certificates: the proxy dynamically issues a certificate for each destination it intercepts, signed by the intercept CA. More overhead but matches the public CA model and avoids the wildcard mismatch on root domain.

The assignment is set in the proxy configuration. OPNsense’s TLS Inspection page accepts the intercept CA as the signing authority; the proxy generates per-destination certificates on the fly.

Read-only / Safeproxy certificate state
$ configctl tlsproxy cert list 2>/dev/null; echo '---'; ls -la /var/etc/tlsproxy/ 2>/dev/null | head -10
--- (illustrative)
drwxr-xr-x  2 root wheel   512 Aug 14 12:34 .
drwxr-xr-x  4 root wheel   512 Aug 14 12:34 ..
-rw-------  1 root wheel  1704 Aug 14 12:34 intercept-ca.key
-rw-r--r--  1 root wheel  2049 Aug 14 12:34 intercept-ca.crt
-rw-------  1 root wheel  1675 Aug 14 12:34 server.key
-rw-r--r--  1 root wheel  1675 Aug 14 12:34 server.crt

Illustrative output

The exemption list

Some destinations cannot be intercepted. The proxy must bypass them — connect directly without terminating. The bypass categories:

  1. Certificate pinning. Google, Apple, banking, most modern APIs. The client refuses the connection if the certificate does not chain to a known anchor.
  2. Certificate transparency. Some CAs publish all certificates they sign to public logs. Interception certificates appear in those logs (since they chain to the intercept CA, which is itself a CA). Some clients reject certificates that do not appear in the expected log.
  3. Performance-sensitive. Video conferencing, voice calls, large file transfers — the overhead of termination and re-handshake is too high.
  4. Compliance. Banking, healthcare, regulated workloads.
  5. Operational. The operator’s monitoring infrastructure, the firewall GUI itself, services that must remain pinned.

The exemption list is configured as hostnames, domains, IPs, or ACLs. OPNsense’s proxy supports bypass rules (ssl_bump peek / ssl_bump splice in Squid terminology).

Routing traffic through the proxy

For transparent interception, the firewall must redirect port 443 traffic from the LAN to the proxy. Two implementations:

  1. NAT/redirect rule: a port-forward rule on the LAN interface that redirects outbound 443 to localhost:3129 (the transparent proxy port). The proxy listens on 3129; it terminates and re-handshakes.
  2. WPAD/PAC file: the client is told (via DHCP or DNS) to use the proxy explicitly. WPAD deployment is more reliable but requires client cooperation.

NAT-based transparent interception is simpler to deploy and works for every client automatically. The cost is that the firewall must be on the path of every HTTPS connection — no asymmetric routing, no bypass routes that skip the firewall.

LAN host  --HTTPS--> [OPNsense] --redirect to 3129--> [proxy] --HTTPS--> server
              ^           |
              |           client thinks it talks to server
              but traffic is redirected to localhost first

The firewall rule placement matters. The redirect must apply to the traffic the operator wants to inspect — typically the LAN net. Rules for the WAN, the DMZ, the VPN tunnels, and the firewall itself should not be redirected (the proxy must reach the real server, not itself).

Read-only / Safetransparent interception NAT
$ pfctl -s nat | grep -A1 'rdr'
rdr on igb0 inet proto tcp from 192.0.2.0/24 to any port 443 -> 127.0.0.1 port 3129

Illustrative output

Verification

The end-to-end check is from a client that has the intercept CA in its trust store. The client visits a destination that should be intercepted. The connection succeeds without warnings. The certificate presented chains to the intercept CA, not to a public CA.

Read-only / Safeend-to-end interception verification
$ 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

The second check is on the firewall side. The proxy logs show the connection. The certificate presented to the client chains to the intercept CA. The destination certificate retrieved from the real server chains to a public CA.

Read-only / Safeproxy access log
$ tail -50 /var/log/squid/access.log 2>/dev/null | grep -E 'CONNECT|TLS_HANDSHAKE' | tail -10
1700000123.456 789 192.0.2.50 TCP_TUNNEL/200 12345 CONNECT example.com:443 - -/- 0 0 - - - - - - - -
1700000124.567 234 192.0.2.51 TCP_TUNNEL/200 12345 CONNECT api.example.org:443 - -/- 0 0 - - - - - - - -

Illustrative output

Common deployment failures

The most common failures on first deployment:

SymptomLikely cause
Every HTTPS connection shows certificate warningIntercept CA not in client trust store
Some destinations work, some show warningsPinning or transparency on the failing destinations; exemption needed
Proxy log shows traffic but no inspectionProxy in splice mode for that destination
Interception works for a week then stopsIntercept CA or proxy certificate expired
Proxy CPU at 100%Too many concurrent inspections, or proxy not offloading to a sensible cipher

The discipline: every one of these failures is detectable before the user reports it. The operator should be monitoring proxy CPU, proxy log volume, intercept CA expiry, and per-destination interception status. The user is the last to know.

Knowledge check · 3 questions

  1. Q1. The proxy log shows HTTPS connections from LAN hosts, the firewall NAT rule redirects 443 to the proxy, and the client sees no warnings. Yet the destination certificate chains to a public CA (Let’s Encrypt), not the intercept CA. What is happening?

  2. Q2. Transparent TLS interception works without client cooperation because the firewall redirects the traffic.

  3. Q3. Which of the following are valid reasons to add a destination to the TLS interception bypass list? Select all that apply.

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