Recommended Services
Supported Scripts
FortiGate policy components: interfaces, zones, firewall policy and security profiles

A FortiGate firewall does nothing until you write a policy. Every packet crossing it is matched against an ordered list of firewall policies, and whichever one matches first decides whether the traffic is allowed, how it is translated, and which security inspection it receives. Understanding that matching process — and the difference between interfaces, zones, NAT and security profiles — is the whole job. This guide breaks it down.

How FortiGate Evaluates Traffic

When a packet arrives, FortiOS looks for the first policy matching all of these at once: incoming interface, outgoing interface, source address, destination address, service (protocol and port), schedule, and user or group where configured.

  • Top-down, first match wins. Once a policy matches, evaluation stops.
  • An implicit deny sits at the bottom. Anything unmatched is dropped — enable logging on it to see what you’re missing.
  • Policies are stateful. Allow the outbound session and return traffic is permitted automatically.
  • Order beats intent. A broad allow near the top makes every specific rule beneath it dead configuration.

Modern FortiOS lists policies by interface pair, which hides ordering problems if you’re not careful. Switch the policy list to Sequence Grouping view when auditing so you see true evaluation order.

Interfaces and Zones

An interface is a physical port, VLAN sub-interface, aggregate or tunnel. A zone is a named group of interfaces that policies can treat as one.

Zones are worth using as soon as you have more than a couple of internal segments. If you have four internal VLANs that all need the same internet access, one policy from zone INTERNAL to wan1 replaces four near-identical policies — and when you add VLAN five, you add it to the zone rather than writing another rule.

config system zone
    edit "INTERNAL"
        set interface "internal1" "internal2" "vlan10" "vlan20"
        set intrazone deny
    next
end

Note set intrazone deny. By default, traffic between members of the same zone is allowed without a policy. Setting it to deny forces you to write explicit rules for VLAN-to-VLAN traffic, which is what you want in any segmented network.

Anatomy of a Firewall Policy

FieldWhat it does
NameFree text. Name every policy — unnamed policies become unmaintainable within months.
Incoming / Outgoing InterfaceThe direction. Determines which policies are even considered.
Source / DestinationAddress objects, address groups, or geography objects.
ServiceProtocol and port objects such as HTTPS, DNS, or a custom object.
ScheduleWhen the policy is active. always unless you have a reason.
ActionACCEPT, DENY, or IPsec for policy-based VPN.
NATEnables source NAT for this policy.
Security ProfilesThe inspection applied to allowed traffic.
Log Allowed TrafficOff by default on some builds. Turn it on — you cannot troubleshoot what you don’t log.

A typical outbound policy in CLI form:

config firewall policy
    edit 0
        set name "INTERNAL-to-Internet"
        set srcintf "INTERNAL"
        set dstintf "wan1"
        set srcaddr "LAN_Subnets"
        set dstaddr "all"
        set action accept
        set schedule "always"
        set service "HTTP" "HTTPS" "DNS" "NTP"
        set nat enable
        set utm-status enable
        set ssl-ssh-profile "certificate-inspection"
        set av-profile "default"
        set ips-sensor "default"
        set application-list "default"
        set webfilter-profile "default"
        set logtraffic all
    next
end

NAT: Source NAT vs Virtual IP

FortiGate handles the two directions of NAT in completely different places, and confusing them is the most common configuration mistake.

Outbound: source NAT

Tick NAT in the policy. By default it uses the outgoing interface address. To present a different public IP, apply an IP pool:

config firewall ippool
    edit "mail-outbound"
        set type overload
        set startip 203.0.113.25
        set endip 203.0.113.25
    next
end
# then in the policy:  set ippool enable / set poolname "mail-outbound"

Inbound: virtual IP (destination NAT)

To publish an internal server, create a VIP and then use it as the destination of an inbound policy:

config firewall vip
    edit "web-server-vip"
        set extip 203.0.113.10
        set mappedip "192.168.10.20"
        set extintf "wan1"
        set portforward enable
        set protocol tcp
        set extport 443
        set mappedport 443
    next
end

config firewall policy
    edit 0
        set name "Internet-to-WebServer"
        set srcintf "wan1"
        set dstintf "INTERNAL"
        set srcaddr "all"
        set dstaddr "web-server-vip"
        set action accept
        set schedule "always"
        set service "HTTPS"
        set utm-status enable
        set ips-sensor "protect_http_server"
        set logtraffic all
    next
end

Two things trip people up here. The policy destination is the VIP object, never the internal IP. And you do not enable NAT on an inbound VIP policy — doing so also source-NATs the traffic, and your web server logs every visitor as the firewall.

Security Profiles: Where the Real Protection Lives

Allowing traffic is layer 3/4. Security profiles are what inspect the content:

ProfileWhat it inspects
AntiVirusFiles in HTTP, FTP, SMTP, IMAP and POP3 streams
IPSExploit signatures — the most valuable profile on inbound server policies
Web FilterURL categories and reputation for outbound browsing
Application ControlIdentifies applications regardless of port
DNS FilterBlocks known malicious domains at resolution time
SSL/SSH InspectionGoverns how much of the encrypted traffic above can actually be seen

That last row is the one that determines whether the others do anything. With certificate inspection, FortiGate only reads the certificate and SNI — enough for web filtering by hostname, but antivirus and IPS cannot see inside the payload. With deep inspection, it decrypts and re-encrypts the session, so all profiles work fully — at the cost of CPU, and requiring the FortiGate CA certificate on every client device.

A pragmatic compromise: deep inspection on outbound user traffic (with exemptions for banking and health categories), certificate inspection on server-to-server flows.

Troubleshooting: Which Policy Matched?

Stop guessing — ask the firewall. The policy lookup tool in the GUI (Policy & Objects » Policy Lookup) and its CLI equivalent tell you exactly which policy a hypothetical packet would hit:

# Which policy would match this traffic?
diagnose firewall iprope lookup 192.168.10.50 34500 8.8.8.8 53 17 internal1

# Watch a live session being processed, end to end
diagnose debug reset
diagnose debug flow filter addr 192.168.10.50
diagnose debug flow show function-name enable
diagnose debug flow trace start 20
diagnose debug enable
# ... reproduce the traffic ...
diagnose debug disable

# Inspect active sessions
diagnose sys session filter dst 203.0.113.10
diagnose sys session list

diagnose debug flow is the single most useful command on the platform. It shows the routing decision, the policy ID that matched, whether NAT was applied, and the exact reason a packet was dropped.

Policy Best Practices

  • Name every policy and keep the naming scheme consistent (SOURCE-to-DESTINATION-purpose).
  • Never use ALL as a service on an internet-facing policy. Specify the ports the application actually needs.
  • Specific policies above general ones. Review order after every addition.
  • Log the implicit deny so blocked traffic is visible rather than mysterious.
  • Apply IPS to every inbound server policy — it is the profile that stops exploitation of unpatched applications.
  • Audit for unused policies using the hit counters in the policy list; a policy with zero hits over months is either dead or a mistake.

Conclusion

FortiGate policies are simple once the model is clear: traffic is matched top-down on interface pair, addresses and service; the first match wins; everything else is implicitly denied. Use zones with intrazone deny to keep the rule count sane, enable NAT on outbound policies and VIPs for inbound ones (never NAT on a VIP policy), and attach IPS and antivirus profiles so allowed traffic is actually inspected. When something doesn’t work, diagnose debug flow will tell you why in seconds.

Leave a Reply

Your email address will not be published. Required fields are marked *