tools for FortiOS

From time to time I will add useful batch command files or scripts that deal with certain aspects of FortiOS, the operating system of FORTINET’s firewalls.

Copy-Left: feel free to use the scripts in your work as a firewall admin – as long as you retain the copyright notice to me and this website.


Speeding up IPsec VPN recovery – using blackhole routes

Use case: you use IPsec VPNs in interface mode. A route points to the remote network to allow traffic to traverse the VPN tunnel.
Now imagine the tunnel breaks down. FortiOS will remove the route as the interface status changes to „down“. At this moment, the default route takes over, and traffic from an internal subnet is directed towards the internet.

As a consequence, a session is established, private traffic reaches your ISP’s router and is discarded there. There is a common understanding that traffic from private networks (RFC 1918) like 192.168.x.y, 172.16.x.y or 10.x.x.x, is not routed on the internet.

Nonetheless, what will happen when the tunnel is re-established?
The tunnel will be up, but no traffic will traverse it. That is because there already is a valid session to the WAN interface. It will take some time until that session is timed out, and a new session is established across the tunnel.

If you prevent the WAN session to be set up in the beginning, there wouldn’t be any delay after a tunnel crash.

You can configure that by using a DENY policy, from each internal subnet/interface to the WAN interface, or by using blackhole routes. A blackhole route, if followed, will discard all traffic. Most important, there won’t be any session to the internet. You would assign the least attractive metric to a bh route, that is, 254, so it will only be used if no other valid route exists.

You can download a FortiOS script here. Import it, and you will never have to worry about tunnel build-up delays anymore.

↑ back to top

Using external blacklists

Use case: you have a list of IP addresses and want to import them into your Fortigate, and use them in a policy to block or allow traffic from or to these hosts (blacklist or whitelist).

Such a list can for instance be generated by hosts.deny.

The following script takes a text file with IP addresses and converts it to a FortiOS batch command file, ready to be imported as a ‚bulk command‘ (System > Advanced > Configuration Scripts; in FortiOS 6.4+, use the user menu in the upper right corner, then Configuration > Scripts).

To circumvent certain object size limits the script will

  • parse the input for IP addresses and add them to an internal list
  • for each IP address, create a FOS address object
  • for each nnn addresses, create a FOS address group
  • create one or more FOS ’super‘ address group(s) (group of groups)

As the script cannot read the ‚live‘ configuration from the FGT it will create a ‚purge‘ batchfile to delete the imported address objects before importing new addresses.

usage: iplist2forti.exe [-h] [-m {s,m,l}] [-n MAXADDR] [-p PREVADDR] [-d] [-D] [-o CMDFNAME] [-s SPLITCOUNT] infile
Create (a lot of) address objects and groups from list for use in FortiOS.

positional arguments:
 infile                read IPs from <infile>

optional arguments:
 -h, --help            show this help message and exit
 -m {s,m,l}, --model {s,m,l}
                       FortiGate model: small (<FGT-100) / medium (<FGT-1000)
                       / large
 -n MAXADDR, --newest MAXADDR
                       use only newest/last <maxAddr> addresses from list
                       replace <prevAddr> old addresses
 -d, --dontresolve     skip non-numeric addresses (FQDNs) in input
 -D, --debug           print debug output
 -o CMDFNAME, --outfile CMDFNAME
                       write output to <cmdfname>
                       split output into <splitcount> parts

Download: (remove the .txt extension) and a sample hosts.deny file.

expected output: -ms -d -o out.txt hosts.deny

reading file "hosts.deny"...
        invalid IP (value): 4.5.337.0
        invalid IP (value):

    4057 IPs in file
     104 IPs skipped
     104 FQDNs skipped
    3953 IPs in 40 address groups of size 100
      40 address groups in 1 super group
specific for small Fortigate model

now import bulk command file "out_2201041407.txt"
refer to address group "sblockgroup000" in DENY policy
to get rid of these addresses, import "out_purge_2201041407.txt"
↑ back to top

Block traffic by country – All Countries address group

Sometimes it’s useful to block traffic by geolocation. In FortiOS v5 and newer, an address can have the „set type geography“ setting to denote a dynamic object. It encompasses all IP addresses used by internet providers in a country. Of course, this is not 100% exact but it can help a lot to secure your traffic.

As assigned IP ranges change from time to time FortiGuard updates the internal list of address ranges for each country.

If you want to use this feature you create a new address object, preferably in the CLI, and add the type specifier:

config firewall address
   set type geography
   set country AQ

Unfortunately, there is no obvious relation between the country names you know and the country code FortiOS uses. There are 2 ways to cope with this:

  • you can type a ‚?‘ instead of a country code to get the current list of codes
  • you can use my ‚all countries‘ batch command files to create address objects for ALL countries at once

Additionally, an address group with all country address objects will be created.

The batch command file is available

and looks like this:

config firewall address
   edit geo_Reserved
      set type geography
      set country ZZ
   edit geo_Andorra
     set type geography
     set country AD
config firewall addrgrp
   edit all_countries
      set member geo_Reserved geo_Anonymous_Proxy geo_Satellite_Provider ...

An example how to use this new address group:

Say, you want to allow administrative access to your Fortigate from France only, assuming ‚wan1‘ is the interface facing the WAN.

You would create 2 new ‚local-in‘ policies for this (if you cannot see the menu item ‚Policy & Objects‘ > ‚Local In Policy‘, enable it in ‚System‘ > ‚Feature Visibility‘ > ‚Additional Features‘ > ‚Local In Policy‘ first):

config firewall local-in-policy
   edit 1
      set intf "wan1"
      set srcaddr "geo_France"
      set dstaddr "all"
      set action accept
      set service "ALL"
      set schedule "always"
   edit 2
      set intf "wan1"
      set srcaddr "all"
      set dstaddr "all"
      set action deny
      set service "ALL"
      set schedule "always"
↑ back to top

Bug warning (2018-08-17):

If you happen to find one day that you cannot see any address objects anymore, and you have geolocation addresses defined, it might be due to a bug in FortiOS v5.2 and v5.4.

Fortinet has removed the „Asia-Pacific“ and „Europe“ country codes. If your address group still contains one of these, the address object page in the WebGUI will not be accessible anymore.

Fix: edit the address group in the CLI („config firewall address group“) and delete these entries.

↑ back to top

import & export quarantine list

FortiOS provides an internal quarantine list of IP addresses which will be blocked from traffic. An address can be supplied from a UTM module (AV, IPS, DLP or DoS), or can be entered manually in the GUI.

To export the list of quarantined addresses, use

    diagnose user quarantine list

to see the number of items use

    diagnose user quarantine stat

You can even enter an address in CLI via

    diagnose user quarantine add src4|src6 a.b.c.d duration_in_seconds source

Here is a tool which reads the items‘ list from a file and creates an output file which can be imported as a script. This way, you can export the quarantine list on one Fortigate, and import it into another one.

Download: (remove the .txt extension)

↑ back to top