Technical Tip: How to configure FortiGate to perform routing based on specific URLs using One-Arm URL filtering
Description
This article describes a few options for configuring the FortiGate to route traffic based on the URL/FQDN of the destination. This article will primarily focus on a method based on One-Arm URL Filtering, though modern alternative options will also be suggested.
Scope
FortiGate.
Solution
Consider the following example topology:

In the above topology, the FortiGate is configured with a pair of ISP uplinks, and the administrator would prefer that certain websites (such as 'www.fortinet.com') are accessed via ISP 2, with ISP 1 handling all other general Internet access. This setup would benefit from the FortiGate being able to dynamically resolve the public IP address(es) associated with the destination website, especially in cases where the IP addresses can change frequently (e.g., CDN-based websites, Geo DNS, etc.) such that standard policy-based routing is not efficient.
One option available for accomplishing this is to partially utilize One-Arm URL Filtering. For an in-depth explanation of this feature and its primary purpose, review the following KB article: Technical Tip: Understanding One-Arm URL Filtering on the FortiGate (AKA offline/parallel Web Filtering).
To briefly summarize the KB article, One-Arm URL Filtering is able to produce static routes based on FQDNs that are entered into a Static URL Filter. This could be used to create a list of FQDNs that should be routed using a specific outgoing interface, though there are alternative options available, such as Static Routes based on FQDN Address Objects and SD-WAN Rules with FQDN Address Objects. The following is a comparison of the three proposed methods, though this article will focus on the One-Arm URL Filtering method and the example configuration that would need to be implemented:
One-Arm URL Filtering.
- Overview: FortiGate extracts FQDNs from the Static URL Filter list created by the admin, resolves them via DNS, and then generates /32 static routes for each resolved IP address.
- Pros:
- Resolves DNS using up to five servers that can be configured separately from system DNS.
- Entries are managed from a single Web Filter page as part of the Static URL Filter table.
- Does not require a Web Filter Profile to be applied to a Firewall Policy to function.
- Works with SD-WAN.
- Cons:
- Can only specify a single outgoing interface and next-hop gateway associated with these routes per-VDOM.
- Only configurable via the CLI.
FQDN-based Static Routes.
- Overview: Admin creates FQDN Address objects and then creates static routes using these FQDN objects (see also: Technical Tip: Creating a static route that uses a FQDN firewall address object).
- Pros:
- Can configure each route individually.
- Routes can be configured for multiple outgoing interfaces.
- Centralized in regular static routing config, rather than a separate, CLI-only section.
- Cons:
- Does not work with SD-WAN (see: Technical Tip: Why FQDNs or Named Addresses cannot be used in SD-WAN static routes).
- FQDN Address objects can only be resolved via FortiGate's configured system DNS servers.
SD-WAN Rules with FQDN destination.
- Overview: Admin creates FQDN Address objects and then creates SD-WAN Rules with these FQDN objects as Destinations (see also: SD-WAN rules overview).
- Pros:
- Works well with existing SD-WAN configurations.
- SD-WAN Rules allow for more dynamic routing (traffic can be re-routed via any SD-WAN member depending on health-check/SLA states).
- Cons:
- Requires SD-WAN to already be configured.
- Routing is handled as part of SD-WAN only, so no additional routes are added to the routing table (i.e., for redistribution into dynamic routing protocols like BGP).
Configuring One-Arm URL filtering:
The following is an example configuration for One-Arm URL Filtering that will resolve FQDNs defined in the Web Filter/Static URL Filter table and generate static routes for those addresses that egress via ISP 2 (port2, next-hop gateway 192.168.1.2). As a reminder, a more in-depth explanation of each of these settings can be found at the following KB article: Technical Tip: Understanding One-Arm URL Filtering on the FortiGate (AKA offline/parallel Web Filtering).
config system ips-urlfilter-dns <--- Specify DNS servers used to resolve FQDNs in the Static URL Filter table.
edit 208.91.112.52
next
edit 208.91.112.53
next
edit 1.1.1.1
next
edit 8.8.8.8
next
end
config webfilter ips-urlfilter-cache-setting
set dns-retry-interval 1800 <--- FortiGate re-queries for these FQDNs every 1800 seconds (30 minutes)...
set extended-ttl 432000 <--- ...and caches the results for 432000 seconds (5 days).
end
config webfilter ips-urlfilter-setting <--- Specifies the interface, next-hop gateway, and administrative-distance for routes.
set device "port2"
set gateway 192.168.1.2
set distance 1
end
With the above baseline configuration created, the next step is to create a Static URL Filter table that contains Simple-type entries with the Block action, followed by enabling one-arm-ips-urlfilter. Note that while it is necessary to create the Web Filter profile, it is not necessary to actually install this specific profile into a Firewall Policy, as the routes will be generated as soon as the Static URL Filter entries are created and saved in the configuration.
Additionally, these entries can be created directly in the CLI, but an easier method may be to create and manage the profile from the Web GUI (for more info, see: Technical Tip: Using a static URL filter feature to allow/block web sites:(
config webfilter urlfilter
edit 1
set name "UrlList"
set one-arm-ips-urlfilter enable
config entries
edit 1
set url "fortinet.com"
set action block
next
end
next
end
config webfilter profile
edit "URLsOverPort2"
config web
set urlfilter-table 1
end
next
end
Verification and troubleshooting:
To verify the current cache of domain names and resolved IP entries on the FortiGate (must be run from Global VDOM), run the command diagnose test application ipsufd 1:
FortiGate # diagnose test application ipsufd 1
"fortinet.com",IPv4,80681,1,"54.177.212.176 (80681)(United States)","54.151.118.105 (80681)(United States)",
To view the route cache entries associated with the resolved IP addresses, run the command diagnose test application ipsufd 6:
FortiGate # diagnose test application ipsufd 6
IPv4 GEO cache:
54.151.118.105 geo=21333(United States) ref=1
54.177.212.176 geo=21333(United States) ref=1
To check that the routes have been installed in the routing table, run the command get router info routing-table all or get router info routing-table static:
FortiGate # get router info routing-table all
Codes: K - kernel, C - connected, S - static, R - RIP, B - BGP
O - OSPF, IA - OSPF inter area
N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external
E1 - OSPF external type 1, E2 - OSPF external type 2
i - IS-IS, L1 - IS-IS level-1, L2 - IS-IS level-2,
* - candidate default
S* 0.0.0.0/0 [10/0] via 10.108.19.254, port1
[10/0] via 192.168.1.2, port2
C 10.108.16.0/22 is directly connected, port1
C 192.168.1.0/24 is directly connected, port2
C 10.158.0.0/22 is directly connected, internal1
S 54.151.118.105/32 [1/0] via 192.168.1.2, port2, [254/0] <--- Note the AD of 1 and priority of 254.
S 54.177.212.176/32 [1/0] via 192.168.1.2, port2, [254/0]
Finally, to verify that traffic is flowing out via port2 as expected, check with a packet capture on the FortiGate:
FortiGate # diagnose sniffer packet any "host 54.151.118.105 or host 54.177.212.176" 4 10
interfaces=[any]
filters=[host 54.151.118.105 or host 54.177.212.176]
4.621420 internal1 in 10.158.2.66.50405 -> 54.151.118.105.80: syn 3734828542
4.621724 internal1 out 54.151.118.105.80 -> 10.158.2.66.50405: syn 4262438317 ack 3734828543
4.622091 internal1 in 10.158.2.66.50405 -> 54.151.118.105.80: ack 4262438318
4.622681 internal1 in 10.158.2.66.50405 -> 54.151.118.105.80: psh 3734828543 ack
4.622824 internal1 out 54.151.118.105.80 -> 10.158.2.66.50405: ack 3734829576
4.625467 port2 out 10.108.18.9.50405 -> 54.151.118.105.80: syn 28282687
4.817876 port2 in 54.151.118.105.80 -> 10.108.18.9.50405: syn 3871582676 ack 28282688
4.818094 port2 out 10.108.18.9.50405 -> 54.151.118.105.80: ack 3871582677
4.819637 port2 out 10.108.18.9.50405 -> 54.151.118.105.80: psh 28282688 ack
5.014052 port2 in 54.151.118.105.80 -> 10.108.18.9.50405: ack 28283721
10 packets received by filter
0 packets dropped by kernel
Related articles: