[Linux UFW] Protect master port against DDOS attacks

Topic created · 1 Posts · 29 Views
  • 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.

    Enable UFW:
    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).

    Disable IPV6
    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?
    Type:

    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.
    Type

    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).

    BONUS TUTORIAL
    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.

Log in to reply