Course menu

Module 2: Firewall PoliciesLesson 2.1 (1 of 5 in this module)6 of 18 in the FortiGate Administrator course

How firewall policies work

Match criteria, top-down first match, the implicit deny, policy IDs versus order, and the session table.

Beginner · 11 min read

What you will learn

After this lesson, you can predict which policy a new connection matches, explain the implicit deny, and tell a policy's ID from its position in the list.

  • Match criteria
  • First match
  • Implicit deny
  • Sessions

A firewall policy is a rule that matches new connections by incoming interface, outgoing interface, source, destination, schedule and service, and then accepts or denies them. The FortiGate checks policies from the top of the list down and uses the first one that matches; a connection that matches none is dropped by the implicit deny policy.

In simple terms: The FortiGate reads its rule list from the top. The first rule that fits the connection decides. If nothing fits, the answer is no.

A real-life situation

FGT1 has a policy that lets the LAN reach the Internet, and above it a new policy meant to block one website. Users complain the site still opens. Another administrator added the block policy below the general one by mistake. Because the FortiGate stops at the first match, the block never runs. Order is everything.

What a policy matches

FieldExampleNotes
Incoming interfaceport2 (LAN)Where the first packet arrives
Outgoing interfaceport1 (WAN)Chosen by the routing table, so routing must agree
SourceLAN-subnet, or a user groupAddresses, and optionally users or devices
Destinationall, a server, an Internet ServiceAfter destination NAT: the real server address
Schedulealways, work-hoursWhen the policy is active
ServiceHTTP, HTTPS, DNS, ALLProtocol and destination port
ActionACCEPT or DENYPlus NAT, logging and security profiles on ACCEPT

A policy matches only when every field matches. A connection from the LAN to the DMZ doesn't match a LAN-to-WAN policy, however open its other fields are.

Top-down, first match

Here is FGT1's rule base for traffic from port2 (LAN) to port1 (WAN), in sequence order:

Seq.IDNameSourceDestinationServiceAction
14Block-SocialLAN-subnetSocial-sites (FQDN group)ALLDENY
22Admins-SSH-outAdmin-PCsallSSHACCEPT
31LAN-to-InternetLAN-subnetallHTTP, HTTPS, DNSACCEPT
–0Implicit denyallallALLDENY

Predict the result for each connection before opening the answer.

PC1 (10.0.1.10) opens https://www.example.com

Policy 4 doesn't match (example.com isn't in Social-sites); policy 2 doesn't match (PC1 isn't an admin PC); policy 1 matches. Accepted by ID 1.

PC1 opens a social-media site over HTTPS

Policy 4 matches first. Denied by ID 4, even though policy 1 below would have allowed it.

PC1 (not an admin PC) connects to a server with SSH

Not policy 4, not policy 2 (wrong source), not policy 1 (SSH isn't in its services). Dropped by the implicit deny, policy 0.

Policy ID versus sequence

Every policy gets an ID when it is created, and keeps it. Its sequence is its current position in the list, which is what decides matching. In the table above, ID 4 was created last but moved to the top. Logs, the session table and debug output all name the ID, so learn to read both.

Sessions remember the decision

Only the first packet of a connection goes through the policy lookup. If it is accepted, the FortiGate creates a session recording the addresses, ports, interfaces, policy ID and NAT. Every later packet in either direction matches the session and is forwarded without a new lookup, which is why no policy is needed for replies. When the rule base changes, FortiOS by default marks existing sessions to be checked again, so a new deny policy also affects connections already open.

Why it works this way

First match makes the rule base predictable: you can read it top-down and know the answer. It also means specific rules (exceptions, blocks, narrow allows) must sit above general ones. The implicit deny makes the firewall safe by default: anything you forgot to allow stays blocked.

Common mistakes

  • Putting a specific block or allow below a broader policy that already matches the same traffic.
  • Forgetting that the outgoing interface comes from the routing table: no route, no policy match.
  • Writing policies for return traffic. Sessions handle replies.
  • Reading the ID column as the order. The order is the list position.

Key takeaways

✅ Key takeaways
  • A policy matches on interfaces, source, destination, schedule and service; all must match.
  • Policies are checked top-down and the first match wins; put specific policies above general ones.
  • Unmatched traffic hits the implicit deny, policy 0, which doesn't log by default.
  • IDs are permanent names; the sequence decides matching. Sessions carry the decision for replies.

Check yourself

Predict · scenario 1

A DENY policy for a site is at sequence 5. An ACCEPT policy for all LAN web traffic is at sequence 2. Is the site blocked?

Predict · scenario 2

Traffic matches no policy. What happens, and is it logged by default?

Predict · scenario 3

You move policy ID 3 to the top of the list. What does the traffic log show for sessions it matches afterwards?

FAQ

If I move policy 7 to the top, does its ID change?
No. The ID stays 7 for life; only its position in the list (its sequence) changes. Logs record the ID, so they keep pointing at the same rule after reordering.
Can I log what the implicit deny drops?
Yes. Logging on the implicit deny is off by default; turn on 'Log Violation Traffic' for it, or add your own deny policy at the bottom with logging enabled.