Home Knowledge base Firewalls & Network Security Configure a FortiGate Firewall Policy and NAT from the CLI KNOWLEDGE BASE

Configure a FortiGate Firewall Policy and NAT from the CLI

A hands-on FortiOS CLI walkthrough: address objects, a least-privilege firewall policy, source NAT, a Virtual IP for inbound DNAT, an IPsec VPN, and the diagnostic commands to verify it all.

This guide walks through building a working FortiGate ruleset entirely from the FortiOS command line. The CLI is faster, scriptable and far less error-prone than clicking through the GUI for repetitive work, and it is the only reliable way to document a configuration as code. Commands below follow modern FortiOS (7.x) syntax and are confirmed against Fortinet's documentation; object names, IP addresses and interface names are examples, so replace them with your own.

Connect to the FortiGate over SSH or the console port and log in as an administrator before you begin.

1. Create address objects

Never reference raw IP addresses inside policies. Define named address objects first, so policies read clearly and objects can be reused. Here we create an internal LAN subnet, a single internal web server, and an FQDN object.

config firewall address
    edit "LAN_Subnet"
        set subnet 192.168.10.0 255.255.255.0
    next
    edit "WebServer_Internal"
        set subnet 192.168.10.50 255.255.255.255
    next
    edit "Updates_FQDN"
        set type fqdn
        set fqdn "updates.example.com"
    next
end

For a range instead of a subnet, use set type iprange with set start-ip and set end-ip. Group related objects with config firewall addrgrp.

2. Build a least-privilege outbound policy with SNAT

A firewall policy pairs a source interface/zone with a destination interface/zone and decides what to do. This policy lets the LAN reach the internet, enables source NAT so internal addresses are translated to the outgoing interface IP, turns on logging, and attaches security profiles.

config firewall policy
    edit 0
        set name "LAN_to_Internet"
        set srcintf "port2"
        set dstintf "port1"
        set srcaddr "LAN_Subnet"
        set dstaddr "all"
        set action accept
        set schedule "always"
        set service "HTTP" "HTTPS" "DNS"
        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 logtraffic all
    next
end

Notes: editing policy ID 0 tells FortiOS to assign the next free ID automatically. set nat enable performs source NAT using the egress interface address; to NAT to a different pool, define an IP pool with config firewall ippool and add set ippool enable and set poolname. Avoid set srcaddr "all" / set dstaddr "all" with set service "ALL" on production traffic, that is the broad rule that defeats the firewall.

3. Publish an internal server with a Virtual IP (DNAT)

To make an internal web server reachable from the internet, FortiOS uses a Virtual IP (VIP) to perform destination NAT. The VIP maps a public/external IP (and optionally a port) to the internal server, then a policy permits the traffic.

config firewall vip
    edit "VIP_WebServer"
        set extip 203.0.113.10
        set mappedip "192.168.10.50"
        set extintf "port1"
        set portforward enable
        set protocol tcp
        set extport 443
        set mappedport 443
    next
end

Now allow inbound traffic to that VIP. The destination address in the policy is the VIP object, and you do not enable NAT on this inbound policy (the VIP already handles the destination translation):

config firewall policy
    edit 0
        set name "Internet_to_WebServer"
        set srcintf "port1"
        set dstintf "port2"
        set srcaddr "all"
        set dstaddr "VIP_WebServer"
        set action accept
        set schedule "always"
        set service "HTTPS"
        set logtraffic all
    next
end

4. Optional: switch to Central NAT

By default FortiOS uses policy-based NAT (the set nat enable shown above). Larger or more complex environments sometimes prefer Central NAT, which moves SNAT and DNAT into dedicated, ordered tables independent of security policies. Enable it globally first:

config system settings
    set central-nat enable
end

Then define source-NAT behaviour in the central SNAT map:

config firewall central-snat-map
    edit 1
        set orig-addr "LAN_Subnet"
        set srcintf "port2"
        set dst-addr "all"
        set dstintf "port1"
        set nat enable
    next
end

With Central NAT enabled, VIPs continue to handle DNAT but are no longer attached inside the firewall policy. Pick one model and stay consistent, because mixing mental models is how NAT bugs are born.

5. Add a site-to-site IPsec VPN (IKEv2)

Connect a branch to head office with a route-based IPsec tunnel. Phase 1 defines the peer and crypto; Phase 2 defines the protected subnets.

config vpn ipsec phase1-interface
    edit "VPN_to_Branch"
        set interface "port1"
        set ike-version 2
        set peertype any
        set proposal aes256-sha256
        set dhgrp 14
        set remote-gw 198.51.100.20
        set psksecret <your-strong-pre-shared-key>
    next
end
config vpn ipsec phase2-interface
    edit "VPN_to_Branch_P2"
        set phase1name "VPN_to_Branch"
        set proposal aes256-sha256
        set dhgrp 14
        set src-subnet 192.168.10.0 255.255.255.0
        set dst-subnet 192.168.20.0 255.255.255.0
    next
end

Add a static route pointing the remote subnet at the tunnel interface, then a policy to permit the traffic both ways:

config router static
    edit 0
        set dst 192.168.20.0 255.255.255.0
        set device "VPN_to_Branch"
    next
end

Make sure both sides use matching Phase 1/Phase 2 proposals and DH groups, because mismatched proposals are the number-one cause of tunnels that never come up.

6. Verify and troubleshoot

After committing changes, verify before you trust. These diagnostics are the core of FortiGate troubleshooting:

# Trace exactly how a packet is handled (policy match, NAT, drop reason)
diagnose debug flow filter addr 192.168.10.50
diagnose debug flow show function-name enable
diagnose debug enable
diagnose debug flow trace start 10

# Watch live traffic on an interface (verbosity 4 shows headers + interface)
diagnose sniffer packet port1 'host 203.0.113.10' 4

# Check which policy a session matched
diagnose firewall iprope lookup <src-ip> <src-port> <dst-ip> <dst-port> <protocol> <interface> <pol_type>

# IPsec VPN tunnel status
diagnose vpn tunnel list
diagnose vpn ike gateway list

# Turn debug off when done
diagnose debug disable
diagnose debug reset

The diagnose debug flow output is the single most valuable tool: it tells you precisely which policy a packet matched (or that it matched none), whether NAT was applied, and the exact reason for any drop, eliminating guesswork.

Need help?

Configuring FortiGate correctly across many sites, with HA, SD-WAN and centralized management, is where small mistakes become outages. SKYLINE installs, configures and supports Fortinet FortiGate across Saudi Arabia. Browse the firewalls & network security category, see the full marketplace, or contact us / call +966 50 993 9334.

SKYLINE Engineering

@skyline

The engineering team at SKYLINE Industrial Solutions. We publish field-tested guides drawn from real KSA and GCC deployments.

See author profile
SKYLINE engineering services

Need this implemented for you?

Reading is free — building it right takes a team. SKYLINE engineers ship Firewalls & Network Security for Aramco vendors, banks, hospitals and government agencies across Saudi Arabia. Talk to us before you start.

Aramco Approved Contractor ISO 9001 · ISO 27001 SAMA CSF aligned NCA ECC ready 247+ KSA clients

Comments

0 total · 0 threads
Be the first to leave a comment.