Configure Suricata as IPS to prevent host from SYN Flood

Hi everyone.
I need to know what kind of setting do I have to configure on suricata.yaml or the rules to prevent my host from SYN Flood.
I’ve been configure it to drop it using these following rule:

drop http any any -> $HOME_NET 80 (msg:“HPING3”; ttl:64; flags:S; threshold:type threshold; track by_dst, count 100, seconds 5; classtype:attempted-dos; sid:1; rev:1; metadata:created_at 2020_06_11, updated_at 2020_06_11;)

but the problem then is that every http request from the client cannot be processed because iptables is blocking port 80.

Is there any reference for this thing? I’ve been looking for it, but the topic on suricata is too broad, whereas I have little time to finish this.
hope anyone can help me solve this problem

This can’t be done in a single rule, instead you’ll need an alert rule that matches on the SYN pkts and then a rate_filter threshold rule (in threshold.config) that dynamically changes it to a drop rule:

See also Rules - limiting traffic to a specific time

The http protocol shouldn’t be used in such a rule btw, in a SYN packet we normally don’t know what the protocol will be yet.


Is the existing rule activated or replaced by a new rule?
what else do I need to change? maybe in suricata.yaml, or additional rules? I tried the rate_filter that you said, but on fast.log doesn’t detect or detect anything. Anyway I used hping3 (SYN flag) to do the attack.

I already changed http to tcp, so the rule is:
drop tcp any any -> $HOME_NET 80 (msg:“HPING3”; ttl:64; flags:S; threshold:type threshold; track by_dst, count 100, seconds 5; classtype:attempted-dos; sid:1; rev:1; metadata:created_at 2020_06_11, updated_at 2020_06_11;)

This rule would drop all SYN packets being sent to the server on port 80. Would it be better to do track by_src so you oinly drop packets from the supposed SYN packet spammer?

A rule like this

alert tcp any any -> $HOME_NET any (msg:"HPING3"; ttl:64; flags:S; sid:1; rev:1;)

combined with a rate filter like this one

rate_filter gen_id 1, sig_id 1, track by_src, count 100, seconds 5, \
  new_action drop, timeout 30

would drop all packets from any ip sending more than 100 syn packets in less than 5 seconds to any HOME_NET IP. The spamming IP would be unblocked after 30 seconds.
The downside to this approach is that the rule will flood your alert logs due to triggering on all SYN packets when not dropping.

I have not actually tested this and might have misunderstood Victor.

I wonder if you could add a threshold for that. Maybe that would conflict with the rate_filter.

You could also add noalert;, but then it would just never alert. You’d still get drop records in EVE though.

I changed the rate_filter on track by_src to track by_dst and now it sends log to fast.log.

But still doesn’t drop anything :sweat_smile:

Is it have something to do with iptables / firewall stuff?

The last screenshot shows that Suricata didn’t not see any packet? This is odd as your fast.log screenshot does show some alerts.

Do you see any other logs in http.log or eve.json?

http.log is empty, it doesnt show any alerts. but eve.json shows that it blocked the attack.
http.log :

eve.json :

but still, it seems like the dropped packet isnt detected.

Here is my suricata.yaml file:
suricata.yaml (68.8 KB)

I believe there is another Suricata running. The eve.json alert record has a in_iface field, which has a value of vboxnet0. The NFQUEUE mode doesn’t set this. It also still shows 0 packets in the screenshot.

What does pidof suricata tell you?

Screenshot from 2020-07-01 13-34-27

what problem this could be? I’ve been looking for anything in suricata.yaml but still dont get anything

The problem is likely in your iptables rules setup and/or in the general routing. Can you share your iptables rules? iptables -v -L.

can suricata run in two modes (NFQ and AF_PACKET)?

No, its either one or the other. You can of course run multiple instances of Suricata, but you’ll have to make sure they don’t get in each others way by specifying unique paths.

So what else do I have to configure based on my iptables rules?

It is probably easiest if you only use the NFQUEUE-suricata while testing. So start that & make sure no other Suricata is running. Then run your hping test, and check:

  • iptables -v -L to see if the packet counters for the NFQUEUE rules are increasing as you expect
  • eve.json stats records: tail -f eve.json | jq -c 'select(.stats)|.stats.ips'
  • eve.json http records: tail -f eve.json | jq -c 'select(.event_type=="http")'

this is the NFQUEUE rules from iptables -v -L

it’s the only thing i got from tail -f eve.json | jq -c 'select(.stats)|.stats.ips'

and tail -f eve.json | jq -c 'select(.event_type=="http")' :