T Techclick ← FortiGate hub
FortiGate · Evidence desk · Interactive lesson

Prove FortiGate — five tickets, first tool, one field

02:11. Queue has five P1/P2s. Helpdesk wants a new accept. You do not guess. You pick one first tool — session table, diagnose debug flow, or Log & Report — and you paste one proof field. Lab values only. Confirm live syntax, VDOM, and change-control before you type on a real box.

~20 min read · L2 primary · Quiz at end

After this page you can

Quick answer

Live 5-tuple right now → session table first (filter then list; proof is proto_state + policy_id). Packet never installed a session, or you need the per-packet verdict → filtered diagnose debug flow (then stop). It already happened → Log & Report Forward Traffic; proof is action + policyid, and utmaction if UTM touched it. You change nothing until those fields are in the ticket.

Say this out loud

Filter is not a list. proto_state 01 is not a missing allow. A traffic log action=accept is not a finished handshake. Debug flow without a filter is a change you did not get approved. Empty flow on HTTPS can be NP offload — that is official, not a broken CLI.

Hero · 02:11 evidence desk
Teaches: night-shift FortiGate work is three instruments — session, flow, logs
Notice: the ticket is won on one proof field, not on a cloned policy.

1. Why the desk exists

The session factory taught how FortiOS builds a flow. This page is the night shift. Five tickets. Each one has a first tool and a proof field. If you cannot name both, you are not ready to ask for a change window.

Concept: evidence is a field, not a feeling. Path: pick the instrument → filter → read one field → write the ticket sentence. Do: close all five tickets below without adding policy 15.

Live box warning

Fortinet documents that diagnose debug flow generates a significant amount of data. If the FortiGate is connected to FortiAnalyzer or FortiCloud, that output is recorded as event log messages. Do not run it longer than necessary. Unfiltered flow, session-table flush, and leaving debug enabled are forbidden on this desk.

2. Three instruments

Pre-train the three words before the tickets. You will use all three tonight. You will start with only one.

Session table — live now

diagnose sys session filter then list. Official filter keys include src, dst, dport, proto, proto-state, policy, vd. Proof fields: proto_state, policy_id, orig/reply tuple, NAT hooks.

Debug flow — this packet

CLI: filter, enable, trace start <N>, then trace stop. GUI: Network → Diagnostics → Debug Flow. Proof lines: received a packet, allocate a new session, Allowed by Policy-N, or no line at all.

Log & Report — already happened

GUI pane Log & Report. Forward Traffic is type=traffic subtype=forward. Proof fields from the official log reference: action, policyid, sessionid, utmaction, utmref.

They are not substitutes

A session is now. A flow trace is why this packet. A log is history. iprope lookup (predicted policy) is none of the three — do not treat it as live proof.

Feel · Packet → Session → Verdict → Proof
Teaches: packet becomes a session, then a verdict, then a proof field
Notice: you write the last panel — the field — not the first feeling.

3. First-tool decision

Flowchart first. Read the diamond, then the prose.

Flow 1 · first tool
What is true about this 5-tuple right now? User is failing this second, and you have src / dst / port? YES Session table proto_state · policy_id NO / past Already happened? Log & Report action · policyid Debug flow filter · start N · stop No session + need this-packet verdict → yellow. History → logs. Live tuple exists or should exist → session table first. Never start unfiltered.

Read the diamond first. Yellow is isolate but risky live. Never start there because someone is loud.

Feel · Session / Flow / Logs
Teaches: first tool is a three-way split — session, flow, or logs
Notice: three paths. One first click. The other two are confirmation, not the opener.

4. How to choose

If you seeFirst toolProof fieldNot first
HTTPS hangs right now; you have src/dst/portSession table: filter then listproto_state + policy_idNew accept policy
User said “blocked” 10 minutes ago; session is goneLog & Report → Forward Trafficaction + policyidUnfiltered session dump
Filter + list is empty; packet may never have arrivedFiltered debug flow“received a packet…” vs silenceAdding policy 15
Policy already accepts; page is a FortiGuard / IPS blockLog & Report (traffic + Security Events)utmaction (and utmref)Another accept
Debug flow prints nothing for live HTTPSSession npu_state, then ICMP flow or disable NP offloadOfficial NP6/NP7 exceptionLeaving flow on overnight

Primary source for the session column: FortiOS Administration Guide — Using a session table. Primary source for the flow column: Debugging the packet flow plus Using the debug flow tool. Primary source for the log column: FortiOS Log Message Reference — Log message fields.

5. Side A / B / C — the three tools

Hard words, then the commands. Tickets come next. Every step cites one official page.

Side A — session table (isolate)

Source: Using a session table. FortiOS places an entry in the session table for each traffic session that passes through a security policy. The CLI supports filters so you show only the data you need.

  1. State VDOM and HA role

    get system status and, if clustered, get system ha status. An empty table on the standby is not a missing policy.

  2. Arm the filter — this is not a list

    diagnose sys session filter src 10.10.20.45. Official options also include dst, dport, proto, proto-state, policy, vd (−1 matches all VDOMs), and clear.

  3. List and read the proof fields

    diagnose sys session list. Quote proto_state, policy_id, orig-tuple, reply-tuple, NAT hooks. TCP proto_state=01 is SYN seen — not established. 11 is the established pair operators look for after a fix.

  4. GUI twin (optional show-back)

    FortiView Sessions, or Security Fabric → Physical Topology → Metrics → Sessions. Same 5-tuple. Do not open Firewall Policy from this screen to add 15.

FGT-LAB # session table · isolate Training mock · not live
FGT-LAB # diagnose sys session filter src 10.10.20.45
session filter:
        vd: 0
        proto: any
        src: 10.10.20.45-10.10.20.45
        dst: any
filter applied.

FGT-LAB # diagnose sys session list
session info: proto=6 proto_state=01 duration=48 expire=3552 timeout=3600
  orig-tuple: 10.10.20.45:51990 -> 198.51.100.80:443
  reply-tuple: 198.51.100.80:443 -> 203.0.113.20:18422
  hook=post dir=org act=snat 10.10.20.45:51990->203.0.113.20:18422
  policy_id=14 pol_idx=0
  npu_state=00000000
  total: 1 session listed

Proof field: proto_state=01 with policy_id=14. Filter is armed; list is a second command. Source: Using a session table — diagnose sys session filter / list.

Side B — diagnose debug flow (isolate, risky)

Source: Debugging the packet flow (CLI) and Using the debug flow tool (GUI). Packet-flow debug is a CLI-first instrument. The GUI path is Network → Diagnostics → Debug Flow.

  1. Filter first — official keys

    IPv4: diagnose debug flow filter with addr, saddr, daddr, port, sport, dport, proto, vd, or clear. IPv6 uses filter6. GUI Basic filter = addr / port / proto. GUI Advanced = saddr / sport / daddr / dport / proto.

  2. Enable, name functions, start N packets

    Official sequence: diagnose debug enablediagnose debug flow filter addr 10.10.20.45diagnose debug flow show function-name enablediagnose debug flow trace start 100. GUI: click Start debug flow. Messages are real-time.

  3. Read the official-style lines

    Look for received a packet, allocate a new session, find a route, Allowed by Policy-N: SNAT. Silence after a reproduce is also evidence — the packet never hit this VDOM, or the session is NP-offloaded.

  4. Stop is part of isolate

    diagnose debug flow trace stop, then disable / reset. GUI: Stop debug flow, then Save as CSV if you need the file. Add the Function column (Configure Table) when you want fw_forward_handler next to the message.

FGT-LAB # diagnose debug flow · isolate then off Training mock · not live
FGT-LAB # diagnose debug enable
FGT-LAB # diagnose debug flow filter addr 10.10.20.45
FGT-LAB # diagnose debug flow show function-name enable
FGT-LAB # diagnose debug flow trace start 100
id=20085 trace_id=17 func=print_pkt_detail msg="vd-root:0 received a packet(proto=6, 10.10.20.45:51990->198.51.100.80:443) from port2."
id=20085 trace_id=17 func=resolve_ip_tuple msg="allocate a new session-00000e90"
id=20085 trace_id=17 func=fw_forward_handler msg="Allowed by Policy-14: SNAT"
FGT-LAB # diagnose debug flow trace stop
FGT-LAB # diagnose debug disable
FGT-LAB # diagnose debug reset

Proof field: the Allowed by Policy-14: SNAT line (official sample style: Allowed by Policy-3: SNAT). Stop and reset are mandatory. Source: Debugging the packet flow.

https://fgt-lab.example.com/#/network/diagnostics/debug-flow
Training mock · not live

Network → Diagnostics → Debug Flow · VDOM root

Debug Flow

FiltersOutput
Advanced
6 (TCP)
10.10.20.45
any
198.51.100.80
443

FortiOS Administration Guide · Using the debug flow tool. Path: Network → Diagnostics → Debug Flow. Advanced fields map 1:1 to saddr / sport / daddr / dport / proto. Next click after the reproduce: Stop debug flow, then Save as CSV.

NP6 / NP7 — official exception

Flow monitoring does not work for traffic offloaded to NP6 or NP7 processors. Official workarounds: test with ICMP (ICMP is not offloaded) or temporarily disable NP offloading. Do not treat a blank HTTPS trace as “the packet never arrived” until you have checked npu_state on the session.

Side C — Log & Report (history)

Source: Log message fields. In the GUI you view logs in the Log & Report pane (formatted). Raw format is a download you open in a text editor. A traffic log is type="traffic" subtype="forward".

  1. Open Forward Traffic, filter the 5-tuple

    Log & Report → Forward Traffic. Filter source 10.10.20.45, destination, service HTTPS. You are looking for a row that already exists — not a live session.

  2. Quote the official fields

    action (example in the reference: close; you will also see accept / deny / ip-conn). policyid. sessionid. trandisp / transip if NAT. utmaction is “Security action performed by UTM.” utmref is the UTM reference number — follow it into Security Events.

  3. If utmaction is not allow, open Security Events

    Web Filter, IPS, Antivirus — whichever profile the policy attached. The traffic log can say the firewall accepted while UTM blocked. That is not a missing accept rule.

https://fgt-lab.example.com/#/log/traffic/forward
Training mock · not live

Log & Report → Forward Traffic · VDOM root · formatted view

Forward Traffic

FormattedRaw (download)
10.10.20.45 : 40772
198.51.100.80 : 443
deny
0
traffic / forward
allow / —

FortiOS Log Message Reference · Log message fields. Formatted view lives in Log & Report. Raw is a download. Proof on this row: action=deny and policyid=0 (implicit). Next click: do not add policy 15 until you know which interface pair missed a policy.

6. Five tickets

Each card is the same contract: first tool, proof field, ticket sentence, what you do not do. Lab 5-tuple: 10.10.20.45198.51.100.80:443, SNAT 203.0.113.20.

Flow 2 · five tickets → first tool → proof field
Ticket → first tool → field you paste T1 HTTPS hang session · proto_state T2 already blocked log · action+policyid T3 no session flow · received? T4 UTM after accept log · utmaction T5 empty flow npu_state · ICMP Ticket sentence you write T1 proto_state=01 policy_id=14 — handshake never finished. Not a missing allow. T2 action=deny policyid=0 — implicit deny in Forward Traffic. Fix the interface pair, not a clone of 14. T3 No “received a packet” after filtered start 100 — packet never hit this VDOM (or you are on standby). T4 action=accept / close and utmaction=block — UTM, not policy. Follow utmref. T5 npu_state shows offload — official: flow does not see NP6/NP7. Retest ICMP or disable offload.

Five tickets. Five first tools. Five fields. If you cannot point at this row, keep isolating.

T1 — HTTPS allowed, handshake never finishes

P2INC-441802:11Finance SaaS

Browser stays on connecting to 198.51.100.80:443. Helpdesk wants a new accept. Lab user 10.10.20.45.

First toolSession table — filter src then list
Proof fieldproto_state=01 with policy_id=14

Hypothesis: policy already accepts. TCP is not established. The Side A CLI card is this ticket. SNAT hook is present. Reply tuple exists. Handshake is one-way.

Ticket sentence: Policy 14 already matched. proto_state=01 — SYN seen, not established. Adding policy 15 will not finish TCP. Isolate the return path / server SYN-ACK. Change-control only with an owner if the SNAT pool or return route is wrong.

T2 — “It was blocked ten minutes ago”

P2INC-441902:28New VLAN

User on a new subnet tried once and gave up. Live session list for that src is empty. NOC wants you to “just add the same policy again.”

First toolLog & Report → Forward Traffic
Proof fieldaction=deny + policyid=0

History, not live. The Side C portal is this ticket. Official fields: type=traffic subtype=forward, action, policyid, srcip, dstip, srcintf, dstintf.

Ticket sentence: Forward Traffic shows action=deny policyid=0 for this 5-tuple — implicit deny, not a broken session. Next isolate is the interface pair on that log row. Change-control is one new policy on the right srcintf/dstintf, not a clone of 14 on the old pair.

T3 — Filter + list is empty, user is clicking now

P1INC-442102:41New host

Session filter for 10.10.20.88 lists nothing. User is reproducing. You do not know if the packet reached this FortiGate.

First toolFiltered diagnose debug flow (then stop)
Proof fieldreceived a packet… from <intf> — or silence

Use Side B. Confirm you are on the HA primary and the correct VDOM first. Then filter addr 10.10.20.88, trace start 100, reproduce, read, stop.

If you get vd-root received a packet … from port2 and then a deny or no route — the packet arrived; the verdict is on the next line. If you get nothing, the packet never hit this VDOM (wrong box, wrong VLAN, or you are on standby). That silence is the proof. Do not add a policy for a packet that never arrived.

T4 — Policy accept, page is a FortiGuard block

P3INC-442302:55Web Filter

Session shows policy_id=14 and proto_state=11. User still sees a FortiGuard replacement page. Someone already asked to “open 443.”

First toolLog & Report — traffic row, then Security Events via utmref
Proof fieldutmaction (official: “Security action performed by UTM”)

Established TCP plus a block page is UTM, not a missing accept. Official traffic-log example includes utmaction="allow" and utmref=0-220586. Your row will show a non-allow UTM action and a utmref you follow.

Ticket sentence: Firewall accepted (policyid=14, session established). utmaction is the block. Change-control is the Web Filter / IPS profile or an override — not policy 15.

T5 — Debug flow is empty on production HTTPS

P2INC-442503:08NP offload

Hardware FortiGate. Session exists, users work or fail, but diagnose debug flow prints nothing for that HTTPS 5-tuple. Junior engineer wants to leave flow on until morning.

First toolSession list npu_state, then ICMP flow or disable NP offload
Proof fieldOfficial NP6/NP7 exception + npu_state

Fortinet: flow monitoring does not work for traffic offloaded to NP6 or NP7. Official options: test with ICMP (not offloaded), or temporarily disable NP6 fastpath / disable NP7 offloading on the firewall policy that accepts the traffic.

Ticket sentence: Empty HTTPS flow is not proof the packet missed the box. Session npu_state shows offload. Retest ICMP with a tight filter, or an approved offload disable, then stop debug. Leaving flow on is forbidden.

7. After the capture

Once the first tool has spoken, the runtime path is short. You do not start a second dangerous tool because you are curious.

  1. Paste the field

    One line in the ticket: instrument + field + 5-tuple + VDOM + HA role.

  2. Turn dangerous things off

    diagnose debug flow trace stop → disable → reset. GUI: Stop debug flow. Confirm no leftover filter if you will hand the box to day shift (diagnose sys session filter clear is a filter clear — not a session flush).

  3. Decide isolate vs change-control

    A read is isolate. A new policy, NAT pool, profile change, or NP disable on a production policy is change-control: one owner, one reversible edit, same 5-tuple retest.

  4. Retest the same tuple

    Success is proto_state=11 (or the user transaction) plus, if UTM was in play, utmaction=allow. Green HA and a green dashboard widget are not the retest.

Proof · field then checkmark
Teaches: proof is a field and a retest, not a green widget
Notice: a recovered ticket is the same 5-tuple with the new field value, not a green cluster badge.

8. Traps and proof

TrapYou will hearYou write instead
List without filter“Just dump sessions”Filter src, then list. Official CLI is filter + list.
Accept = healthy“Add policy 15”T1: policy_id=14 + proto_state=01
Empty table = no policy“Nothing is matching”Wrong VDOM / standby, or T3 — run filtered flow
Empty flow = never arrived“Packet never hit us”T5: check npu_state and the NP6/NP7 exception first
Traffic accept = page works“Firewall allowed it”T4: read utmaction / utmref
Debug forever“Leave flow on so we catch it”Filter, trace start N, stop, disable, reset
Filter clear = session clear“Clear the filter to drop the hang”filter clear clears the view. Session clear is a user-impacting change.
Proof checklist (paste into the ticket)
Interview close

I pick the instrument from the symptom: live tuple → session table, this-packet verdict → filtered debug flow, already happened → Log & Report. I quote proto_state, the flow Policy-N line, or action/policyid/utmaction. I do not add accept rules to fix a one-way handshake or a UTM block. I stop debug. Empty HTTPS flow makes me say NP offload out loud.

Knowledge check

Six judgments. Each maps to a first tool or a proof field. Check answers. Reset and retry if you miss isolate versus change.

Q1

HTTPS is hanging right now. You have src 10.10.20.45 and dst :443. First tool?

Correct: b. Live 5-tuple → session table. Filter is not a list. Re-read Side A and T1.
Q2

Session list: proto_state=01, policy_id=14, SNAT hook present. What do you write?

Correct: c. Proof field is proto_state=01. Re-read T1 and the Side A CLI card.
Q3

User was blocked ten minutes ago. Live session list for that src is empty. First tool?

Correct: a. History → logs. Official fields live in the Log & Report formatted view. Re-read T2 and Side C.
Q4

On a hardware FortiGate, filtered debug flow prints nothing for a live HTTPS session. Official next step?

Correct: d. Official Debugging the packet flow exception. Re-read T5 and the NP callout.
Q5

You finished a filtered debug flow capture. Which step is still isolate, and required?

Correct: b. Fortinet: do not run debug flow longer than necessary. Stop is part of isolate. Re-read Side B step 4.
Q6

Session is proto_state=11 on policy 14, but the user gets a FortiGuard block page. What is the proof field?

Correct: c. Official field: UTM Action (utmaction) — security action performed by UTM. Re-read T4 and Side C.

Sources

Related: FortiGate session factory · FortiGate troubleshooting command center · FortiGate interview · Policies and NAT · FortiGate interview hub