Fortigate DoS/DDoS sensor/policy rules configuration and verification
Facts to know:
- You use Dos protection by creating Dos policy (Policy & Objects -> IPv4/Ipv6 DoS Policy) in which you enable/modify anomalies.
- The list of anomalies is pre-set in any policy you create. You only have the choice which ones to enable and which ones not to.
- All anomalies are set by default to Pass the offending traffic and are disabled, so make sure under the given anomaly to set
status enable
and action toblock
. On Fortigates with hardware NP modules, you also have Proxy as an action intcp_syn_flood
protection to enable, which makes Fortigate to proxy SYN connections. - You can (actually must) specify: source/destination IPs to match the DoS policy (
all
can be used), service (ALL
can be used), and incoming interface to apply the DoS policy to. - Thresholds for anomalies are configurable and do what they say - once traffic matched by this policy exceeds the threshold, it gets blocked. No learning or adaptive thresholds here.
- By default, only exceeding the threshold packets get blocked. To block the sender IP completely, you can use
set qurantine
parameter under the specific anomaly. - Dos sensor/policy protects against INCOMING traffic for the specified interface.
- For smarter anti-DDoS solution Fortinet have FortiDDoS physical appliance.
- Fortigate applies Dos protection early in the policy matching, before the Security policy is checked, so it consumes less resources than blocking the same traffic in Security rules. This means, though, that even if some security rule allows traffic, if such traffic exceeds DoS thresholds it may be blocked.
- Note: in previous versions of FortiOS the feature was called DoS sensor, so I mention it for easier reference only. In FortiOS 6.x and newer it is called DoS Policy.
- From my personal experience, to protect large networks with this DoS feature of Fortigate is more hassle than help. The false positives, especially for TCP SYN and alike protections, would block legitimate clients to the internal servers available from the Internet due to sudden surge of the client requests. You would need then to fix the thresholds, then again... For small networks, and those that do not have accessible from the outside servers, it may be a nice to have feature.
Configuring DoS policy.
I enable just icmp_flood
anomaly here and change the threshold to 10 packets per second sent to destination of 12.12.12.3 :
config firewall DoS-policy
edit 1
set interface "port1"
set srcaddr "all"
set dstaddr "12.12.12.3"
set service "ALL_ICMP"
config anomaly
edit "tcp_syn_flood"
set threshold 2000
next
edit "tcp_port_scan"
set threshold 1000
next
edit "tcp_src_session"
set threshold 5000
next
edit "tcp_dst_session"
set threshold 5000
next
edit "udp_flood"
set threshold 2000
next
edit "udp_scan"
set threshold 2000
next
edit "udp_src_session"
set threshold 5000
next
edit "udp_dst_session"
set threshold 5000
next
edit "icmp_flood"
set status enable
set action block
set threshold 10
next
edit "icmp_sweep"
set threshold 100
next
edit "icmp_src_session"
set threshold 300
next
edit "icmp_dst_session"
set threshold 1000
next
edit "ip_src_session"
set threshold 5000
next
edit "ip_dst_session"
set threshold 5000
next
edit "sctp_flood"
set threshold 2000
next
edit "sctp_scan"
set threshold 1000
next
edit "sctp_src_session"
set threshold 5000
next
edit "sctp_dst_session"
set threshold 5000
next
end
next
end
Verification
Sending 5 packets per second, traffic is NOT blocked:
root@ubuntu:~# ping -i 0.2 12.12.12.3
PING 12.12.12.3 (12.12.12.3) 56(84) bytes of data.
64 bytes from 12.12.12.3: icmp_seq=1 ttl=255 time=3.03 ms
64 bytes from 12.12.12.3: icmp_seq=2 ttl=255 time=1.96 ms
64 bytes from 12.12.12.3: icmp_seq=3 ttl=255 time=0.469 ms
64 bytes from 12.12.12.3: icmp_seq=4 ttl=255 time=0.318 ms
64 bytes from 12.12.12.3: icmp_seq=5 ttl=255 time=0.405 ms
64 bytes from 12.12.12.3: icmp_seq=6 ttl=255 time=0.497 ms
Sending roughly 10 packets per second - Fortigate starts to block excessive icmp packets.
root@ubuntu:~# ping -i 0.1 12.12.12.3
PING 12.12.12.3 (12.12.12.3) 56(84) bytes of data.
64 bytes from 12.12.12.3: icmp_seq=1 ttl=255 time=1.33 ms
64 bytes from 12.12.12.3: icmp_seq=2 ttl=255 time=0.712 ms
...
--- 12.12.12.3 ping statistics ---
143 packets transmitted, 115 received, 19% packet loss, time 14526ms
To see the active attacks/blocked anomalies (block happens when freq
goes 10 or higher):
diagnose ips anomaly list
FG3-AS1680 # diagnose ips anomaly list
list nids meter:
id=icmp_flood ip=12.12.12.3 dos_id=1 exp=993 pps=1 freq=14
Next, I add second policy with destination address all
but also with qurantine enabled.
config firewall DoS-policy
edit 2
set interface "port1"
set srcaddr "all"
set dstaddr "all"
set service "ALL"
config anomaly
edit "icmp_flood"
set status enable
set log enable
set quarantine attacker
set quarantine-expiry 2m <-- to set to 2 min I entered: 000d00h02m
set quarantine-log disable
set threshold 10
next
Exceeding the threshold:
root@ubuntu:~# ping -c 2000 -i 0.01 13.13.13.6
PING 13.13.13.6 (13.13.13.6) 56(84) bytes of data.
64 bytes from 13.13.13.6: icmp_seq=1 ttl=254 time=0.741 ms
64 bytes from 13.13.13.6: icmp_seq=2 ttl=254 time=1.82 ms
64 bytes from 13.13.13.6: icmp_seq=3 ttl=254 time=1.89 ms
--- 13.13.13.6 ping statistics ---
2000 packets transmitted, 11 received, 99% packet loss, time 24308ms
As you can see, 1st 10 packets were allowed, the 11th packet triggered the following block.
FG3-AS1680 # diagnose ips anomaly list
id=icmp_flood ip=13.13.13.6 dos_id=2 exp=998 pps=38 freq=83
Also, because I set qurantine period for 2 minutes, even after stopping the attack traffic, the sending server is blocked from sending ANY packets to the target 13.13.13.6 for the next 2 minutes:
root@ubuntu:~# ping 13.13.13.6
PING 13.13.13.6 (13.13.13.6) 56(84) bytes of data.
--- 13.13.13.6 ping statistics ---
11 packets transmitted, 0 received, 100% packet loss, time 10029ms
Releasing the blocked senders
Fortigate does not show us the source IPs of the blocked hosts, just the target IP, still, we can clear the blocked attackers list and allow the blocked senders to pass through. If they again send the excessive traffic, they will be blocked again, i.e the clear action is real-time and not permanent. Also, for the senders blocked with the quarantine, clearing the list will still keep them blocked until the qurantine expiration.
FG3-AS1680 # diagnose ips anomaly list
list nids meter:
id=icmp_flood ip=12.12.12.3 dos_id=1 exp=999 pps=2 freq=20
Clear the list:
diagnose ips anomaly clear
FG3-AS1680 # diagnose ips anomaly clear
FG3-AS1680 # diagnose ips anomaly list
list nids meter:
total # of nids meters: 0.
Follow me on https://www.linkedin.com/in/yurislobodyanyuk/ not to miss what I publish on Linkedin, Github, blog, and more.