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.
contents
- Speeding up IPsec VPN recovery – using blackhole routes
- Using external blacklists
- Block traffic by country – All Countries address group
- important bug in FortiOS 5.x
- import & export quarantine list
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
-p PREVADDR, --prev PREVADDR
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>
-s SPLITCOUNT, --split SPLITCOUNT
split output into <splitcount> parts
Download:
iplist2forti.py (remove the .txt extension) and a sample hosts.deny file.
expected output:
iplist2forti.py -ms -d -o out.txt hosts.deny
reading file "hosts.deny"...
invalid IP (value): 4.5.337.0
invalid IP (value): 221.011.70.255
processing...
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
end
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
- in English (all_countries.bcmd) and
- in German/auf Deutsch 🙂 (alle_Laender.bcmd)
and looks like this:
config firewall address
edit geo_Reserved
set type geography
set country ZZ
next
...
edit geo_Andorra
set type geography
set country AD
next
...
end
config firewall addrgrp
edit all_countries
set member geo_Reserved geo_Anonymous_Proxy geo_Satellite_Provider ...
next
end
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"
next
edit 2
set intf "wan1"
set srcaddr "all"
set dstaddr "all"
set action deny
set service "ALL"
set schedule "always"
next
end
↑ 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:
import_quar.py (remove the .txt extension)