Fortigate STIG Hardning – NDM STIG V1R4

Introduction

Securing network infrastructure is critical for maintaining compliance and protecting sensitive data. This post provides a detailed overview of the Security Technical Implementation Guide (STIG) requirements for Fortinet FortiGate Firewalls, based on the Network Device Management (NDM) STIG Version 1, Release 4 (V1R4). These guidelines, published by the Defense Information Systems Agency (DISA), outline mandatory configurations and best practices to harden FortiGate devices against vulnerabilities and unauthorized access.
By following these STIG controls, organizations can ensure their FortiGate firewalls meet DoD security standards and align with industry best practices for network security.

Download Excel with all STIG for Fortigate –> HERE

STIG

This example is meant as a starting point. You’ll still need to adjust it for your environment, including:

  • Management network addresses, syslog/SNMP/NTP servers, CA names, and similar details.
  • Which admin profiles exist and who is assigned to them.
  • Whether you use FortiAnalyzer, syslog, or both.
  • Version-specific differences, since some commands vary slightly between FortiOS builds.

The goal is to show how the FortiGate-side controls map to what the checklist is actually enforcing.

Requirements that go beyond FortiGate configuration

Most controls in the STIG XML include a clear GUI or CLI configuration step. The one that cannot be enforced purely through configuration is:

FGFW-ND-000305 – Patch validation and provenance

  • Title: “The FortiGate device must only install patches or updates that are validated by the vendor via digital signature or hash.”
  • What this really means:
    • Admins must download FortiOS images and patches only from trusted Fortinet sources (FortiGuard or the official support portal).
    • The organization needs a process to verify signatures or hashes before installation (e.g., check SHA256 against Fortinet’s published value, verify certificates).
  • Why it’s not just config:
    • There’s no setting that forces “only signed images.” This is an operational practice tied to change management.

There are also hybrid requirements where configuration is necessary but not enough without supporting policies and processes. Examples include:

  1. FGFW-ND-000035 – Access limited to ISSM-designated roles
    • Config: Create admin profiles and map them to AAA groups (see RBAC section).
    • Non-config: ISSM must define which roles and groups are allowed and keep documentation current.
  2. FGFW-ND-000030 – Only one local account as a last resort
    • Config: Maintain exactly one local “break-glass” admin with a strong password; all others use remote authentication.
    • Non-config: Define who holds that password, when it can be used, and how often it must be changed.
  3. FGFW-ND-000250 – No default manufacturer passwords at deployment
    • Config: Change or disable the default admin account.
    • Non-config: Deployment SOPs must ensure no device enters production with defaults, and auditors can verify compliance.
  4. FGFW-ND-000285 – Access to config backups and removable media
    • Config: Restrict backup/restore functionality to a very limited admin profile (e.g., SECOPS-BACKUP).
    • Non-config: Define how backups are stored, who can access them, off-site handling, and encryption at rest.
  5. FGFW-ND-000290 – Protection against DoS/DDoS using organization-defined safeguards
    • Config: Apply local-in policies, rate limiting, IPS/DoS policies, and harden management interfaces.
    • Non-config: The organization must define thresholds, exposed services, acceptable risk, and monitoring procedures.
  6. Logging and auditing controls (FGFW-ND-000005 through FGFW-ND-000090)
    • Config: Enable event logging and forward logs to SIEM or FortiAnalyzer.
    • Non-config:
      • Ensure a SIEM or log-management platform exists and is maintained.
      • SOC procedures must define who reviews logs, how often, and what actions to take when alerts occur.

In practice:

  • The CLI block above gives you a strong baseline for device configuration under the FortiGate NDM STIG.
  • The hybrid and non-config items require formal processes, documentation, and operational controls—such as patch intake, ISSM role definitions, backup handling, and SOC procedures.

CLI Example

BASIC SYSTEM AND MANAGEMENT PLANE HARDENING

config system global
    set hostname "FGT-STIG-CORE"

    # Idle admin session timeout – 10 minutes (FGFW-ND-000270 / -000275)
    set admintimeout 10

    # Lock out after 3 bad attempts for 15 minutes (FGFW-ND-000045)
    set admin-lockout-threshold 3
    set admin-lockout-duration 900

    # Limit concurrent admin sessions (FGFW-ND-000300)
    set admin-concurrent disable
    set admin-login-max 3

    # Strong crypto for management (FGFW-ND-000255 / -000260 / -000265 / -000280)
    set admin-https-ssl-versions tlsv1-2 tlsv1-3
    set admin-https-pki-required enable
    set ssh-strong-crypto enable
    set ssh-cbc disable
    set ssh-hmac-sha2-256 enable
    set ssh-kex-sha256 enable

    # Enable FIPS mode where supported (requires reboot; model/OS dependent)
    set fips-mode enable

    # Enforce that management is only from trusted management networks
    set admin-restrict-local enable
endCode language: JavaScript (javascript)

LOGIN BANNERS – DoD NOTICE AND CONSENT (FGFW-ND-000050 / -000055)

config system global
    set pre-login-banner enable
end

config system replacemsg admin pre_admin-disclaimer-text
    set buffer "
You are accessing a Organization information system, which includes this network equipment. Unauthorized use is prohibited and may result in disciplinary action, civil and criminal penalties.
By continuing to use this system, you consent to the following:

Monitoring and Recording: All activities on this system are subject to monitoring, interception, recording, and auditing by authorized personnel for security and administrative purposes.
No Expectation of Privacy: You have no reasonable expectation of privacy regarding any communication or data transmitted or stored on this system.
Authorized Use Only: This system is for official use by authorized users only. Unauthorized access or use may result in criminal prosecution.

If you do not agree to these terms, disconnect immediately.
"
endCode language: JavaScript (javascript)

Or DOD Banner

https://prhome.defense.gov/Portals/52/Documents/MRA_Docs/MPP/OEPM/O6B%20Screen%20Shots%20Access%20DMDC%20DSS%20Ver%202%2026Oct2012.pdf?ver=2018-01-30-213607-083

https://ebs.dai.csd.disa.mil/OA_HTML/banner_appsLogin.jsp

ADMIN ACCOUNTS AND RBAC (FGFW-ND-000030 / -000035 / -000250 / -000285)

config system accprofile
    edit "SECOPS-READONLY"
        set secfa read
        set sysgrp read
        set netgrp read
        set loggrp read
        set fwgrp read
        set vpngrp read
        set utmgrp read
    next

    edit "SECOPS-OPERATOR"
        set secfa read-write
        set sysgrp read
        set netgrp read-write
        set loggrp read-write
        set fwgrp read-write
        set vpngrp read-write
        set utmgrp read
    next

    edit "SECOPS-SUPERADMIN"
        set secfa read-write
        set sysgrp read-write
        set netgrp read-write
        set loggrp read-write
        set fwgrp read-write
        set vpngrp read-write
        set utmgrp read-write
    next
end

# Local accounts – exactly one break-glass local account, others via AAA
config system admin
    # Remote admin tied to AAA; no local password (FGFW-ND-000030, -000035)
    edit "admin"
        set accprofile "SECOPS-SUPERADMIN"
        set remote-auth enable
        set trusthost1 10.10.10.0 255.255.255.0
        set trusthost2 192.168.100.0 255.255.255.0
    next

    # Single emergency local account with strong password (FGFW-ND-000030 / -000250)
    edit "breakglass"
        set accprofile "SECOPS-SUPERADMIN"
        set password ENC <STRONG_ENCRYPTED_PASSWORD>
        set trusthost1 10.10.10.0 255.255.255.0
    next
endCode language: JavaScript (javascript)

PASSWORD POLICY (FGFW-ND-000220 / -000225 / -000230 / -000235 / -000240 / -000311)

config system password-policy
    set apply-to admin

    # Minimum length 15 (FGFW-ND-000220)
    set minimum-length 15

    # Require complexity: upper, lower, number, special (FGFW-ND-000225..000240)
    set min-upper-case-letter 1
    set min-lower-case-letter 1
    set min-numeric-character 1
    set min-non-alphanumeric 1

    # History / change requirement (FGFW-ND-000311)
    set reuse-password disable
    set expire-days 60
    set enforce-history 5
    set must-change enable
endCode language: JavaScript (javascript)

AUTHENTICATION – RADIUS/LDAP OVER LDAPS/SAML (FGFW-ND-000035 / -000245 / -000255)

# Example LDAPS config
config user ldap
    edit "CORP-LDAP"
        set server "ldap01.corp.example.mil"
        set dn "DC=corp,DC=example,DC=mil"
        set type regular
        set username "CN=svc_fgt_ldap,OU=Service Accounts,DC=corp,DC=example,DC=mil"
        set password ENC <LDAPS_BIND_PASSWORD>
        set secure ldaps
        set port 636
        set ssl-min-proto-version TLSv1-2
        set ca-cert "DoD-Root-CA"
    next
end

# Map LDAP groups to admin profiles
config user group
    edit "SECOPS-ADMINS"
        set member "CORP-LDAP"
        config match
            edit 1
                set server-name "CORP-LDAP"
                set group-name "CN=SECOPS-ADMINS,OU=Groups,DC=corp,DC=example,DC=mil"
            next
        end
    next

    edit "SECOPS-READONLY"
        set member "CORP-LDAP"
        config match
            edit 1
                set server-name "CORP-LDAP"
                set group-name "CN=SECOPS-READONLY,OU=Groups,DC=corp,DC=example,DC=mil"
            next
        end
    next
end

# SAML EXAMPLE
config vpn certificate remote
    edit "EntraID-SSO-Admins"
        set remote "-----BEGIN CERTIFICATE-----
MIICMzCCAZygAwIBAgIJALiPnVsvq8dsMA0GCSqGSIb3DQEBBQUAMFMxCzAJBgNV
BAYTAlVTMQwwCgYDVQQIEwNmb28xDDAKBgNVBAcTA2ZvbzEMMAoGA1UEChMDZm9v
MQwwCgYDVQQLEwNmb28xDDAKBgNVBAMTA2ZvbzAeFw0xMzAzMTkxNTQwMTlaFw0x
ODAzMTgxNTQwMTlaMFMxCzAJBgNVBAYTAlVTMQwwCgYDVQQIEwNmb28xDDAKBgNV
BAcTA2ZvbzEMMAoGA1UEChMDZm9vMQwwCgYDVQQLEwNmb28xDDAKBgNVBAMTA2Zv
bzCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAzdGfxi9CNbMf1UUcvDQh7MYB
OveIHyc0E0KIbhjK5FkCBU4CiZrbfHagaW7ZEcN0tt3EvpbOMxxc/ZQU2WN/s/wP
xph0pSfsfFsTKM4RhTWD2v4fgk+xZiKd1p0+L4hTtpwnEw0uXRVd0ki6muwV5y/P
+5FHUeldq+pgTcgzuK8CAwEAAaMPMA0wCwYDVR0PBAQDAgLkMA0GCSqGSIb3DQEB
BQUAA4GBAJiDAAtY0mQQeuxWdzLRzXmjvdSuL9GoyT3BF/jSnpxz5/58dba8pWen
v3pj4P3w5DoOso0rzkZy2jEsEitlVM2mLSbQpMM+MUVQCQoiG6W9xuCFuxSrwPIS
pAqEAuV4DNoxQKKWmhVv+J0ptMWD25Pnpxeq5sXzghfJnslJlQND
-----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-4d6b-4e8d-9305-2e0c2178f9a1/"
    set idp-single-sign-on-url "https://login.microsoftonline.com/b793f2e8-4d6b-4e8d-9305-2e0c2178f9a1/saml2"
    set idp-single-logout-url "https://login.microsoftonline.com/b793f2e8-4d6b-4e8d-9305-2e0c2178f9a1/saml2"
    set idp-cert "EntraID-SSO-Admins"
    set server-address "192.168.1.1:1234"
end

config system admin
    edit "admin"
        set accprofile "SECOPS-SUPERADMIN"
        set trusthost1 10.10.10.0 255.255.255.0
        set remote-auth enable
        set user-group "SECOPS-ADMINS"
    next
endCode language: PHP (php)

NTP WITH AUTHENTICATION (FGFW-ND-000215)

config system ntp
    set ntpsync enable
    set type custom

    config ntpserver
        edit 1
            set server "ntp1.csd.example.mil"
            set ntpv3 enable
            set key-id 1
            set authentication enable
        next
        edit 2
            set server "ntp2.csd.example.mil"
            set ntpv3 enable
            set key-id 1
            set authentication enable
        next
    end

    # NTP symmetric keys (example – exact syntax depends on version)
    config key
        edit 1
            set key "NTP-Shared-Key-Here"
            set key-type sha1
        next
    end
endCode language: JavaScript (javascript)

INTERFACE AND MANAGEMENT ACCESS CONTROL (FGFW-ND-000035 / -000285 / -000290)

config system interface
    edit "mgmt"
        set vdom "root"
        set ip 10.10.10.1 255.255.255.0
        set allowaccess https ssh snmp
        set alias "OOB-MGMT"
        set role lan
    next
end

# Local-in policy to restrict who can talk to mgmt services
config firewall local-in-policy
    edit 1
        set intf "mgmt"
        set srcaddr "MGMT-NETS"
        set dstaddr "all"
        set service "HTTPS" "SSH" "SNMP"
        set action accept
        set schedule "always"
    next

    edit 2
        set intf "mgmt"
        set srcaddr "all"
        set dstaddr "all"
        set service "HTTPS" "SSH" "SNMP"
        set action deny
        set schedule "always"
        set log enable
    next
endCode language: JavaScript (javascript)

LOGGING AND AUDITING (FGFW-ND-000005 / -000010 / -000020 / -000040 / -000060 # -000065 / -000070 / -000075 / -000080 / -000085 / -000090 # -000295)

# Event logging of system, admin, and security events
config log eventfilter
    set event enable
    set system enable
    set endpoint enable
    set user enable
    set vpn enable
    set firewall enable
end

# Remote logging to SIEM / syslog collector (rather than local only)
config log syslogd setting
    set status enable
    set server "10.20.30.40"
    set mode reliable
    set port 514
    set facility local7
    set format default
    set ssl-min-proto-version TLSv1-2
end

# Optionally also log to FortiAnalyzer
config log fortianalyzer setting
    set status enable
    set server "faz01.csd.example.mil"
    set reliable enable
    set enc-algorithm high
endCode language: PHP (php)

SNMP FOR CENTRAL MONITORING (FGFW-ND-000295)

config system snmp community
    edit 1
        set name "SECOPS-MON"
        set status enable
        set events cpu-high mem-low log-full intf-ip vpn-tun-up vpn-tun-down ha-switch
        set hosts
            edit 1
                set ip 10.20.40.50
            next
        end
    next
end
Code language: JavaScript (javascript)

SESSION LIMITS, PROTECTION, AND DOS CONTROLS (FGFW-ND-000290 / -000300)

# Management DoS protection – restrict and rate-limit management services
config firewall vip
    # (Example, if mgmt is exposed through a VIP – often not needed on strict OOB)
end

# Example local-in shaping / DoS policy (syntax varies by version; concept only)
config firewall shaper per-ip-shaper
    edit "MGMT-HTTPS-SHAPER"
        set max-connections 50
    next
end

config firewall local-in-policy
    edit 3
        set intf "mgmt"
        set srcaddr "all"
        set dstaddr "all"
        set service "HTTPS"
        set action accept
        set schedule "always"
        set per-ip-shaper "MGMT-HTTPS-SHAPER"
        set log enable
    next
end
Code language: PHP (php)

BACKUP / EXPORT ACCESS CONTROL (FGFW-ND-000285)

# Ensure only a limited role can perform backup/restore
config system accprofile
    edit "SECOPS-BACKUP"
        set sysgrp read
        set loggrp read
        set mntgrp read-write      # only this profile can backup/restore
        set fwgrp none
        set netgrp none
    next
endCode language: PHP (php)

Assign SECOPS-BACKUP only to the dedicated backup service account (via AAA)

Example – mapping omitted here; concept is that only that profile can export configs.