Dealing with DDOS on Capped Internet

Hi everyone. I’m hoping someone can guide me on this as it’s quite a headache for me. As an end-user I’ve experienced a few times now whereby my capped internet runs out of bandwidth due to DDOS attacks. I’m not the only one but I was thinking this could possibly work, just have no clue how to do such a thing…

From my understanding, whether I dropped packets or reject them on the firewall the bandwidth has already been consumed. So if I had 200GB of dropped packets then thats me minus 200GB left for the month.

Is there some way that one could configure a script that would disconnect the pppoe when there is an excessive amount of dropped packets in say 15mins time. Lets say, if dropped packets exceed 1GB in 15mins, that it simply disconnects the PPPoE connection? How can I possibly achieve such a thing?

Your IP was the target of the DDOS?

More likely, you’ve got allow remote requests = yes in your DNS settings, and your box is being used as a soldier in the DDOS attack on some other victim… Try doing a DNS lookup from the Internet using your router’s wan IP as the server. If it works, then there’s your answer, and make sure your input chain is dropping DNS queries from the Internet side.

Eventually your box will be removed from the roster of exploitable DNS servers and this will go away - or else you could release your IP and get a shiny new one. :wink:

But you’re right about how the traffic is going to count against your monthly usage even if you discard it, so your script is probably a good idea if you keep getting such traffic.

The command to disable your PPPoE client would be easy if you only have one connection:
/interface pppoe-client disable [find]

I think you could cheat a little by making your rule have a bandwidth limit on it, and if exceeded, add an IP to the address list DISABLE PPPOE with a timeout of whatever amount of “hold down” time you like…

Then have a script that runs once per minute that checks whether there’s anything in DISABLE-PPPOE, and if the number of entries is > 0, execute the pppoe-client disable command.

I’m sure Boen_Robot could give you a much better script though. :slight_smile:

I do have remote requests on, but thats due to having multiple vlans and being able to query the mikrotik for dns internally. Dunno if i switch it off then I can’t query the mikrotik. But despite that DNS is definitely not reachable from the outside world. Tested this and used various tools to make sure all necessary ports are very much closed.

Re: your suggestion. I get what you say with the bandwidth limit, just really clueless as to how to configure these rules. Don’t always understand the whole ‘workflow’ of mikrotik. Confuses me more than anything lol.

I wasn’t saying to turn it off - just make sure the firewall rules block it from the outside.
If your box is an open DNS resolver, worms will find it, and it will get used for DNS amplification attacks later.


As for the firewall creating an IP Address entry automatically whenever the packet rate exceeds something:

go into your input filter chain and find the last rule - the default drop all rule.
Edit it and go to the ‘Extra’ tab, where you’ll find a section called ‘Limit’ (not Connection limit, Dst. Limit, etc - just Limit)
When you expand that row, you’ll see rate/sec and burst.
This is a packet counter. As long as the packets per rate (sec/min/hour) are below the specified rate, then the rule will match. When the rate exceeds this, then the rule will not match any more.

Set the rates to something like 30 / sec with a burst of 50.
Then after this rule, add another rule with no criteria whatsoever, only an action add src address to list, and set the list to be DOS and a timeout of something like 1hr.
Add one final rule after this, and make that rule’s action just be ‘drop’ (the new default drop rule)

Watch this for a while, and see whether anything appears in the DOS address list.
If so, check to see if your network is really getting DDOS traffic - if not, then loosen the timers. If so then you know it’s working. Now set a script to run on the scheduler and watch the DDOS list as in my earlier suggestion.

Ok, so there’s a bit of progress. Tested it by doing a flood ping from another remote host. If I flood ping my public ip then that remote host’s IP shows up in the ddos-list. Any chance you or someone else could assist with the script part. Not entirely sure I follow mikrotik’s scripting language here… appears very weird and foreign to me.

This should do the trick:

Go into system scripts and create a new script with name=ddos

:local ifname "ether4"

/ip firewall address-list
:log debug "running DDoS check script"

:if ( [:len [ find where list="DDOS" ] ] > 0 ) do={
  /int ethernet
  :local x [ find where name=$ifname and ! disabled ]
  :if ( [ :len $x ] > 0 ) do={
    :log info "disabling $ifname due to ddos attack."
    /int ethernet disable $x
  } else={ :log debug "$ifname already disabled." }
} else={
  /interface ethernet
  :local x [ find where name=$ifname and disabled ]
  :if ( [ :len $x ] > 0 ) do={
    :log info "All clear, captain. Re-enabling $ifname."
    enable $x
  } else={ :log debug "$ifname already enabled" }
}

Of course, change ifname in your copy to whichever ethernet interface has the modem attached to it.

Finally, set the script up with a scheduler entry. Create a new schedule and for “On Event” just type the name of your script (e.g. ddos if you named it as I did above).

I’d suggest the script interval be 1 minute, and don’t forget to put a timeout value on the address entry created by your add-address-to-list rule that you’ve been testing.

I had to modify it a bit, changed the script to this…

:local pppoe “WAN (PPPoE)”

/ip firewall address-list
:log debug “Running DDoS check script”

:if ( [:len [ find where list=“DDoS” ] ] > 0 ) do={
/int pppoe-client
:local x [ find where name=$pppoe and ! disabled ]
:if ( [ :len $x ] > 0 ) do={
:log info “Disabling $pppoe due to DDoS attack.”
/int pppoe-client disable $x
} else={ :log debug “$pppoe already disabled.” }
} else={
/int pppoe-client
:local x [ find where name=$pppoe and disabled ]
:if ( [ :len $x ] > 0 ) do={
:log info “All clear. Re-enabling $pppoe.”
enable $x
} else={ :log debug “$pppoe already enabled” }
}

sadly it doesn’t seem to work. i see the log info ‘disabling due to ddos attack’ but the pppoe does not get disabled. not sure why because if i run /int pppoe-client disable “WAN (PPPoE)” manually via ssh it works…

try putting quotes around the variable name - name=“$pppoe” - because your interface name has a space in it.

managed to get it right. didn’t get the script policy stuff. a better term would be ‘script permissions’ …

thanks ZeroByte for all the help! Really appreciate it!