09 July 2026

Is your firewall man-in-the-middling you? Check the certificate issuer.

A VPN I was setting up simply refused to connect — no error I could act on, just a sulk. The thing that explained it took one command, and it's a trick worth having in your pocket whenever a service mysteriously won't talk on a network you don't control.

The one command

echo | openssl s_client -connect controlplane.example-vpn.com:443 -servername controlplane.example-vpn.com 2>/dev/null \
  | openssl x509 -noout -issuer -subject

What came back was not the certificate I expected:

issuer=C=US, O=Fortinet, OU=Certificate Authority, CN=<appliance-serial>
subject=CN=controlplane.example-vpn.com

That O=Fortinet issuer is the smoking gun. A FortiGate firewall was doing deep SSL inspection — terminating the TLS, presenting its own certificate signed by the appliance's CA, and re-encrypting onwards. My client validates that endpoint's certificate against the public trust store, the Fortinet CA isn't in it, the handshake fails, and the whole thing quietly gives up. (The VPN's own logs, to its credit, even said the cert "looks like Fortinet equipment" — they ship a detector for exactly this.)

The genuinely useful bit: map what's tampered with

Interception is rarely applied to everything — it's expensive, and it breaks things. So check a handful of endpoints and compare issuers; the pattern tells you your firewall's policy:

Endpoint Issuer seen Verdict
controlplane.example-vpn.com Fortinet intercepted
api.cloudflare.com Google Trust Services clean
github.com Sectigo clean

In my case the interception was targeted — the VPN's control plane specifically, everything else untouched. That immediately reframed the problem: stop fighting the blocked thing, and pick a transport the firewall leaves alone (a Cloudflare tunnel egressed perfectly happily, real cert and all).

Why this matters beyond "my VPN broke"

If a corporate box is inspecting your TLS, it can read everything that crosses it that it has decrypted — which is the point of the appliance, but worth being clear-eyed about. The cert issuer is the quickest way to find out whether and where it's happening. A real public CA (Let's Encrypt, Google Trust Services, Sectigo, DigiCert) on the cert means end-to-end; your employer's name, or "Fortinet"/"Palo Alto"/"Zscaler", means the conversation is being opened in transit.

Go and openssl s_client a few of your own endpoints — you may be surprised who's signing them.

Ta ta for now, and I hope you found this helpful.

No comments:

Post a Comment