Redux "possible SYN flooding ..."

This had been addressed a small number of times when the first version of ROS to include the (apparently a bit overactive) DNS TCP syn flood (7.18, if I recall correctly). Since then it hasn't appeared (much).

I'd never seen this on any of my MikroTiks. Until now.

This morning for the first time I noticed it on an RB951Ui-2HnD running ROS stable 7.24.2. This router's DNS server is only accessible from its internal LAN. All DNS requests were routine, reasonable, not floody-looking. Hm, ok, looking back through the log, this particular MikroTik has logged this message 15 times since August 10th, and just one other of my four active MikroTiks (various hardware models, all always running the then-current 'stable' release versions; automatic updating scripts run nightly) has logged a TCP syn flood warning message just three times. The other two routers do not have a TCP syn flood warning message in their current logs.

On this one router, in addition to mostly port 53 warnings, I also see a few port 80 warnings; port 80 on this router is only open to inbound port 80 connections briefly when the router itself has first reached out to an ACME certificate issuer, and then only to connections from the ACME server (one DNS name that ROS dynamically resolves).

Amusingly, the only other of the four routers which has reported a possible SYN flood, has only three such entries in the log, and two of them are WinBox (which is only ever accessible from my internal LANs).

So it seems that this TCP syn flood detection in ROS really is a bit hyperactive.
Is there a way to tune it down, or should I just report this as a probably bug (or, mis-feature) to MikroTik?

thanks,

Hello, I think the best method is do an investigation to know what is the possible reason to receave that. But, ROS have 2 methods to avoid SYN Flood.

[admin@MikroTik] > /ip settings set tcp-syncookies=yes

Look before:

[admin@MikroTik] > /ip settings print
ip-forward: yes
send-redirects: yes
accept-source-route: no
accept-redirects: no
secure-redirects: yes
rp-filter: no
ipv4-multipath-hash-policy: l3
tcp-syncookies: no
tcp-timestamps: random-offset
max-neighbor-entries: 8192
arp-timeout: 30s
icmp-rate-limit: 10
icmp-rate-mask: 0x1818
icmp-errors-use-inbound-interface-address: no
allow-fast-path: yes
ipv4-fast-path-active: yes
ipv4-fast-path-packets: 0
ipv4-fast-path-bytes: 0
ipv4-fasttrack-active: no
ipv4-fasttrack-packets: 0
ipv4-fasttrack-bytes: 0

Look after:

admin@MikroTik] > /ip settings print
ip-forward: yes
send-redirects: yes
accept-source-route: no
accept-redirects: no
secure-redirects: yes
rp-filter: no
ipv4-multipath-hash-policy: l3
tcp-syncookies: yes
tcp-timestamps: random-offset
max-neighbor-entries: 8192
arp-timeout: 30s
icmp-rate-limit: 10
icmp-rate-mask: 0x1818
icmp-errors-use-inbound-interface-address: no
allow-fast-path: yes
ipv4-fast-path-active: yes
ipv4-fast-path-packets: 0
ipv4-fast-path-bytes: 0
ipv4-fasttrack-active: no
ipv4-fasttrack-packets: 0
ipv4-fasttrack-bytes: 0

And, you can limit your router to receive TCP SYN messages with:

/ip firewall filter
add action=drop chain=input src-address-list=block-syn-flood
add action=add-src-to-address-list address-list=block-syn-flood address-list-timeout=1d chain=input dst-port=53
limit=100,5:packet protocol=tcp tcp-flags=syn

The dst-port can be not set, but (of course), the protocol must be TCP.

But, becareful with the limit, choose a real limit to your reality.

Obs.: Those commands are in a CHR with zero configurations, so, becareful with the mentioned configurations. use safe-mode to avoid any problem.

Without making wild guesses or offering solutions that fail to stop anything,
especially since they don't address the root cause,
please show the firewall /export, as is standard practice.

Yeah, all of that "how to protect against SYN floods" seems a bit off, since these are internally-accessible-only MikroTik routers; only my known devices are on their LANs; and I have no reason to believe that any traffic that the MikroTik routers are receiving is in any way unusual. The question really is: Is ROS' "SYN flood 'detection'" known to be a bit overly sensitive?

About the firewall rules, here is information from one of the simpler configured devices, which did report three possible SYN floods (including the WinBox items):grin: :
{ I '# quoted the comment lines; is there a way to post text into this MikroTik forum, where a text line begins with #, which avoids that being misinterpreted by the forum software as indicating LARGE HEADER TEXT? }

I'm fairly sure that I've set/changed nothing in here that would modify how ROS by default decides when something looks like a SYN flood, and I don't think that any of my LAN traffic should look like a SYN flood - it's all pretty default stuff.

'# 2026-09-14 16:26:12 by RouterOS 7.24.2
'# software id = R90K-MHKZ
'#
'# model = RB951Ui-2HnD
'# serial number = ..........
/ip firewall filter
add action=accept chain=input comment="defconf: accept ICMP" protocol=icmp
add action=accept chain=input comment="defconf: accept established,related" connection-state=established,related
add action=drop chain=input comment="defconf: drop all from WAN" disabled=yes in-interface=ether1
add action=fasttrack-connection chain=forward comment="defconf: fasttrack" connection-state=established,related
add action=accept chain=forward comment="defconf: accept established,related" connection-state=established,related
add action=accept chain=input comment=
"SUPERCEDED BY AUTOMATIC OUTGOING ACME ADDRESS-LIST BASED TEMPORARY ACCESS RULES: Allow HTTP port 80 for ACME" disabled=yes
dst-address=192.168.254.3 dst-port=80 in-interface=bridge log=yes log-prefix=HTTP80 protocol=tcp
add action=drop chain=forward comment="defconf: drop invalid" connection-state=invalid
add action=accept chain=input comment="TEMP allow JayThink to try to talk to Tado" disabled=yes dst-address=192.168.254.248/29
in-interface=bridge src-address=192.168.254.24
add action=accept chain=forward comment="TEMP allow Tado to say anything to anyone" disabled=yes in-interface=ether5
add action=accept chain=input comment="Allow Tado network to talk to MikroTik e.g. DNS, DHCP, ..." dst-address=192.168.254.249
src-address=192.168.254.248/29
add action=drop chain=input comment="Block all other attempts from Ether5 (Tado isolation network) to talk to any of my internal
networks. (Tado is only allowed to talk to the Internet and the MikroTik)" dst-address=192.168.0.0/16 in-interface=ether5
add action=accept chain=forward comment=
"(other than what was blocked from Tado on Ether5 above) Allow Tado to talk (to Internet)" in-interface=ether5
add action=drop chain=forward comment=
"Do not allow MERCUSYS ME10 WiFi range extender to talk to anything outside of Felines networks" dst-address=
!192.168.252.0/22 log=yes log-prefix="ME10 forward" src-address=192.168.254.62
add action=drop chain=input comment=
"Do not allow MERCUSYS ME10 WiFi range extender to talk to anything outside of Felines networks" dst-address=
!192.168.252.0/22 log=yes log-prefix="ME10 input" src-address=192.168.254.62
'# sstp-out1 not ready
'# sstp-out1 not ready
add action=accept chain=input comment="Allow Felines MikroTik VPN networks, coming through MikroTiks' VPN tunnel from BCN"
in-interface=sstp-out1 src-address-list=FelinesMikroTikVPNNets
add action=accept chain=input comment=
"Allow Felines MikroTik VPN networks, coming through MikroTiks' WireGuard VPN tunnel from BCN" in-interface=wg1
src-address-list=FelinesMikroTikVPNNets
add action=accept chain=input comment="Allow Felines Ribes de Freser network" src-address=192.168.254.0/24
add action=accept chain=input comment=
"Allow connections to MikroTik2 on $someport for SSTP VPN redirected from public $someotherport by Vodafone router" dst-address=
192.168.254.3 dst-port=$someport protocol=tcp
add action=accept chain=input comment="Allow WireGuard VPN connections in to MikroTik2" dst-port=$myWGport in-interface=bridge
protocol=udp
add action=add-src-to-address-list address-list=KnockKnock:$knockPort1 address-list-timeout=1m chain=input comment=
"Port knocking to enable direct outside administrative access" dst-port=$knockPort1 protocol=tcp
add action=add-src-to-address-list address-list=KnockedSuccessfully address-list-timeout=1m chain=input comment=
"Port knocking to enable direct outside administrative access, part 2" dst-port=$knockPort2 log=yes log-prefix=
"Knocked successfully" protocol=tcp src-address-list=KnockKnock:$knockPort1
add action=add-src-to-address-list address-list=Suspected_port_scanners address-list-timeout=5m chain=input comment="Detect port
scanners. n.b. in order for this to work, the ISP router in front of this MikroTik must allow a few invalid ports through. We
_set those to (the ports that wrap around our knock ports)" connection-state=!established in-interface=
bridge log=yes log-prefix="firewall Portscanner(psd)" protocol=tcp psd=3,1m,1,1 src-address=!192.168.248.0/21
add action=accept chain=input comment="Accept connections from those who have knocked successfully in the past 60 seconds" log=
yes log-prefix="Connect After Knocking" src-address-list=KnockedSuccessfully
add action=drop chain=input comment="Drop all other attempts to enter Mikrotik2 not permitted above"
add action=drop chain=forward comment="defconf: drop all from WAN not DSTNATed" connection-nat-state=!dstnat connection-state=
new disabled=yes in-interface=ether1
add action=accept chain=output comment="Allow anything out to Tado on Ether5" out-interface=ether5
add action=accept chain=input comment="When MikroTik ACME client reaches out (see mangle rules) the ACME-client list will tempora
rily be populated with {me}, which will allow incoming HTTP connections for the ACME server to perform Domain Validation. This avoids the need to keep port 80 open inbound all the time." dst-address-list=ACME-client dst-port=80 in-interface=bridge
log=yes log-prefix=HTTP80 protocol=tcp

use </> button after selecting the code

This is the actual order in which the rules are considered; you have them mixed up, and they aren't easy to read.

# 2026-09-14 16:26:12 by RouterOS 7.24.2
# software id = R90K-MHKZ
#
# model = RB951Ui-2HnD
# serial number = ..........
/ip firewall filter
add action=accept chain=input comment="defconf: accept ICMP" protocol=icmp
add action=accept chain=input comment="defconf: accept established,related" connection-state=established,related
add action=drop chain=input comment="defconf: drop all from WAN" disabled=yes in-interface=ether1
add action=accept chain=input comment="SUPERCEDED BY AUTOMATIC OUTGOING ACME ADDRESS-LIST BASED TEMPORARY ACCESS RULES: Allow HTTP port 80 for ACME" disabled=yes dst-address=192.168.254.3 dst-port=80 in-interface=bridge log=yes log-prefix=HTTP80 protocol=tcp
add action=accept chain=input comment="TEMP allow JayThink to try to talk to Tado" disabled=yes dst-address=192.168.254.248/29 in-interface=bridge src-address=192.168.254.24
add action=accept chain=input comment="Allow Tado network to talk to MikroTik e.g. DNS, DHCP, ..." dst-address=192.168.254.249 src-address=192.168.254.248/29
add action=drop chain=input comment="Block all other attempts from Ether5 (Tado isolation network) to talk to any of my internal networks. (Tado is only allowed to talk to the Internet and the MikroTik)" dst-address=192.168.0.0/16 in-interface=ether5
add action=drop chain=input comment="Do not allow MERCUSYS ME10 WiFi range extender to talk to anything outside of Felines networks" dst-address=!192.168.252.0/22 log=yes log-prefix="ME10 input" src-address=192.168.254.62
# sstp-out1 not ready
add action=accept chain=input comment="Allow Felines MikroTik VPN networks, coming through MikroTiks' VPN tunnel from BCN" in-interface=sstp-out1 src-address-list=FelinesMikroTikVPNNets
add action=accept chain=input comment="Allow Felines MikroTik VPN networks, coming through MikroTiks' WireGuard VPN tunnel from BCN" in-interface=wg1src-address-list=FelinesMikroTikVPNNets
add action=accept chain=input comment="Allow Felines Ribes de Freser network" src-address=192.168.254.0/24
add action=accept chain=input comment="Allow connections to MikroTik2 on $someport for SSTP VPN redirected from public $someotherport by Vodafone router" dst-address=192.168.254.3 dst-port=$someport protocol=tcp
add action=accept chain=input comment="Allow WireGuard VPN connections in to MikroTik2" dst-port=$myWGport in-interface=bridge protocol=udp
add action=add-src-to-address-list address-list=KnockKnock:$knockPort1 address-list-timeout=1m chain=input comment="Port knocking to enable direct outside administrative access" dst-port=$knockPort1 protocol=tcp
add action=add-src-to-address-list address-list=KnockedSuccessfully address-list-timeout=1m chain=input comment="Port knocking to enable direct outside administrative access, part 2" dst-port=$knockPort2 log=yes log-prefix="Knocked successfully" protocol=tcp src-address-list=KnockKnock:$knockPort1
add action=add-src-to-address-list address-list=Suspected_port_scanners address-list-timeout=5m chain=input comment="Detect port scanners. n.b. in order for this to work, the ISP router in front of this MikroTik must allow a few invalid ports through. We set those to (the ports that wrap around our knock ports)" connection-state=!established in-interface=bridge log=yes log-prefix="firewall Portscanner(psd)" protocol=tcp psd=3,1m,1,1 src-address=!192.168.248.0/21
add action=accept chain=input comment="Accept connections from those who have knocked successfully in the past 60 seconds" log=yes log-prefix="Connect After Knocking" src-address-list=KnockedSuccessfully
add action=drop chain=input comment="Drop all other attempts to enter Mikrotik2 not permitted above"
add action=accept chain=input comment="When MikroTik ACME client reaches out (see mangle rules) the ACME-client list will tempora rily be populated with {me}, which will allow incoming HTTP connections for the ACME server to perform Domain Validation. This avoids the need to keep port 80 open inbound all the time." dst-address-list=ACME-client dst-port=80 in-interface=bridge log=yes log-prefix=HTTP80 protocol=tcp

add action=fasttrack-connection chain=forward comment="defconf: fasttrack" connection-state=established,related
add action=accept chain=forward comment="defconf: accept established,related" connection-state=established,related
add action=drop chain=forward comment="defconf: drop invalid" connection-state=invalid
add action=accept chain=forward comment="TEMP allow Tado to say anything to anyone" disabled=yes in-interface=ether5
add action=accept chain=forward comment="(other than what was blocked from Tado on Ether5 above) Allow Tado to talk (to Internet)" in-interface=ether5
add action=drop chain=forward comment="Do not allow MERCUSYS ME10 WiFi range extender to talk to anything outside of Felines networks" dst-address=!192.168.252.0/22 log=yes log-prefix="ME10 forward" src-address=192.168.254.62
add action=drop chain=forward comment="defconf: drop all from WAN not DSTNATed" connection-nat-state=!dstnat connection-state=new disabled=yes in-interface=ether1

add action=accept chain=output comment="Allow anything out to Tado on Ether5" out-interface=ether5

"Allow anything out to Tado on Ether5" It is absolutely useless.

"defconf: drop all from WAN not DSTNATed" is disabled...

That (Allow anything out to Tado on Ether5 is useless; defconf: drop all from WAN not DSTNATed is disabled) may be true, but how does it relate to the concern, which is that my routers are reporting what I'd argue are spurious "possible TCP syn flood" warnings?

All I see is bloated junk.
Too hard to discern what the problem may be.
It would appear your concern is more about blocking stuff, than simply ensuring NEEDED traffic is passed and everything just simply dropped by catch all drop rules at the end of the input/forward chain.

The only thing you should have in the input chain besides the default rules are
a. bonafide vpn ports allowed ( wireguard, ipsec etc.)
b. allow admin access.
c. perhaps allow lan users to DNS
d. drop rule at end to discard any other traffic.

Same goes with forward chain, some of the default rules
allow users to go out to the internet if required.
( note: different user groups should be on different vlans for basic separation at layer2 )
admin access to all
permit any other NEEDED inter router traffic ( like users to common printer etc)
permit any other NEEDED incoming vpn traffic ( to devices etc.)
drop rule at end to drop all other layer3.

Anav is right and your firewall is sort of a mix of different concepts. However, based on a shallow reading, I don't see that your ports would be open to the outside.

It would be helpful if you could add action=passthrough log=yes rules to your input chain right below the accept established/related rule. Do this selectively for the dst ports that the alerts are about. This will allow you to see where these connections are coming from.

I don't know exactly how Mikrotik's SYN flood alerting works exactly, but I've seen it triggered for totally legitimate traffic, especially at/near router restarts. If the traffic is legitimate, it's a totally valid handling of the situation to just ignore them. (Some people have this weird view that warnings should somehow be made to disappear, because it disrupts their mental filing cabinet. Sometimes warnings are simply spurious.)

I agree, this "firewall"'s filter rules are a years-old collection of mostly cruft. But they're not the focus here.

All of my MikroTik routers sit behind ISP standard block-all-by-default firewalls, with a small number of forward-this-port-to-that-internal-IP-address holes poked through them.

NONE of the ISP routers ever forward the WinBox port in. And the one that forwards in port 80 reaches an input filter rule which allows connections only from the ACME certificate server, and only during brief periods of time right after the MikroTik router has reached out to that ACME certificate server.

So really I ask everyone to stop focusing on the agreed mess that are most of the rules.

To the TCP syn flood detection, which is my whole focus here, I argue that any time a "warning" is raised (and, indeed, ROS' built-in TCP syn flood detection is hardwired to raise system,warning) then it must be more likely right most of the time, and it must include (without the administrator having to after the fact set up debugging rules to try to guess what might have trigged inadequate quality detection) sufficient details to allow the administrator or their security team to efficiently evaluate whether this requires action.

(I spent years in the engineering function of a major airline, building the systems which could generate sensor events which would feed detection algorithms, to which the whole Security Operations Centre would have to respond; poor quality alerting was a Very Bad Thing, because even with only good quality alerting there was generally too much to try to look at).

So, I agree that sometimes the right response is "ignore"; I disagree that warnings should not be made to disappear just because they disrupt some people's mental filing cabinets -- our mental filing cabinets are already disrupted with real information; it is a necessary characteristic of security-oriented devices that they do not unnecessarily produce false positives, that they do not produce un-actionable alerts (see Ssld,error ssl: record overflow, no common ciphers - yes, someone did something potentially bad towards the ROS ssld process .. but the errors do not provide enough information to be able to analyze it at all), and that real effort is made by the manufacturer to present information in a consistent, not-mental-filing-cabinet-disruptive form.

If you disregard my "mental filing cabinet" comment, my point is exactly that in my experience these sorts of detectors don't work reliably at all.

You may be right that it would be better to have diagnostics available for a given event, and the usual IDS/IPS platforms do produce the kind of logs you're looking for. They are much beefier devices, and most of the time this feature comes with warnings about the excessive write loads they produce. (E.g. for a product like https://shop.opnsense.com/product/dec677-opnsense-desktop-security-appliance/ it's specified that IDS/IPS is only supported with a proper NVMe SSD.) This explains why it's not done by default on Mikrotiks.

The usual cause for these SYN flood type warnings is either some over-zelous device or some type of thundering herd phenomenon.

I'd recommend turning on the suggested logging just to be sure. Otherwise, taking these warnings at face value and trying to somehow acting on them without knowing the full story is more likely to be harmful than to have any positive outcome.

If the log entries appear around the time after the router rebooted, then they can be explained:

If they appear long after reboot, but only sporadically, then it could be that there was some connectivity issue with the upstream DNS servers.

Most of the normal DNS traffic (initiated by normal clients, non-DoH/DoT/DoQ, also not zone transfers between DNS servers) is normally over UDP. The clients only switch to TCP when the response is too big (server answers with a flag that says that the answer has been truncated), or when they did not get a response to a query over UDP after a couple of seconds. In your case within your LAN, the flood of TCP SYN on port 53 of the router is probably due to the latter.

As I also saw this on WinBox, which is only ever accessible locally, I conclude that MikroTik's "SYN flood ''detection''" is not very useful.

I agree with all the other comments about real IDS type features requiring much more powerful boxes; perhaps MikroTik should not attempt to do these things at all if what they're going to produce is "there may be something. or, maybe not. and it's impractical to really figure it out" for TCP syn, for ssld errors, and a lot of other stuff.

I love the power-price ratio of MikroTik. I am less impressed by their product feature decision-making.

Its all very explainable, they have in internal organization that decides all functionality:

Latvian Synatax Decisions :slight_smile: