fortigate web filtering
fortigate web filtering
Need to Know
Table of Contents
Important facts to know . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Static URL Filter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
FortiGuard Category based Web filtering . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
Category cache verification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
Action - Authenticate . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
Allow User Override . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
Usage Quota. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
Custom/local Categories and Web rating Override . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
Remote Category filter for external threat feed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
Search Engines Safe Search and Vimeo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
Rate by both IP Address and Domain . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
Block Invalid URLs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
Content Web Filtering . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
Proxy Options . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
Video Filter (not part of Web Filtering). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
Debug and Verification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36
• SSL Profile - either Certificate-only or Deep SSL Inspection, tells Fortigate whether to decrypt
completely SSL communication or look just at domain names in the SSL Certificates. The no-
inspection profile disables SSL inspection altogether, meaning any HTTPS websites will not be
scanned.
• FortiGuard Web Filtering service - enables us to filter web sites/URLs by Category, instead of
static URLs. You need Web Filter license for that.
• Static URL Filter - checks URL of the web site a user tries to enter, can be used together with
Fortiguard Web Filtering.
• Web Content Filtering - looks inside the Contents of a web page to find predefined by us
"banned" words and makes decision based on their existence and their count on the page.
Order of processing:
1
1. Static URL Filter
4. Advanced options filter - proxy mode only (ActiveX, Java Applets etc.)
5. AntiVirus Scanning
Work Flow - Fine tune SSL Profile if built-ins are not enough, create webfilter profile in Security
Profiles, fine tune it, apply to Security rule, together with SSL profile and enable UTM in such rule.
Web Filter-related databases on Fortigate are not updated by default, only after you
NOTE
create 1st Web Filter Profile and use it in the security rule, will Fortigate update dbs.
The actions:
• Block - block connection, no other processing (by AV/IPS signatures/etc.) is done. User sees
custom or default block page that access was blocked by the policy.
• Exempt - allow connection AND stop any further security checks like AV/AppControl/IPS. This
will exempt the connection even from Category based URL filtering. We can decide what exact
further checks to exempt, see below.
• Monitor - monitor (and log if logs are enabled in the security rule) but do NOT block the
connection.
In Static URL filter, we match domain/URL by either Simple, Wildcard, or Regex expressions.
Simple is what it says - matches exactly what you put in it. It is the least flexible but also least
resource-intensive for the Fortigate. Also, its matching depends on the inspection mode - Proxy or
Flow. In proxy the match is exact - e.g. if we set as Simple "yurisk.com" , it will match just
yurisk.com, but not anything else, like any subdomain - www.yurisk.com, test.yurisk.com will NOT
be matched. In the Flow mode, it may also do partial matching, including sub-domains.
We may indicate the protocol as well - HTTP or HTTPS, but Fortigate will remove it anyway.
The whole URLs can be matched as well - if I want to block only say a specific page
https://yurisk.info/2020/05/20/fortigate-bgp-cookbook-of-example-configuration-and-debug/ but
allow anything else in yurisk.info, this will work too:
• CLI configuration: create static URL list, then reference it by its table number in the webfilter
profile:
3
set url "yurisk.com"
set action block
next
edit 3
set url "yurisk.info/2020/05/20/
fortigate-bgp-cookbook-of-example-configuration-and-debug/"
set action block
next
end
next
end
① Number 1 is a reference to the URL filter table entry, this way (and only in CLI) we can reference
the same URLs table in different web filtering profiles, so not to re-create the same table of URLs
for each new profile.
Wildcard match - does what the names says, we can replace any part of the domain/URL with * .
When using it in the form of *.example.com, this will match all subdomains of the example.com as
well as the root domain example.com itself. Some examples: *facebook.com, forti*.com
Regex matching - Fortinet uses PCRE standard regex syntax. Few notes:
• You do not have to escape dot "." used to separate domain name parts, e.g. www.example.com is
OK, but "proper" www\.example\.com would work too.
• By default, the regex is NOT case-sensitive, but if for some strange reason you need it to be - add
after the regex "i" option, e.g. /EXAMPLE.COM/i and it will only match EXAMPLE.COM, not
example.com.
• We can use "^" to anchor the regex to the beginning of an domain/URL string.
• When entering regex on CLI, escape any special symbol twice, see below
5
next
edit 7
set url "sky\\.com"
set type regex
set action block
next
end
end
Exempt - this action allows the stated URL and skips any or specific further processing. The option
to specify what further checks to skip is available on CLI only. E.g. here I exempt "espn.com" only
from FortiGuard checks, but not from AV or other checks if they are set via Security Profiles in the
security rule. As I have the category "Sports" inside Fortigaurd Category filtering set to action
Authenticate, this exempt will disable Authentication when entering "espn.com" (and any URL
path), but will leave Authentication enabled for any other website in the Sports category, including
say espn.co.uk.
CLI config:
Prerequisites:
• Being able to connect to FortiGuard servers, again start with dia debug rating to verify.
• As an option, Fortimanager that does have access to Fortiguard can be configured as FDS to be
used by Fortigates.
• You have to use SSL inspection Profile in security rule. When using Certitificate-only profile, the
Fortigate will only be able to check domain name of the website, not page contents, nor the full
path in URL (part after the 1st slash in URL). For maximum efficiency, the Deep SSL Inspection
SSL profile should be used (but beware of browser error on MiTM - have to 1st install the
Fortigate CA certificate on all end stations).
• Watch out for SSL Exemption list inside the SSL Inspection Profile - categories/domains/IP
addresses listed there will NOT be inspected if they use SSL (most of the websites) and thus
features like Usage Quota/Warning/etc. will work but in a bit different way. See Usage Quota.
7
To see category of a domain, you either check Fortiguard site
https://www.fortiguard.com/webfilter or can go to Security Profiles → Web Rating
TIP
Overrides → Select Create New → URL put the domain in question and click "Lookup
Rating"
Configuring it is simple - just enable it in Web Filter Profile as Category Based Filter, choose
Categories and their Action and use this Web Filter in security rule(s) with UTM enabled.
Actions:
• Block - conneciton to the web site is blocked, no further security processing is done, the verdict
is final.
• Allow - allow connection from Web Filtering point of view, the connection will still be checked
by other security profiles/features if available - IPS/AppControl, etc and thus may be blocked
later.
• Monitor - monitor (and log if logs are enabled in the security rule) but do NOT block the
connection. Mostly useful to get detailed info on web sites users are visiting.
• Authenticate - access will be granted after the end user successfully authenticates to Fortigate.
• Warning - users will see a web page warning them that they are entering restricted domains,
and if the user clicks on "Proceed" she will be redirected to the original web site.
Categories order of precedence: Local Category > Remote Category > Fortiguard Category.
Cache Contents:
-=-=-=-=-=-=-=-
Cache Mode: TTL
Cache DB Ver: 234.25972
The 1st number is the category in hex. After we translate it to decimal, we can compare with the
built-in categories of the Fortigate get webfilter categories | grep n:
As we can see, most of the IP addresses do not get their rating at all, except the well-known Google
DNS, that is because I have option "Rate URLs by domain and IP Address" disabled.
Action - Authenticate
Here we are not blocking or allowing access to a Category immediately, but require additional
authentication from the user to proceed and view the web site. Users can be local or remote (e.g.
RADIUS/LDAP, but no FSSO/SAML meantime). Once we have user/group, we can set them in the Web
Filter → Category → Authenticate. Each time user tries to access such category, she will be asked to
enter user/pass, and will be allowed access for the Warning period of time (default = 5 minutes),
after which the access again is blocked until the user again authenticates.
NOTE FortiOS up to 7.4.4 require proxy-mode policy for this feature to work.
GUI Config:
9
• Enable Category filtering, find the needed Category (here Sport), and click on Action =
Authenticate.
• On trying to enter the website belonging to the restricted Category, the user will see:
And after entering the user/pass combo correctly, the user will be redirected to the original website,
here espn.com.
11
On CLI the log :
• CLI configuration
E.g. I create a new Web Filter profile that allows more categories than the main Web Filter,
including Social Networks and News & Media named "OverrideAllowAll" (not shown here).
Then I create the main Web Filter called "WebProfile", which lists that "OverrideAllowAll" profile as
a replacement after the user successfully authenticates, and in which ("WebProfile") I block Social
Networks and News & Media:
13
In the section below, I set the user group to authenticate against (can be local and can be remote -
LDAP/RADIUS) and replacement Web Filter profile for such authenticated users:
Also, note that I set override duration to 5 mins, which means after 5 minutes user will be again
blocked from accessing the site with option to authenticate again.
Page with the option to override the Web Filter profile that blocks access as seen by end user:
Pay attention to the port used by Fortigate to authenticate end user, make sure it is open:
The ports used by Fortigate for this and other features are listed here, and can be set to anything
15
you want: config webfilter fortiguard
As categories are all appear as numbers, it is easier to configure in GUI, but for completeness sake,
here is the complete Web Filter profile:
17
next
edit 32
set category 59
next
edit 33
set category 62
next
edit 34
set category 6
next
edit 46
set category 46
set action authenticate
set warn-duration 2h2m
set auth-usr-grp "webauthgrp"
next
edit 37
set category 37
set action block
next
edit 38
set category 30
set action block
next
edit 39
set category 36
set action block
next
end
end
next
end
Pay attention - we can NOT specify which category to override - ALL blocked categories are
overriden by new Web Filter profile "OverrideAllowAll" and will be blocked/allowed according to
the new profile.
Verification and debug - I didn’t find yet much info on this, except that we can clear all
overrides/warning periods and thus force users to authenticate again with dia test app ovrd 6:
For debug dia deb app urlfilter 250 will give A LOT of output, beware. And dia deb app urlfilter
-1 will given even more .
Usage Quota
When a Category has action set to one of Warning, Authenticate, or Monitor, we can limit how
much bandwidth or time the end user can consume from such a category. After a user uses up her
quota (for this day) she will be blocked from the websites in such category. The usage counters reset
automatically each midnight. The quota is calculated per user, and for the whole category - i.e. if a
user used up Sport Category by browsing espn.com, she will be blocked for any other website which
is also in this category.
The end user will see such message of using up her quota:
19
In logs we will see UTM block once the quota is reached (here user blocked after using up 10 Mbytes
on espn.com - Sports Category):
• How do I know if a website is SSL exempted? 2 ways - in the browser check the SSL/TLS
certificate of the website - if it is the original certificate of the website - it is exempted, but if it is
a Fortigate CA certificate - then it is not (given SSL Deep Inspection is used). The other way is in
Fortigate logs - the action for such website will be "passthrough":
21
Check SSL Exemption list in Security Profiles → SSL/SSH Inspection:
• CLI config
edit 31
set category 31
next
edit 46
set category 46
set action authenticate
set warn-duration 2h2m
set auth-usr-grp "webauthgrp"
end
config quota
edit 1
set category 46 <-- SPORTS CATEGORY
set type traffic
set value 10 <-- 10 MBYTES
next
edit 2
set category 31 <-- FINANCE CATEGORY
next
end
end
next
end
E.g. I will re-assign www.tripadvisor.com from Travel to the Local custom1 category and then will
set the Action to Block on it, while leaving action for the Travel category Allow.
Assign the website to the Local custom1 category in Security Profiles → Web Rating Overrides:
23
Change the Action to Block in the actual Web Filterfor custom1:
Now, even though "Travel" category is allowed, the specific website is being blocked on "custom1"
category:
CLI configuration:
First, we create a text file with URLs and host it on external web server. The file will look like:
urls.txt
https://yurisk.info/2025/02/26/fortigate-dlp-file-filtering-and-more-examples/
*.sky.com
cnn.com
1st is a complete URL, 2nd is a wildcard (no regex is supported) that will also block sky.com, and 3rd
is an exact match.
25
NOTE Do NOT, by mistake, chose Domain Name as this is for DNS FIlter, not Web Filter.
In which we set URL to access the external feed, optional authentication and refresh rate of data
from remote server (default 5 mins):
27
Now, the category "Remote" will appear in all existing and future Web Filter Profiles (by defult in
status Disabled) with the external feed we just configured, make sure to change the Action to
Block/Monitor/etc.:
Also, the FGT blocks access to the full path URL but not to the whole website (yurisk.info):
Again, it is possible because I have Deep SSL Inspection in Web Profile, otherwise FGT would not be
able to see beyong 1st slash after .info in https://yurisk.info/
This Remote feed will also be available in SSL Profile for Exemption if we need to:
29
Search Engines Safe Search and Vimeo
Not much to configure here - just enable or not the option to redirect end users to the Safe Search
page of the listed Search Engines. The "safety" of the search is enforced by the search providers
themselves, not by the Fortigate. The config is done under Static URL section (proxy-mode only
feature):
CLI:
config web
set bword-threshold 20
set bword-table 1
set safe-search url header <-- SAFE SEARCH CONFIG STARTS HERE
set youtube-restrict strict
set log-search enable
end
end
config web
set bword-threshold 20
set bword-table 1
set safe-search url header
set youtube-restrict strict
set log-search enable
end
(web) $ get
bword-threshold : 20
bword-table : 1 <-- CONTENT BLOCK TABLE
urlfilter-table : 0 <-- STATIC URL FILTER TABLE
content-header-list : 0
blocklist : disable <-- USE URL LIST RECEIVED FROM FSA TO BLOCK
allowlist :
safe-search : url header
youtube-restrict : strict
vimeo-restrict : <-- VIMEO
log-search : enable
keyword-match :
31
of each returned category - the one having higher weight will be used. I haven’t seen many admins
using this option.
The Security Policy where such web filter is used, has to be in Proxy mode, not
NOTE
Flow.
Obviously, the Deep SSL Inspection profile has to be used for it to be anything effective.
Web Filter Content, complete - blocks 2 keywords "cisco/Cisco" and "palo*alto" (wildcard)
edit "[Cc]isco" ①
set pattern-type regexp
set status enable
next
end
next
end
① Wildcards are case-sensitive so just listing "cisco" would only block pages with exact word
"cisco", not "Cisco" nor "CISCO". I added regex as pattern to account for "cisco" and "Cisco".
(palo*alto) $ get
name : palo*alto
pattern-type : wildcard
status : enable
lang : western
score : 10
action : block
Scoring:
• Each separte keyword entry is counted only once on the page. In the example above, there may
be 10 words "palo alto" on the same page, but Web Filter will only count 1 word/phrase worth
score of 10 points.
• The default score for each keyword entry is 10. By "each keyword entry" I mean in the keywords
list above - e.g. I have 2 keywords for Cisco, one matches "Cisco", 2nd "cisco" - if on the same
page there both "Cisco" and "cisco", it will count as 2 words found, each adding 10 points to
score, making it 20 for the page.
• The default score for the page to be blocked is 10, and the default score for each individual
keyword entry being also 10 means, by default, any single word from the keywords will cause
blocking of the page.
• We can change both bword-threshold and score so that only when multiple keywords appear on
the page, the page will be blocked. E.g. if we set ban-word-threshold to 20, then only pages with
2 keywords (each worth 10 points) in them will be blocked.
• When using regex they seem to count as a single appearance any number of matches. E.g. if I
remove from the above keywords list the wildcard "cisco" and leave only regex "[Cc]isco" then
page with "Cisco" and "cisco" will count just 1 appearance of this keyword, not 2.
• To force FGT to look for the whole phrases only, enclose them in double quotes.
33
Now only the page that has multiple different banned words AND when they add up to 20, will it be
blocked.
Log on the CLI can be seen with exe log filter category 3, exe log display:
25 logs found.
10 logs returned.
Proxy Options
Features that work, obviously from the name, in Proxy mode only.
• CLI config
• Block POST action - will prevent uploading files, authenticating to the web sites.
• cookiefilter - strips all cookies sent by website, will make 90% of web sites unusable today.
• activexfilter - strips all ActiveX applets from a web page, quite redundant today - no reputable
35
site uses ActiveX any more, and all browsers have it disabled anyway.
• javafilter - strip all Java applets, the same - no one uses them anymore and browsers have it
blocked by default.
Service : Web-filter
Status : Enable <-- WILL BE DISABLED IF NO WEB FILTER IS USED
IN SECURITY RULES
License : Contract
Service : Antispam
Status : Disable
Num. of servers : 1 <-- WITH ANYCAST, WITH UNICAST MANY SERVERS WILL
BE LISTED
Protocol : https
Port : 443
Anycast : Enable
Default servers : Included
IP
Weight
RTT Flags
TZ
FortiGuard-requests
Curr
Lost
Total Lost
Updated Time
173.243.141.16
Also, make sure under config sys fortiguard there is no set webfilter-force-off enable which
turns off the FortiGuard web filtering service.
• Make sure there are no other strange configs under sys fortiguard:
37
(fortiguard) # get
fortiguard-anycast : enable
fortiguard-anycast-source: fortinet
protocol : https
port : 443 <-- WORTH CHANGING IF IT IS BEING BLOCKED to 53, 8888
load-balance-servers: 1
auto-join-forticloud: disable
update-server-location: usa
sandbox-region :
update-ffdb : enable
update-uwdb : enable
update-dldb : enable
update-extdb : enable
update-build-proxy : enable
vdom : <-- WHICH VDOM IS USED TO CONNECT TO FORTIGUARD
auto-firmware-upgrade: enable
auto-firmware-upgrade-day:
auto-firmware-upgrade-delay: 3
auto-firmware-upgrade-start-hour: 1
auto-firmware-upgrade-end-hour: 4
FDS-license-expiring-days: 15
antispam-force-off : disable
antispam-cache : enable
antispam-cache-ttl : 1800
antispam-cache-mpermille: 1
antispam-license : Contract
antispam-expiration : Fri Jan 1 2038 <-- LIC EXPIRATION DATE
antispam-timeout : 7
outbreak-prevention-force-off: disable
outbreak-prevention-cache: enable
outbreak-prevention-cache-ttl: 300
outbreak-prevention-cache-mpermille: 1
outbreak-prevention-license: Contract
outbreak-prevention-expiration: Fri Jan 1 2038
outbreak-prevention-timeout: 7
webfilter-force-off : disable
webfilter-cache : enable
webfilter-cache-ttl : 3600
webfilter-license : Contract
webfilter-expiration: Fri Jan 1 2038 <-- LICENSE EXPIRATION DATE
webfilter-timeout : 15
anycast-sdns-server-ip: 0.0.0.0
anycast-sdns-server-port: 853
sdns-options :
source-ip : 0.0.0.0 <-- SOURCE IP TO USE
source-ip6 : ::
proxy-server-ip :
proxy-server-port : 0
proxy-username :
proxy-password : *
If you want to disable anycast and switch to unicast when having problems with FortiGuard servers
reachablity, see https://yurisk.info/2021/02/21/failed-to-connect-to-fortiguard-servers-updated/
• To see the latest update date and versions of all downloadable databases on Fortigate, run diag
autoupdate versions:
AV Engine
---------
Version: 7.00035 signed
Contract Expiry Date: Fri Jan 1 2038
Last Updated using manual update on Thu Nov 14 00:39:00 2024
Last Update Attempt: n/a
Result: Updates Installed
Virus Definitions
---------
Version: 1.00000 signed
Contract Expiry Date: Fri Jan 1 2038
Last Updated using manual update on Mon Apr 9 19:07:00 2018
Last Update Attempt: n/a
Result: Updates Installed
--CUT--
To debug auto updates: diagnose debug application update -1, dia deb enable, and exe update-
now. Excerpts of debug output:
39
upd_comm_connect_fds[457]-Trying FDS 173.243.141.6:443
[116] __ssl_cert_ctx_load: Added cert /etc/cert/factory/root_Fortinet_Factory.cer,
root ca Fortinet_CA, idx 0 (default)
[497] ssl_ctx_use_builtin_store: Loaded Fortinet Trusted Certs
upd_cfg_extract_sfas_version[789]-version=07004000SFAS00000-00005.00046-2502130417
pack_obj[186]-Packing obj=Protocol=3.2|Command=Update|Firmware=FGVMA6-FW-7.04-2726|
SerialNumber=FGTAWSNXXXXXX|UpdateMethod=0|AcceptDelta=1|
DataItem=07004000DBDB00100-00003
upd_status_extract_contract_info[1330]-pending registration(255)
support acct() company() industry() <-- THIS FGT IS NOT REGISTERED FOR SUPPORT
• Verify that the name resolving on the Fortigate works. For live queries to Fortiguard, Fortigate
uses 2 hosts - service.fortiguard.net (without anycast) and globalguardservice.fortinet.net
(with anycast):
• For Fortiguard Category filtering, make sure the websites are categorized correctly by looking at
the cache with diag webfilter fortiguard cache dump, see Category cache verification for
example output.
To see the whole list of Categories with their respective numbers, run get webfilter categories
• Logs - Web Filter logs are under Events → Security Events → Web Filter menu or on the CLI it is
exe log filter category 3 and exe log display. See example at [logs_cli]
• Regular dia deb flow debug is useful as well. E.g. for an internal host 192.168.17.0:
• Finally, the most verbose Web Filtering debug is dia deb app urlfilter -1, the example output:
I also write cheat sheets/scripts/guides to help in daily work, so make sure to check out my Github at
https://github.com/yuriskinfo and https://www.linkedin.com/in/yurislobodyanyuk/ for updates
41