T Techclick ← All lessons
Fortinet · FortiGate · Interactive lesson

SSL inspection CA first then deep inspect

Ticket: policy is accept, AV and IPS are on, then every browser on LAN throws NET::ERR_CERT_AUTHORITY_INVALID. The ask is “turn SSL inspection off.” Wrong object. FortiOS SSL/SSH Inspection is either certificate-inspection (handshake / SNI / CN — payload stays ciphertext) or deep-inspection (decrypt, inspect, re-sign). Deep inspect without Fortinet_CA_SSL in the client Trusted Root store is a self-inflicted outage. Pinning is an exemption, not a reason to go blind. Lab: LAN 10.20.20.0/24, FGT 10.20.20.1, WAN 192.0.2.0/24, policy LAN-to-WAN, profile ssl_lan_wan.

16 min read · L2 primary · Quiz at end

After this page you can

Lessons · FortiGate series · SSL inspection + CA trust

This page vs IPS / App Control and policy

This lesson is the inspect gate: which SSL/SSH profile the policy uses, whether the client trusts the re-signing CA, and what you exempt. Signature sensors stay blind on ciphertext until Full SSL Inspection is on. Policy accept is a different object.

IPS + App Control · Security profiles · Zone, policy, NAT

Hero · handshake is not decrypt
Laptop TLS session through a firewall with Handshake and Decrypt panes, CA shield in front of the inspect path
Mood, not a packet capture. Exact path is in the SVG: 10.20.20.10 ClientHello, FortiGate either reads SNI/cert or impersonates and re-signs with Fortinet_CA_SSL. No CA on the client, deep inspect is an outage.
Quick answer

FortiOS ships four SSL/SSH profiles: read-only certificate-inspection, deep-inspection, no-inspection (clone them), plus editable custom-deep-inspection. Certificate inspection inspects headers up to the TLS layer (SNI, then CN/SAN) — Web Filter category and some App Control signatures work; AV / DLP / file body / most IPS stay blind. Deep inspection (Full SSL Inspection) impersonates the recipient, decrypts, inspects, re-encrypts with Fortinet_CA_SSL (or your uploaded CA). The browser does not trust that CA until you import it to Trusted Root. Untrusted server certs re-sign with Fortinet_CA_Untrusted — never import that one. Pinning and bank/health/privacy apps get ssl-exempt on the profile, not a global disable. Attach with set ssl-ssh-profile on the firewall policy. Lab: LAN 10.20.20.0/24, FGT 10.20.20.1, WAN 192.0.2.0/24.

Why HTTPS still hides the payload

Accept on LAN-to-WAN only won the 5-tuple. HTTPS is still ciphertext after that. IPS, AV, DLP and most App Control signatures never see the body until SSL/SSH Inspection is Full SSL Inspection. Certificate-inspection is the usual “we turned inspection on” state that still leaves you blind on 443.

Three tickets look identical from the desk (browser red padlock or a broken app) and are three different objects:

Policy hit counter is not SSL proof

A climbing hit count means the 5-tuple matched. It does not mean the payload was visible. Proof is the padlock issuer on a non-exempt site plus Security Events › SSL. Re-read One flow after go-live.

Certificate vs deep — two objects

The profile lives under Security Profiles › SSL/SSH Inspection (config firewall ssl-ssh-profile). You attach it on the firewall policy (set ssl-ssh-profile), same row as IPS / AV. Outbound internet uses Multiple Clients Connecting to Multiple Servers. Inbound to a published TLS server is Protecting SSL Server — a different profile shape (replace/re-sign a specific server cert). This lesson is outbound.

Path · CA, handshake, decrypt, then exempt
Four glass panels labeled Trust CA, Handshake, Decrypt, Exempt
Feel of the order. CA push is Side A and happens before you flip the policy to deep-inspection. Handshake-only is certificate-inspection. Decrypt is Full SSL. Exempt is Full SSL only.

certificate-inspection

Inspect SSL handshake only. SNI then CN/SAN. No re-sign of the origin cert. Allowed browsing does not throw CA warnings. Payload stays encrypted.

deep-inspection

Full SSL Inspection. FortiGate impersonates, decrypts, inspects, re-encrypts with caname (default Fortinet_CA_SSL). Client must trust that CA.

Fortinet_CA_SSL

Re-signing CA for verified servers. Download from the profile. Import to Trusted Root (or GPO). Not in any public browser store.

ssl-exempt

Full SSL only. Address / wildcard-FQDN / FortiGuard category / Reputable websites. Default categories: Finance and Banking, Health and Wellness, Personal Privacy — pinning and privacy.

Say this out loud

Certificate-inspection reads the handshake. Deep-inspection decrypts and re-signs. The client must trust Fortinet_CA_SSL first. Pinning is an exemption on the profile, not a reason to inspect nothing.

How a TLS session is inspected

Existing session first. New 443 from 10.20.20.10 hits policy LAN-to-WAN, then the SSL/SSH profile. Certificate-inspection stops at ClientHello SNI + server cert. Deep-inspection builds two TLS legs: client ↔ FortiGate (cert signed by Fortinet_CA_SSL) and FortiGate ↔ origin (real server cert). Exempt dests skip decrypt and keep the origin cert end-to-end.

Flow 1 · lab packet 10.20.20.10 → 203.0.113.80:443
1 Policy LAN-to-WAN accept 2 SSL profile ssl_lan_wan 3 Method? cert vs deep 4 Exempt? ssl-exempt hit 5 UTM AV / IPS / WF certificate-inspection SNI / CN / SAN only · origin cert kept no CA on client for allowed browse deep-inspection re-sign with Fortinet_CA_SSL payload visible · CA must be trusted Deep on, CA missing: NET::ERR_CERT_AUTHORITY_INVALID on every HTTPS site. Fix the store. Do not set ssl-ssh-profile no-inspection to “make browsing work.” Exempt hit: origin cert end-to-end. Pinning apps survive. Payload UTM does not run on that dest. Log SSL exemptions if you need the row. Untrusted origin re-signs with Fortinet_CA_Untrusted — never import that CA. Source: FortiOS 8.0 — SSL & SSH Inspection; Certificate inspection; Deep inspection.

Read left → right, then the two method boxes. Exempt is a deep-inspect skip, not a second policy.

ObjectLab valueIf missing
PolicyLAN-to-WAN accept + ssl-ssh-profile ssl_lan_wanDefault or no profile → you are not inspecting TLS. IPS/AV on 443 stay dark.
ProfileClone custom-deep-inspectionssl_lan_wancertificate-inspection and deep-inspection are read-only. Do not try to edit them in place.
CAFortinet_CA_SSL in Trusted Root on 10.20.20.10Every site warns. Chrome: NET::ERR_CERT_AUTHORITY_INVALID.
Untrusted CAFortinet_CA_Untrusted stays off the clientImporting it hides real untrusted origins. Fortinet: never import.
ExemptFinance and Banking + wildcard-FQDN for the pinned appTeams/SAP/bank apps break. Wrong fix is disabling the profile.
ProofIssuer Fortinet_CA_SSL + SSL event logPolicy hits only prove the 5-tuple.

When to stay cert-only vs decrypt

Pick the inspection method the UTM feature actually needs. Mixing “we inspect SSL” with certificate-inspection is the usual empty-AV ticket.

Flow 2 · handshake is not payload
Cert inspect handshake / SNI / CN Web Filter category some App Control no client CA for allow Deep inspect decrypt + re-sign AV / DLP / file / IPS body Fortinet_CA_SSL on clients HTTPS, SMTPS, FTPS… Exempt Full SSL only pinning / bank / health address or wildcard-FQDN origin cert kept Flow-based certificate-inspection does not validate the cert (no untrusted / SNI checks). Replacement / block pages are still signed by the FortiGate CA — install it if users hit those pages. Protocol port mapping is proxy-mode. Flow-based deep-inspection scans all ports regardless. Source: FortiOS — Certificate inspection; Configuring an SSL/SSH inspection profile; Deep inspection.

Three columns, three tickets. Do not decrypt the whole internet to fix a Web Filter category miss.

NeedUseSkip
FortiGuard category / URL on HTTPS, no payload scancertificate-inspection (or clone it to add ports). No CA push for allowed sites.Deep-inspection “because SSL.” You will spend a week on CA and pinning.
AV / DLP / file filter / payload IPS on 443Full SSL Inspection. Clone custom-deep-inspection. CA in Trusted Root first.Leaving the policy on certificate-inspection and blaming AV.
Banking, health, privacy, pinned desktop appsssl-exempt on that dest (category, FQDN, address). Log exemptions during the pilot.Setting the whole policy to no-inspection.
Unknown outbound internetMultiple Clients Connecting to Multiple Servers + your CA.Protecting SSL Server — that is inbound to one cert.

Runbook Side A / B / C

Side A is the CA on the client. Side B is the profile and the policy attach. Side C is exemptions and the SSL log. Do not start at B with a live user VLAN.

Side A — trust Fortinet_CA_SSL

  1. Download the CA from the profile

    Security Profiles › SSL/SSH Inspection — edit deep-inspection or the clone you will use. Default CA Certificate is Fortinet_CA_SSL. Click Download. Source: FortiOS Administration Guide — Deep inspection (import Fortinet_CA_SSL).

  2. Install to Trusted Root on the pilot host

    On 10.20.20.10: Certificate Import Wizard → Trusted Root Certification Authorities. Production: GPO (Computer Configuration → Policies → Windows Settings → Security Settings → Public Key Policies → Trusted Root Certification Authorities). macOS/iOS/Firefox have their own stores — a Windows GPO does not cover Chrome-on-Mac or Firefox’s NSS DB.

  3. Do not import Fortinet_CA_Untrusted

    Untrusted origin certs re-sign with Fortinet_CA_Untrusted when action is Allow. If warnings remain after a correct SSL CA import, that is this CA — not a broken GPO. Never put it in Trusted Root.

CLI — which CA the profile will re-sign with
config firewall ssl-ssh-profile
    edit "ssl_lan_wan"
        set caname "Fortinet_CA_SSL"
        set untrusted-caname "Fortinet_CA_Untrusted"
    next
end
# Download remains a GUI/API action from the profile page.
# Confirm the client store separately — FortiOS cannot see the laptop’s Trusted Root.

Side B — profile then policy

https://10.20.20.1/ · Security Profiles › SSL/SSH Inspection › Create New
Training mock · not live

Security Profiles › SSL/SSH Inspection › Create New

ssl_lan_wan

Multiple Clients Connecting to Multiple Servers
Full SSL Inspection
Fortinet_CA_SSL · Download
Allow
443 · deep-inspection
Finance and Banking · Health · Personal Privacy

Source: FortiOS 8.0 — Configuring an SSL/SSH inspection profile. Inspection method Full SSL Inspection is CLI deep-inspection. Exempt from SSL Inspection is Full SSL only. certificate-inspection / deep-inspection / no-inspection are read-only — clone or create ssl_lan_wan.

  1. Create ssl_lan_wan (do not edit the factory deep-inspection)

    Clone custom-deep-inspection or Create New. Multiple Clients Connecting to Multiple Servers. Inspection method = Full SSL Inspection. CA = Fortinet_CA_SSL. Untrusted = Allow (re-sign with Untrusted CA). Keep the default privacy categories unless the pilot has a reason to decrypt banks.

  2. Attach on LAN-to-WAN after the CA is on 10.20.20.10

    Policy & Objects › Firewall Policy — Security Profiles: SSL/SSH Inspection = ssl_lan_wan. CLI set utm-status enable then set ssl-ssh-profile "ssl_lan_wan". Log allowed traffic during the pilot.

https://10.20.20.1/ · Policy & Objects › Firewall Policy › LAN-to-WAN
Training mock · not live

Policy & Objects › Firewall Policy › LAN-to-WAN

LAN-to-WAN · Security Profiles

LAN → WAN
LAN_NET (10.20.20.0/24)
ssl_lan_wan
ACCEPT · NAT enable

Source: FortiOS firewall policy — SSL/SSH Inspection is a security profile on the policy, not a replacement for accept. Attach deep inspect only after Side A is done on the pilot subnet.

CLI — Side B
config firewall ssl-ssh-profile
    edit "ssl_lan_wan"
        set comment "LAN outbound full inspect after CA push"
        config https
            set ports 443
            set status deep-inspection
            set untrusted-server-cert allow
        end
        set caname "Fortinet_CA_SSL"
        set untrusted-caname "Fortinet_CA_Untrusted"
    next
end
config firewall policy
    edit 1
        set name "LAN-to-WAN"
        set srcintf "LAN"
        set dstintf "WAN"
        set srcaddr "LAN_NET"
        set dstaddr "all"
        set action accept
        set schedule "always"
        set service "ALL"
        set utm-status enable
        set ssl-ssh-profile "ssl_lan_wan"
        set nat enable
        set logtraffic all
    next
end

Side C — pinning exceptions + prove

  1. Exempt pinning dests on the profile, not with a second any-any

    On ssl_lan_wan: Exempt from SSL Inspection — keep Finance and Banking / Health and Wellness / Personal Privacy. Add an address or wildcard-FQDN for the app that pins. Enable Log SSL exemptions on the pilot. Source: FortiOS — Exempt web sites from deep inspection; Configuring an SSL/SSH inspection profile.

  2. Prove decrypt on a non-exempt site

    From 10.20.20.10 open HTTPS to a dest that is not in ssl-exempt. Padlock → issuer Fortinet_CA_SSL (or your custom CA). No NET::ERR_CERT_AUTHORITY_INVALID. Then Log & Report › Security Events › SSL.

  3. Prove the exempt dest kept the origin cert

    Open the pinned/bank URL. Issuer is the public CA, not Fortinet. If Log SSL exemptions is on, that dest has an exemption row — not an ssl-anomaly.

CLI — ssl-exempt (wildcard-FQDN + address)
config firewall wildcard-fqdn custom
    edit "PIN_APP"
        set wildcard-fqdn "*.pinned-app.example"
    next
end
config firewall ssl-ssh-profile
    edit "ssl_lan_wan"
        config ssl-exempt
            edit 1
                set type wildcard-fqdn
                set wildcard-fqdn "PIN_APP"
            next
        end
        set ssl-exemptions-log enable
    next
end
# Factory deep-inspection already exempts Finance and Banking,
# Health and Wellness, Personal Privacy in the GUI. Keep them.
# Do not invent FortiGuard category IDs in CLI — use the GUI list
# or an address / wildcard-FQDN you own.
Green proof

Non-exempt site: issuer Fortinet_CA_SSL, no browser CA error. Exempt site: origin issuer. SSL log has the session (and exemption rows if enabled). That is the close — not “the policy is green.”

One flow after go-live

Host 10.20.20.10 ClientHello to 203.0.113.80:443. Policy 1 matches. Profile ssl_lan_wan is Full SSL Inspection. Dest is not in ssl-exempt. FortiGate completes TLS to the origin, validates the server cert against its CA bundle, decrypts, runs AV/IPS/Web Filter on the body, re-encrypts to the client with a leaf signed by Fortinet_CA_SSL. Client store has that CA → padlock is quiet. Reply path is the same two TLS legs.

Same host to a Finance and Banking URL: ssl-exempt hits. Origin cert is passed through. Payload UTM does not see the body. Pinning survives because the cert the app pinned is still on the wire.

Same host, CA never imported: every non-exempt site is NET::ERR_CERT_AUTHORITY_INVALID. That is Side A, not a Web Filter block.

Proof · issuer plus SSL events, not a dashboard tile
Operations monitor with verified connection health checkmarks and an abstract certificate chain
Ops feel. Actual evidence is the browser issuer on a non-exempt site and Log & Report › Security Events › SSL. Artwork checkmarks are not FortiOS.
Proof + SSL debug (proxy-mode WAD)
show firewall policy 1 | grep ssl-ssh-profile
show firewall ssl-ssh-profile ssl_lan_wan
# https status deep-inspection · caname Fortinet_CA_SSL · ssl-exempt list

# Client: padlock on a non-exempt site → Issued by Fortinet_CA_SSL
# Log & Report › Security Events › SSL  (UTM subtype ssl)
# ssl-anomaly / untrusted → origin cert, not a missing client CA

diagnose wad debug enable category ssl
diagnose debug console timestamp enable
diagnose debug enable
# reproduce from 10.20.20.10, then:
diagnose debug disable
diagnose wad debug disable
Untrusted origin vs untrusted FortiGate CA

Client warning on every site = missing Fortinet_CA_SSL. Client warning on one site after CA is trusted = FortiGate could not validate the origin and re-signed with Fortinet_CA_Untrusted (Allow) or blocked it. CLI set untrusted-server-cert allow|block|ignore. Ignore re-signs as trusted with Fortinet_CA_SSL — Full SSL only, and it hides a bad origin. Source: Fortinet Community — How FortiGate handles Untrusted SSL certificates.

Traps + proof

SymptomLikely causeProof
NET::ERR_CERT_AUTHORITY_INVALID on all HTTPSFortinet_CA_SSL not in that browser’s Trusted Root (or Firefox NSS / mobile store).Padlock issuer is Fortinet_CA_SSL. Store listing. GPO did not cover this store.
CA imported, still untrusted on some sitesOrigin failed FortiGate validation; re-sign used Fortinet_CA_Untrusted. Or you imported the Untrusted CA by mistake.Issuer name on the leaf. Community: never import Fortinet_CA_Untrusted.
AV/IPS silent on HTTPS EICARPolicy still certificate-inspection, or dest is ssl-exempt (including Fortinet’s own test FQDN on factory lists).show firewall policy ssl-ssh-profile. Official AV HTTPS test needs deep-inspection and the host not exempt.
One desktop app / bank site dies; browsers are fineCertificate pinning. Deep inspect replaced the CA the app pinned.Exempt that FQDN/address. Confirm origin issuer on that dest only.
SNI ≠ cert CN/SAN (Adobe-style)Server certificate SNI check. Clone the profile; set SNI check disable/enable as required — do not use the read-only factory profile.Fortinet Community: certificate errors with certificate-inspection SNI mismatch.
Flow policy, cert-inspection, “invalid cert” options do nothingIn flow-based mode, certificate-inspection does not validate the cert; untrusted and SNI checks are not performed.FortiOS Certificate inspection note. Switch to proxy or to Full SSL if you need those checks.
HTTP/3 / QUIC bypasses inspectCertificate-inspection forces HTTP/3 Bypass. Full SSL can Inspect / Bypass / Block HTTP/3 and DNS over QUIC.Profile protocol options. Block or inspect QUIC, or force TCP 443.
Do not import Fortinet_CA_Untrusted to “clear the warnings”

That CA exists so the client can still see that FortiGate did not trust the origin. Importing it trains users to ignore a real untrusted server. Fix the origin, or set untrusted-server-cert block, or ignore only with a written exception.

Pilot checklist

Knowledge check

Six judgment items. Submit once. Reasons point back at the section to re-read.

Q1

Policy LAN-to-WAN is accept with AV and IPS attached. SSL/SSH Inspection is certificate-inspection. What can FortiOS actually see on HTTPS?

Correct: b. Certificate inspection inspects headers up to the TLS layer. HTTP/3 is Bypass and cannot be changed on cert-inspect. Re-read Why HTTPS still hides the payload and How to choose.
Q2

You set the policy SSL profile to deep-inspection. Every user immediately gets NET::ERR_CERT_AUTHORITY_INVALID on all HTTPS sites. First cause?

Correct: a. Fortinet_CA_SSL is not in any public browser store. Outbound uses Multiple Clients Connecting to Multiple Servers. Re-read Side A and Flow 1.
Q3

After a correct Fortinet_CA_SSL import, a few sites still warn. A colleague wants to import Fortinet_CA_Untrusted as well. What do you do?

Correct: c. Official Deep inspection: if warnings remain after importing Fortinet_CA_SSL, it is Fortinet_CA_Untrusted. Never import it. Re-read Side A and Untrusted origin vs untrusted FortiGate CA.
Q4

Browsers are fine after CA push. A pinned desktop app and a bank site fail TLS. Safest production move?

Correct: b. Pinning expects a specific server cert/CA. Deep inspect replaces it — exempt that dest. Exempt is Full SSL only. Re-read How to choose and Side C.
Q5

You only need FortiGuard category Web Filter on HTTPS for a guest VLAN. Must you push Fortinet_CA_SSL first?

Correct: d. Official: certificate inspection does not introduce certificate errors for Web Filter on allowed HTTPS; replacement pages are still FortiGate-signed. Flow-based cert-inspect does not validate. Re-read Certificate vs deep and How to choose.
Q6

What is the proof that deep-inspection on LAN-to-WAN is actually decrypting for 10.20.20.10?

Correct: c. Hit counters prove the 5-tuple. Decrypt proof is the re-signed issuer plus SSL events. Re-read Side C, One flow after go-live, and Traps.

Sources

Related: IPS + App Control · Security profiles + SSL · Zone, policy, NAT · Policy first-match · Command center · FortiGate interview