Fortigate Best practices – CLI Examples (7.6)

Below is a hardened, modular baseline that merges your management/HA/monitoring/logging snippets with additional controls for loopback-VPN, strict local-in rules, and geo-fencing. Each block stands alone and can be applied independently. Citations point to where the Fortinet Best Practices guide aligns with the control.

Management (admin surface hardening)

Central identity for admin (LDAP/SAML) + MFA
Use LDAPS (not LDAP), least-privileged bind, or RADSEC for RADIUS or SAML.
enable MFA on admin accounts.

# Example LDAPS server (minimum hardening)
config user ldap
  edit "ad-ldaps"
    set server "dc01.example.com"
    set cnid "sAMAccountName"
    set dn "dc=example,dc=com"
    set type regular
    set username "CN=ldap-reader,OU=Svc,DC=example,DC=com"
    set password ********
    set secure ldaps
    set port 636
  next
end

# Map LDAP group to an admin profile
config system accprofile
  edit "Ops-Admins"
    set secfabgrp read-write
    set sysgrp read-write
    set fwgrp read-write
    set loggrp read-write
  next
end
config system admin
  edit "ops-admins-sso"
    set remote-auth enable
    set accprofile "Ops-Admins"
    set wildcard enable
    set two-factor email
    set email-to "[email protected]"
  next
end

Example for SAML for Admin login – View the post –> Here

config vpn certificate remote
    edit "EntraID-SSO-Admins"
        set remote "-----BEGIN CERTIFICATE-----
MIIDijCCAnKgAwIBAgIEXXGa6TANBgkqhkiG9w0BAQsFADBbMScwJQYDVQQDDB5SZWdlcnkgU2Vs
Zi1TaWduZWQgQ2VydGlmaWNhdGUxIzAhBgNVBAoMGlJlZ2VyeSwgaHR0cHM6Ly9yZWdlcnkuY29t
MQswCQYDVQQGEwJVQTAgFw0yNTA5MjEwMDAwMDBaGA8yMTI1MDkyMTE3MTI0NFowTDEYMBYGA1UE
AwwPZ29vZC1qb2IudG8ueW91MSMwIQYDVQQKDBpSZWdlcnksIGh0dHBzOi8vcmVnZXJ5LmNvbTEL
MAkGA1UEBhMCVUEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDPS1Qo5AJ7Fuw7TozG
Mu3vFnShXpkav3qzKbYlu6KhPHdY81Qgc5Sop/vk3+QusezrWKr1YYsusWWXMjvgX10IGI4CNM4l
CIpBl2irzfRUidw7Phxg/C9SfXKLzK0tFb0WN7VMbB6/4heR3EdjBDxl0WuWrIM8CjPNkGD+QX1C
YygUZum1g2TJo2pyz9mXRnZfFrNkrPbvayL30RmdLfOMdgyGfiwrALVLnBXN/mMBSk4T2OLxhljN
JS+duy1jJmrkjZmDyefGxKMf4+xqAgyJJgE99vNp+7dFvgirDab7lxEhT5DN+QP8ezzZhLw2vbEu
B1ajMAHi1GcQQiPfrQWNAgMBAAGjYzBhMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGG
MB0GA1UdDgQWBBSWwTYTdCaXXZ9WnDrvCEuI4u8yDDAfBgNVHSMEGDAWgBSWwTYTdCaXXZ9WnDrv
CEuI4u8yDDANBgkqhkiG9w0BAQsFAAOCAQEAjTRYXUgD/kkpNJagn4kNMHyt13T0tckdfCSMbRky
GCjYrHNO37f51k1CG0qhh9iwPCVrGOngiRoLcDK+QvYpmx/DpI48PlaUgZXNt58l8Y+PwLV/0hmP
paLG7VNwV4gOxN0imNEitpMKorR6PZsjVB3SYeekzn1P07kwR/qrYn5fNlu280tQg5j8DMKklQSP
KLzxRanjSgdx8bWtNebtm+ELcArFvfR/DNuacQF64/Rub229lei1A4vAutdFDl4oGePm9ElKJFgJ
KYTHoeqrKgVmgOFWKQKpEruUPQA1DaVh5V6t9rS5Agru59GZK3y4E1YXFanLTBtaVc18ikN52Q==
-----END CERTIFICATE-----"
        
    next
end

config system saml
    set status enable
    set default-login-page normal
    set default-profile "super_admin"
    set entity-id "http://192.168.1.1:1234/metadata/"
    set idp-entity-id "https://sts.windows.net/b793f2e8-DDD-4e8d-9305-2e0c2178f9a1/"
    set idp-single-sign-on-url "https://login.microsoftonline.com/b793f2e8-DDD-4e8d-9305-2e0c2178f9a1/saml2"
    set idp-single-logout-url "https://login.microsoftonline.com/b793f2e8-DDD-4e8d-9305-2e0c2178f9a1/saml2"
    set idp-cert "EntraID-SSO-Admins"
    set server-address "192.168.1.1:1234"
end

Web/SSH ports, hostname/alias, LLDP (your snippet, kept modular)

config system global
  set admin-port 8080
  set admin-scp enable
  set admin-sport 4443
  set admintimeout 30
  set alias "FortiGate01"
  set hostname "FGT01"
  set lldp-reception enable
  set lldp-transmission enable
  set timezone 20
end

Limit where admins can log in from (your snippet, + idle timeout & strong crypto)

config system admin
  edit "admin"
    set trusthost1 10.10.10.0 255.255.255.0
    set accprofile "super_admin"
    set password XXXXXXXXXX
  next
  edit "backup_user"
    set trusthost1 10.10.10.10 255.255.255.255
    set accprofile "super_admin_readonly"
    set vdom "root"
    set password XXXXXXXXXX
  next
end

config system global
  set admin-console-timeout 10
  set strong-crypto enable
  set ssl-static-key-ciphers disable
  set dh-params 8192
end

API user with trust host

config system api-user
  edit "apiuser"
    set api-key XXXXXX
    set accprofile "API_Profile"
    set vdom "root"
    config trusthost
      edit 1
        set ipv4-trusthost 192.168.188.0 255.255.255.0
      next
    end
  next
end

DNS

Not harding, but use trusted DNS Sources for your firewall

config system dns
  set primary 1.1.1.1
  set secondary 8.8.8.8
  set protocol cleartext dot doh
  set server-hostname "globalsdns.fortinet.net"
  set domain "fgt1800.local"
end

NTP

Not harding, but use trusted NTO Sources for your firewall. It is important that the time is correct across all devices.

config system ntp
  set ntpsync enable
  set type custom
  set syncinterval 60
  config ntpserver
    edit 1
      set server "dk.pool.ntp.org"
      set ntpv3 disable
      set authentication disable
      set interface-select-method auto
    next
  end
  set source-ip 0.0.0.0
  set source-ip6 ::
  set server-mode enable
  set authentication disable
  set interface "internal1" "internal2"
end

High Availability

Fortinet recommends HA for resilience; ensure unique group-id per L2 domain.
In a Fortinet FortiGate high availability (HA) cluster, the HA group ID determines the virtual MAC addresses (VMACs) for the interfaces. By default, all interfaces in a cluster use a shared VMAC, but this can be changed by assigning a unique group ID to prevent MAC address conflicts, especially if multiple clusters are on the same network segment.

config system ha
  set group-id 0
  set group-name "clu01"
  set mode a-p
  set password XXXX
  set hbdev "ha1" 0
  set sync-config enable
  set gratuitous-arps enable
  set ha-mgmt-status enable
  config ha-mgmt-interfaces
    edit 1
      set interface "mgmt1"
      set dst 0.0.0.0 0.0.0.0
      set gateway 10.10.10.1
      set gateway6 ::
    next
  end
  set override enable
  set priority 150
  set monitor "ha1" "lacp_Inside" "lacp_outside"
  set ha-direct disable
end

Monitoring

Fortinet highlights SNMPv3/NetFlow/sFlow for baselining and monitoring.

config system snmp sysinfo
  set status enable
  set description "FGTclu01"
  set contact-info "Persons Name"
  set location "Datacenter - Cluster"
end

config system snmp community
  edit 1
    set name "Anchor4143"
    config hosts
      edit 1
        set ip 10.10.10.10 255.255.255.255
        set ha-direct enable
      next
      edit 2
        set ip 10.10.10.12 255.255.255.255
        set ha-direct enable
      next
      edit 3
        set ip 177.177.177.177 255.255.255.255
      next
    end
    set query-v1-status disable
    set trap-v1-status disable
    set events cpu-high mem-low log-full intf-ip vpn-tun-up vpn-tun-down ha-switch ha-hb-failure ips-signature ips-anomaly av-virus av-oversize ...
  next
end

config system snmp user
  edit "Roster5647"
    set notify-hosts 10.10.10.10
    set security-level auth-priv
    set auth-proto sha512
    set auth-pwd xxxx
    set priv-proto aes256
    set priv-pwd xxxx
  next
end

Logging

Fortinet: encrypt to FortiAnalyzer by default; secure channel for third-party logging/VPN if needed. Remember to enable per-policy logging.

config log syslogd setting
  set status enable
  set server "10.10.10.10"
  set mode udp
  set port 514
  set facility local7
  set source-ip "10.10.10.1"
  set format cef
  set priority default
  set max-log-rate 0
  set interface-select-method auto
end

config log syslogd filter
  set severity information
  set forward-traffic enable
  set local-traffic enable
  set multicast-traffic enable
  set sniffer-traffic enable
  set ztna-traffic enable
  set anomaly enable
  set voip enable
end

config log eventfilter
  set event enable
  set system enable
  set vpn enable
  set user enable
  set router enable
  set wireless-activity enable
  set wan-opt enable
  set endpoint enable
  set ha enable
  set security-rating enable
  set fortiextender enable
  set connector enable
  set sdwan enable
  set cifs enable
  set switch-controller enable
end

# Repeat on all rules (example)
config firewall policy
  edit 1
    set logtraffic all
  next
end

Local-In Policy Baseline (tight management & routing daemons)

Fortinet recommends restricting local services using local-in-policy and avoiding WAN admin.

Allow management only from defined subnets

# Define mgmt source(s)
config firewall address
  edit "Mgmt-Nets"
    set subnet 10.10.10.0 255.255.255.0
  next
end

# Allow HTTPS/SSH only from Mgmt-Nets to mgmt port(s)
config firewall local-in-policy
  edit 10
    set intf "mgmt1"
    set srcaddr "Mgmt-Nets"
    set dstaddr "all"
    set action accept
    set service "HTTPS" "SSH"
    set schedule "always"
    set status enable
  next
end

Deny OSPF/BGP on WAN by default; allow only explicit peers

# Explicit peers/routers if needed
config firewall address
  edit "ISP-BGP-Peer"
    set subnet 203.0.113.1 255.255.255.255
  next
  edit "Upstream-OSPF"
    set subnet 203.0.113.2 255.255.255.255
  next
end

# Allow only specific routing peers on WAN
config firewall local-in-policy
  edit 20
    set intf "wan1"
    set srcaddr "ISP-BGP-Peer"
    set dstaddr "all"
    set action accept
    set service "BGP"
  next
  edit 21
    set intf "wan1"
    set srcaddr "Upstream-OSPF"
    set dstaddr "all"
    set action accept
    set service "OSPF"
  next
  edit 29
    set intf "wan1"
    set action deny
    set service "BGP" "OSPF"
  next
end

Geo-block management/VPN access on WAN

Fortinet supports Geo objects in local-in-policy; this is commonly used to fence IKE/SSL admin reachability.

# Denmark + Greenland only
config firewall address
  edit "Geo-DK-GL"
    set type geography
    set country DN GL
  next
end

# Permit IKE/HTTPS/SSH only from DK/GL; default deny after
config firewall local-in-policy
  edit 40
    set intf "wan1"
    set srcaddr "Geo-DK-GL"
    set dstaddr "all"
    set action accept
    set service "IKE" "HTTPS" "SSH"
    set schedule "always"
  next
  edit 49
    set intf "wan1"
    set action deny
    set service "IKE" "HTTPS" "SSH"
  next
end

Loopback-Terminated VPN

Using a loopback for IKE/IPsec termination lets you apply local-in and Geo controls consistently and avoid changing peer configs when WAN links change. Ensure the loopback address is routable/advertised on the internet (e.g., via static/public route from ISP).

You can use NAT into the Loopback for the VPN usage also, if it is not possible to get a routed public ip to your firewall.

# 1) Create loopback for VPN endpoint
config system interface
  edit "loopback-vpn"
    set type loopback
    set ip 198.51.100.10 255.255.255.255   # public /32 routed to you
  next
end

# 2) Bind IPsec Phase1 to loopback
config vpn ipsec phase1-interface
  edit "siteA-vpn"
    set interface "loopback-vpn"
    set peertype any
    set proposal aes256-sha256
    set dhgrp 21
    set npu-offload enable
  next
end

# 3) Local-in policy to fence IKE to loopback via WAN
config firewall local-in-policy
  edit 60
    set intf "wan1"
    set srcaddr "Geo-DK-GL"      # or use specific peers
    set dstaddr "all"
    set action accept
    set service "IKE"
  next
  edit 69
    set intf "wan1"
    set action deny
    set service "IKE"
  next
end

# 4) Route return traffic (ensure ISP routes 198.51.100.10 to your WAN)
config router static
  edit 1
    set dst 0.0.0.0 0.0.0.0
    set gateway 203.0.113.254
    set device "wan1"
  next
end

DoS protection for mgmt/VPN on WAN

Fortinet recommends enabling DoS policies to drop floods before heavier processing.

config firewall DoS-policy
  edit 100
    set interface "wan1"
    config anomalies
      edit "tcp_syn_flood"
        set status enable
        set log enable
        set action block
      next
      edit "ike"
        set status enable
        set log enable
        set action block
      next
      edit "https_flood"
        set status enable
        set log enable
        set action block
      next
    end
  next
end

Close “override” ports used by replacement messages (optional hardening)

If you run WebFilter/UTM and fail PCI scans due to 8008/8010/8015/8020 being probed, close them.

config webfilter fortiguard
  set close-ports enable
end

# Or keep features but move to high ephemeral
config webfilter fortiguard
  set ovrd-auth-port-http 38008
  set ovrd-auth-port-https 38010
  set ovrd-auth-port-https-flow 38015
  set ovrd-auth-port-warning 38020
end

# Disable app replacement message (closes 8008 for AppCtrl)
config application list
  edit "default"
    set app-replacemsg disable
  next
end

Secure password storage + encrypted backups

Fortinet recommends enabling private-data encryption and encrypting backups; 7.6.1+ uses generated keys—mind RMA/restore implications.

# Pre-7.6.1 (manual key) — read the doc before enabling in prod
config system global
  set private-data-encryption enable
end
# Then follow prompts for 32-hex key at the console.

# Encrypted backup
execute backup config flash encrypted fgt.conf "<StrongPassphrase>"

Firmware hygiene, PSIRT, strong cipher posture

Keep current patch, review PSIRT advisories, use strong crypto (already set above), and avoid WAN admin.

# Auto-patch minor updates (standalone devices) – review in change control first
config system autoupdate schedule
  set status enable
  set day monday
  set time 03:30
end

Policy hygiene (least privilege)

Fortinet stresses specific interfaces/objects, top-down specificity, avoid any-any, and VIP priority/match-vip behavior in deny rules.

# Example: deny first with match-vip, then allow
config firewall policy
  edit 10
    set name "Deny-from-HostX-to-VIP"
    set srcintf "wan1"
    set dstintf "dmz"
    set srcaddr "HostX"
    set dstaddr "WebVIP"
    set action deny
    set match-vip enable
    set logtraffic all
  next
  edit 20
    set name "Internet-to-WebVIP"
    set srcintf "wan1"
    set dstintf "dmz"
    set srcaddr "all"
    set dstaddr "WebVIP"
    set action accept
    set schedule "always"
    set service "HTTPS"
    set logtraffic all
  next
end

Summary of what you gain

  • Admin/API exposure reduced to known sources and geographies; WAN daemons fenced by default.
  • Consistent mgmt/VPN reachability even when WAN changes (loopback model) where public routing permits.
  • Lower attack surface (closed override ports, DoS filters, strong crypto).
  • Auditable operations (policy logging, SNMPv3, time sync).
  • Safer backups and predictable HA behavior.