[Linux UFW] Protect master port against DDOS attacks
Hello, this is the first time I post a tutorial so please be kind :).
So this tutorial is for anyone who hosts an MW3 server on a Linux distribution that has UFW (Like Debian, Ubuntu or Arch). I'm sure it can be replicated with iptables alone which is a module present in any Linux distro (or it can be installed on any I think).
The information I have on game ports is true for a good old Tekno MW3 server but I'm sure the same rules apply for a server hosted with Pluto.
If you have followed the headless tutorial made by Spectre you have already UFW enabled. Just in case do
sudo ufw status
It should say
Status: active Logging: on (low) Default: deny (incoming), allow (outgoing), disabled (routed) New profiles: skip
If not please follow Spectre tutorial as he explains how to enable ufw on Ubuntu 16/18/(and 20)
So now that you have ufw enabled you probably also have added your custom rules for allowing traffics to the ports used by your game server(s).
Open with nano (or another editor) /etc/ufw/ufw.conf and add IPV6=no like this:
# /etc/ufw/ufw.conf # IPV6=no # Set to yes to start on boot. If setting this remotely, be sure to add a rule # to allow your remote connection before starting ufw. Eg: 'ufw allow 22/tcp' ENABLED=yes # Please use the 'ufw' command to set the loglevel. Eg: 'ufw logging medium'. # See 'man ufw' for details. LOGLEVEL=low
You don't need IPV6 IPs peeping on your server right now so just block them right away.
Restrict access to net_authPort and net_queryPort
These two ports don't need to be accessible by anyone but your VM/VPS IP address. Let's say that you have already put a general rule in place for these two ports and you want to replace it with a more restrictive one, how do you delete UFW rules?
sudo ufw status numbered
A numbered list will be printed in your terminal window with all the user rules you have put in place (they can be found in /etc/ufw/user.rules)
Let's say the ports 27017 and 27019 are your net_authPort and net_queryPort and you see this in your terminal window (when a protocol is not specified in a rule ufw will allow both udp and tcp packets and block other protocols):
[ 5] 27017 ALLOW IN Anywhere [ 6] 27019 ALLOW IN Anywhere
now proceed to delete the old rules with these commands:
sudo ufw delete 5
(Repeat sudo ufw status numbered as now the order of the rules might have changed then delete what was the 6th rule)
Now that we have deleted the old rules let's restrict the access to the net_authPort and net_queryPort so that only the IP address of our machine can access that port:
sudo ufw allow from VPSIP to any port Game_port
Replace VPSIP with the IP address of you VPS and the game_port with the port of net_authPort and then repeat for the net_queryPort
Now you might think, what would have happened if I didn't bother deleting the old rules? UFW rules are applied in order! So if a packet comes in UFW will check the user's rules in the order printed by sudo ufw status numbered and when ufw finds the first rule that allows the packet to come in it will stop and allow the packet in (if there is a blocking rule afterwards it will be ignored! more on how to prevent this later).
Restrict amounts of packet an IP can send to the master port
I don't think the pluto devs have changed this, but basically it is known that a legitimate IP will send 2 bytes (of packets) to the master port every 10 seconds. The master port is a very vulnerable port and needs to be protected.
We will modify the before.rules found in /etc/ufw/before.rules I will use the nano editor to accomplish this.
The before rules are evaluated before the user rules (added via the command sudo ufw allow) so if you want to avoid messing with the order of the user rules you can modify the before.rules like I'm about to do.
sudo nano /etc/ufw/before.rules
Add these two lines after the *filter
*filter :ufw-http - [0:0] :ufw-http-logdrop - [0:0] (other default lines here) # End required lines
This is the interesting part, add these rules before the COMMIT line or they won't be processed:
# http -A ufw-before-input -p tcp --dport 80 -j ufw-http # https -A ufw-before-input -p tcp --dport 443 -j ufw-http # tekno master port (master server port) -A ufw-before-input -p tcp --dport (your master port here!) -j ufw-http # Limit connections per Class C -A ufw-http -p tcp --syn -m connlimit --connlimit-above 2 --connlimit-mask 24 -j ufw-http-logdrop # Limit connections per IP -A ufw-http -m state --state NEW -m recent --name conn_per_ip --set -A ufw-http -m state --state NEW -m recent --name conn_per_ip --update --seconds 1 --hitcount 1 -j ufw-http-logdrop # Limit packets per IP -A ufw-http -m recent --name pack_per_ip --set -A ufw-http -m recent --name pack_per_ip --update --seconds 1 --hitcount 2 -j ufw-http-logdrop # Finally accept -A ufw-http -j ACCEPT -A ufw-http-logdrop -j DROP COMMIT
What we did above was basically tell ufw to drop (reject without sending a notice to the source) any packets that don't satisfy these rules. Now your server is protected from most DDOS attacks, I didn't mention the net_port because it seems that no matter how hard it gets ddosed nothing much happens so let's just pretend it doesn't exist (bad advice probably).
Want to IP ban a player you hate a lot?
Open your before.rules again and add this rule (don't forget #comments or else ufw will not considerate a rule without an accompanying comment)
#Block XXX IP from XXX (or whatever notation you want to add) -A ufw-before-input -s IPAddressHere -j DROP
Again all the packets will drop, dropping means discarding a packet without telling the source, if you wish to send a response to the source about this refusal add -j REJECT instead of -j DROP but I do not recommend this.
If you have UFW logging set to low, all rejection should be logged and saved in /var/log/ufw.log so you can see there (again with nano) who's knocking on your server. You will find that older logs are compressed and their name is changed like ufw5.gz it will be tricky to access these logs as you are not the owner of these files (the mysterious syslog is the owner) so have fun with that.
Verify UFW rules are in place with this command:
sudo iptables -S sudo iptables --list
Your rules should appear somewhere in the sea of things that are going to be printed
Thanks for reading, leave feedback in the comments below, a friend (shoutout to Zombie if you are reading this) of mine gave me these rules and I thought I wrote a tutorial for the geeks out there.