diff --git a/Fortinet/FortiGate/Configuration Parsers/fortios.json b/Fortinet/FortiGate/Configuration Parsers/fortios.json new file mode 100644 index 0000000..1769fe6 --- /dev/null +++ b/Fortinet/FortiGate/Configuration Parsers/fortios.json @@ -0,0 +1,33 @@ +{ + "id": "6a7cd447bcc938f9b48e6728", + "name": "fortios", + "template": "cisco-ios", + "lexRules": [ + [ + "(\\r\\n|\\r|\\n)", + "end_line" + ], + [ + "$", + "end_line" + ], + [ + "#[^\\r\\n]*", + "comment" + ], + [ + "\"(?:[^\\\\\"\\r\\n]|\\\\.)*\"", + "word" + ], + [ + "\\S+", + "word" + ] + ], + "updated": "2026-08-12T20:15:03.160Z", + "created": "2026-08-12T20:15:03.160Z", + "gbac": { + "read": [], + "write": [] + } +} diff --git a/Fortinet/FortiGate/Golden Configurations/FortiGate - Simple.json b/Fortinet/FortiGate/Golden Configurations/FortiGate - Simple.json new file mode 100644 index 0000000..ec7ffe9 --- /dev/null +++ b/Fortinet/FortiGate/Golden Configurations/FortiGate - Simple.json @@ -0,0 +1,705 @@ +{ + "data": [ + { + "_id": "6a7ce68cbcc938f9b48e6738", + "name": "FortiGate - Simple", + "description": "", + "treeId": "6a7ce68cbcc938f9b48e6737", + "version": "initial", + "deviceType": "fortios", + "root": { + "name": "base", + "attributes": { + "devices": [], + "deviceGroups": [], + "remediationWorkflow": null, + "configId": "6a7ce68cbcc938f9b48e6736", + "export": { + "_id": "6a7ce68cbcc938f9b48e6736", + "deviceType": "fortios", + "lines": [ + { + "id": "6a7ce6a1ed9dd51d", + "words": [ + { + "type": "literal", + "value": "config" + }, + { + "type": "literal", + "value": "system" + }, + { + "type": "literal", + "value": "global" + } + ], + "lines": [ + { + "id": "6a7ce6a14da3e171", + "words": [ + { + "type": "literal", + "value": "set" + }, + { + "type": "literal", + "value": "hostname" + }, + { + "type": "literal", + "value": "\"FGT-EDGE-01\"" + } + ], + "lines": [], + "evalMode": "required", + "fixMode": "manual", + "severity": "info", + "ordering": "none", + "membership": "default" + }, + { + "id": "6a7ce6a1e53d9c07", + "words": [ + { + "type": "literal", + "value": "set" + }, + { + "type": "literal", + "value": "admintimeout" + }, + { + "type": "literal", + "value": "5" + } + ], + "lines": [], + "evalMode": "required", + "fixMode": "manual", + "severity": "error", + "ordering": "none", + "membership": "default" + }, + { + "id": "6a7ce6a14048d8d2", + "words": [ + { + "type": "literal", + "value": "set" + }, + { + "type": "literal", + "value": "admin-https-redirect" + }, + { + "type": "literal", + "value": "disable" + } + ], + "lines": [], + "evalMode": "disallowed", + "fixMode": "manual", + "severity": "error", + "ordering": "none", + "membership": "default" + } + ], + "evalMode": "required", + "fixMode": "manual", + "severity": "error", + "ordering": "none", + "membership": "default" + }, + { + "id": "6a7ce6a16350efaa", + "words": [ + { + "type": "literal", + "value": "end" + } + ], + "lines": [], + "evalMode": "ignored", + "fixMode": "manual", + "severity": "warning", + "ordering": "none", + "membership": "default" + }, + { + "id": "6a7ce6a134217275", + "words": [ + { + "type": "literal", + "value": "config" + }, + { + "type": "literal", + "value": "system" + }, + { + "type": "literal", + "value": "password-policy" + } + ], + "lines": [ + { + "id": "6a7ce6a1ea74af82", + "words": [ + { + "type": "literal", + "value": "set" + }, + { + "type": "literal", + "value": "status" + }, + { + "type": "literal", + "value": "enable" + } + ], + "lines": [], + "evalMode": "required", + "fixMode": "manual", + "severity": "error", + "ordering": "none", + "membership": "default" + }, + { + "id": "6a7ce6a158433a18", + "words": [ + { + "type": "literal", + "value": "set" + }, + { + "type": "literal", + "value": "min-length" + }, + { + "type": "literal", + "value": "12" + } + ], + "lines": [], + "evalMode": "required", + "fixMode": "manual", + "severity": "error", + "ordering": "none", + "membership": "default" + } + ], + "evalMode": "required", + "fixMode": "manual", + "severity": "error", + "ordering": "none", + "membership": "default" + }, + { + "id": "6a7ce6a114952535", + "words": [ + { + "type": "literal", + "value": "end" + } + ], + "lines": [], + "evalMode": "ignored", + "fixMode": "manual", + "severity": "warning", + "ordering": "none", + "membership": "default" + }, + { + "id": "6a7ce6a18c8b8826", + "words": [ + { + "type": "literal", + "value": "config" + }, + { + "type": "literal", + "value": "system" + }, + { + "type": "literal", + "value": "ntp" + } + ], + "lines": [ + { + "id": "6a7ce6a17de3ed96", + "words": [ + { + "type": "literal", + "value": "set" + }, + { + "type": "literal", + "value": "ntpsync" + }, + { + "type": "literal", + "value": "enable" + } + ], + "lines": [], + "evalMode": "required", + "fixMode": "manual", + "severity": "error", + "ordering": "none", + "membership": "default" + }, + { + "id": "6a7ce6a174102c4a", + "words": [ + { + "type": "literal", + "value": "config" + }, + { + "type": "literal", + "value": "ntpserver" + } + ], + "lines": [ + { + "id": "6a7ce6a109c8f10b", + "words": [ + { + "type": "literal", + "value": "edit" + }, + { + "type": "literal", + "value": "1" + } + ], + "lines": [ + { + "id": "6a7ce6a12374c915", + "words": [ + { + "type": "literal", + "value": "set" + }, + { + "type": "literal", + "value": "server" + }, + { + "type": "literal", + "value": "\"ntp.itential.io\"" + } + ], + "lines": [], + "evalMode": "required", + "fixMode": "manual", + "severity": "error", + "ordering": "none", + "membership": "default" + } + ], + "evalMode": "ignored", + "fixMode": "manual", + "severity": "warning", + "ordering": "none", + "membership": "default" + }, + { + "id": "6a7ce6a1e13d0e2a", + "words": [ + { + "type": "literal", + "value": "next" + } + ], + "lines": [], + "evalMode": "ignored", + "fixMode": "manual", + "severity": "warning", + "ordering": "none", + "membership": "default" + } + ], + "evalMode": "ignored", + "fixMode": "manual", + "severity": "warning", + "ordering": "none", + "membership": "default" + }, + { + "id": "6a7ce6a11515ce32", + "words": [ + { + "type": "literal", + "value": "end" + } + ], + "lines": [], + "evalMode": "ignored", + "fixMode": "manual", + "severity": "warning", + "ordering": "none", + "membership": "default" + } + ], + "evalMode": "required", + "fixMode": "manual", + "severity": "error", + "ordering": "none", + "membership": "default" + }, + { + "id": "6a7ce6a155a83b62", + "words": [ + { + "type": "literal", + "value": "end" + } + ], + "lines": [], + "evalMode": "ignored", + "fixMode": "manual", + "severity": "warning", + "ordering": "none", + "membership": "default" + }, + { + "id": "6a7ce6a1678e8867", + "words": [ + { + "type": "literal", + "value": "config" + }, + { + "type": "literal", + "value": "log" + }, + { + "type": "literal", + "value": "syslogd" + }, + { + "type": "literal", + "value": "setting" + } + ], + "lines": [ + { + "id": "6a7ce6a1d19ded84", + "words": [ + { + "type": "literal", + "value": "set" + }, + { + "type": "literal", + "value": "status" + }, + { + "type": "literal", + "value": "enable" + } + ], + "lines": [], + "evalMode": "required", + "fixMode": "manual", + "severity": "error", + "ordering": "none", + "membership": "default" + }, + { + "id": "6a7ce6a12cd7b2ed", + "words": [ + { + "type": "literal", + "value": "set" + }, + { + "type": "literal", + "value": "server" + }, + { + "type": "literal", + "value": "\"10.10.10.50\"" + } + ], + "lines": [], + "evalMode": "required", + "fixMode": "manual", + "severity": "error", + "ordering": "none", + "membership": "default" + } + ], + "evalMode": "required", + "fixMode": "manual", + "severity": "error", + "ordering": "none", + "membership": "default" + }, + { + "id": "6a7ce6a1d7f35c48", + "words": [ + { + "type": "literal", + "value": "end" + } + ], + "lines": [], + "evalMode": "ignored", + "fixMode": "manual", + "severity": "warning", + "ordering": "none", + "membership": "default" + }, + { + "id": "6a7ce6a1ac88e634", + "words": [ + { + "type": "literal", + "value": "config" + }, + { + "type": "literal", + "value": "system" + }, + { + "type": "literal", + "value": "admin" + } + ], + "lines": [ + { + "id": "6a7ce6a1b839d21b", + "words": [ + { + "type": "literal", + "value": "edit" + }, + { + "type": "literal", + "value": "\"admin\"" + } + ], + "lines": [ + { + "id": "6a7ce6a14215d832", + "words": [ + { + "type": "literal", + "value": "set" + }, + { + "type": "literal", + "value": "trusthost1" + }, + { + "type": "literal", + "value": "0.0.0.0" + }, + { + "type": "literal", + "value": "0.0.0.0" + } + ], + "lines": [], + "evalMode": "disallowed", + "fixMode": "manual", + "severity": "error", + "ordering": "none", + "membership": "default" + } + ], + "evalMode": "ignored", + "fixMode": "manual", + "severity": "warning", + "ordering": "none", + "membership": "default" + }, + { + "id": "6a7ce6a10f9a1ba0", + "words": [ + { + "type": "literal", + "value": "next" + } + ], + "lines": [], + "evalMode": "ignored", + "fixMode": "manual", + "severity": "warning", + "ordering": "none", + "membership": "default" + } + ], + "evalMode": "required", + "fixMode": "manual", + "severity": "info", + "ordering": "none", + "membership": "default" + }, + { + "id": "6a7ce6a1666af567", + "words": [ + { + "type": "literal", + "value": "end" + } + ], + "lines": [], + "evalMode": "ignored", + "fixMode": "manual", + "severity": "warning", + "ordering": "none", + "membership": "default" + }, + { + "id": "6a7ce6a1ef964f35", + "words": [ + { + "type": "literal", + "value": "config" + }, + { + "type": "literal", + "value": "system" + }, + { + "type": "literal", + "value": "interface" + } + ], + "lines": [ + { + "id": "6a7ce6a1aabd64c7", + "words": [ + { + "type": "literal", + "value": "edit" + }, + { + "type": "literal", + "value": "\"port1\"" + } + ], + "lines": [ + { + "id": "6a7ce6a14da33b44", + "words": [ + { + "type": "literal", + "value": "set" + }, + { + "type": "literal", + "value": "allowaccess" + }, + { + "type": "literal", + "value": "telnet" + } + ], + "lines": [], + "evalMode": "disallowed", + "fixMode": "manual", + "severity": "error", + "ordering": "none", + "membership": "default" + }, + { + "id": "6a7ce6a1e9093477", + "words": [ + { + "type": "literal", + "value": "set" + }, + { + "type": "literal", + "value": "allowaccess" + }, + { + "type": "literal", + "value": "http" + } + ], + "lines": [], + "evalMode": "disallowed", + "fixMode": "manual", + "severity": "error", + "ordering": "none", + "membership": "default" + } + ], + "evalMode": "ignored", + "fixMode": "manual", + "severity": "warning", + "ordering": "none", + "membership": "default" + }, + { + "id": "6a7ce6a1c5d63ac6", + "words": [ + { + "type": "literal", + "value": "next" + } + ], + "lines": [], + "evalMode": "ignored", + "fixMode": "manual", + "severity": "warning", + "ordering": "none", + "membership": "default" + } + ], + "evalMode": "required", + "fixMode": "manual", + "severity": "info", + "ordering": "none", + "membership": "default" + }, + { + "id": "6a7ce6a1a28c5d19", + "words": [ + { + "type": "literal", + "value": "end" + } + ], + "lines": [], + "evalMode": "ignored", + "fixMode": "manual", + "severity": "warning", + "ordering": "none", + "membership": "default" + } + ], + "template": "config system global\n set hostname \"{{ hostname }}\"\n set admintimeout 5\n {d/}set admin-https-redirect disable\n{i/}end\nconfig system password-policy\n set status enable\n set min-length 12\n{i/}end\nconfig system ntp\n set ntpsync enable\n {i/}config ntpserver\n {i/}edit 1\n set server \"{{ ntp_server }}\"\n {i/}next\n {i/}end\n{i/}end\nconfig log syslogd setting\n set status enable\n set server \"{{ syslog_server }}\"\n{i/}end\nconfig system admin\n {i/}edit \"admin\"\n {d/}set trusthost1 0.0.0.0 0.0.0.0\n {i/}next\n{i/}end\nconfig system interface\n {i/}edit \"port1\"\n {d/}set allowaccess telnet\n {d/}set allowaccess http\n {i/}next\n{i/}end", + "created": "2026-08-12T21:33:00.449Z", + "createdBy": "6a74d2ec429a5ac0051834b8", + "lastUpdated": "2026-08-12T21:33:20.750Z", + "lastUpdatedBy": "6a74d2ec429a5ac0051834b8" + } + }, + "children": [] + }, + "created": "2026-08-12T21:33:00.449Z", + "createdBy": "6a74d2ec429a5ac0051834b8", + "lastUpdated": "2026-08-12T21:33:20.747Z", + "lastUpdatedBy": "6a74d2ec429a5ac0051834b8", + "gbac": { + "read": [], + "write": [] + }, + "variables": { + "hostname": "FGT-EDGE-01", + "ntp_server": "ntp.itential.io", + "syslog_server": "10.10.10.50" + }, + "tags": [] + } + ] +} diff --git a/Fortinet/FortiGate/README.md b/Fortinet/FortiGate/README.md index bc07bd6..fa05bed 100644 --- a/Fortinet/FortiGate/README.md +++ b/Fortinet/FortiGate/README.md @@ -15,12 +15,18 @@ This project provides two ways to automate against FortiGate: netmiko over SSH/C - [Choosing API vs SSH — and a Hybrid Setup](#choosing-api-vs-ssh--and-a-hybrid-setup) - [Device Drivers](#device-drivers) - [fortigate-rest](#fortigate-rest) +- [Configuration Parsers](#configuration-parsers) + - [fortios](#fortios) +- [Golden Configurations](#golden-configurations) + - [FortiGate - Simple](#fortigate---simple) ## Contents | Asset | Description | |---|---| | [device-drivers/fortigate-rest](./device-drivers/fortigate-rest/) | IG5 Python FortiOS REST driver — is-alive, get-config, plus a generic REST passthrough | +| [Configuration Parsers/fortios.json](./Configuration%20Parsers/fortios.json) | Config Manager parser defining the `fortios` device type | +| [Golden Configurations/FortiGate - Simple](./Golden%20Configurations/FortiGate%20-%20Simple.json) | Golden config tree covering admin access, password policy, NTP, syslog, and interface hardening — requires the `fortios` parser | ## Inventory Manager Configuration @@ -172,3 +178,42 @@ iagctl db import import.yaml --force or copy just the `services`/`decorators` blocks into your Itential Gateway's existing `import.yaml`. **Dependencies:** `requests>=2.28.0` + +## Configuration Parsers + +### fortios + +Defines the `fortios` device type in Config Manager. This parser must be imported +before the **FortiGate - Simple** golden configuration tree can be created or used. It +tokenizes FortiOS CLI configuration (`config` / `edit` / `set` / `next` / `end` blocks) +using the `cisco-ios` lexer template, treating each line as a sequence of words +delimited by whitespace, with quoted strings preserved as single tokens. It adds a `#` +comment rule on top of the base `cisco-ios` rules to correctly skip the `#`-prefixed +metadata header lines (`#config-version=...`, `#buildno=...`) that FortiOS always +emits at the top of a configuration export. + +Import via Config Manager → Configuration Parsers → Import. + +--- + +## Golden Configurations + +One golden configuration tree is provided. It ships with no device bindings — bind it +to your devices in Config Manager after importing. + +### FortiGate - Simple + +Device type: `fortios` + +Baseline configuration using literal matching. Covers admin session timeout, password +policy (status + minimum length), NTP sync to a named server, syslog forwarding, and a +handful of security-hardening checks: disallows disabling the HTTPS admin redirect, +disallows a wide-open `trusthost1 0.0.0.0 0.0.0.0` management ACL, and disallows +telnet/HTTP management access on `port1`. Use this as a starting point when all devices +in a group are expected to share identical configuration values with no variation. + +> **Before importing:** The `fortios` parser must be registered in Config Manager first +> (see Configuration Parsers above). Then bind the root node's `devices` to match your +> Inventory Manager device name(s). + +**Dependencies:** `fortios` parser