Firstly, I do not claim to be good at firewalls, DDoS protection or networking in general.
But I wrote a decent set of rules which worked for DoM.
firewall.sh contains iptables rules for blocking common attacks and rate-limiting game ports.
ipset_example.sh contains an example usage of an ipset, how to create one and how to add ips to it.
LoginExample.cs contains appEngine code for the login request, which has been modified to whitelist IPs and remove unused IPs.
- Know how to navigate your server source
- Know how packets work on your server
- Know how to use a Linux VPS (I used Ubuntu)
- Know a little bit of bash scripting
This script simply won't work for you if you don't do these changes.
This script rate-limits incoming packets at a rate of 40/second. This rate is VERY low for a standard private server.
From my tests, you can easily achieve 600 packets/sec with high dex and multiple enemies on screen.
All because every time a player shoots, hits an enemy, etc the packets are sent to server instantly. You might think this is good because there won't be a delay...
But in reality the server doesn't process them instantly, instead they are all queued and processed on next server tick (how it should be).
Sending 600 packets every second is also incredibly innefficient, because every TCP packet has 40 bytes appended to it with TCP flags, so your average EnemyHit packet is not 8 bytes total, but 48!
And the final problem, rate-limiting becomes near impossible with this kind of instability. A normal player may send 600 packets, and the DDoSer may send 600.
Rewrite packets which are sent to server very frequently, to instead be queued on client and only sent when client receives NewTick packet.
This way you are sending one large packet every server tick instead of hundres of small ones.
You have to rewrite the following packets:
- PlayerShoot
- PlayerHit
- EnemyHit
- Any other hits you may have (minions? static objects)
- Make sure your VPS has iptables turned on and other firewalls turned off (like ufw).
- Remove any existing rules you may have in iptables before running this. (I explain how to do that at the bottom of the script)
- This script only covers IPv4, if your system has IPv6 enabled, you might want to disable it or write a script using ip6tables.
- Ensure that Redis is not bound to
0.0.0.0in its config (bind127.0.0.1)
This script whitelists 2 ports: 2050 and 2051, for wServer and appEngine respectively.
You have to change them to the ports that your server is using.
If you have RDP set up on your VPS, uncomment this line and set your IP, so you don't get disconnected after running this.
#iptables -A INPUT -p tcp --dport 3389 -s <YOUR IP> -j ACCEPT # RDPYou need this package installed, for your iptables rules to be saved after system restarts.
Don't do this if you haven't tested the rules yet. You might want the rules to get deleted when you reboot the machine if something goes wrong.
sudo apt install netfilter-persistentTo save rules simply run:
sudo netfilter-persistent save
sudo netfilter-persistent reloadDownload the file and grant permissions to it.
sudo chmod +x ./firewall.shThen simply run it
sudo ./firewall.shYou can have a system which whitelists specific IP addresses, and only those would be allowed to connect to the game server.
This repository has an additional script ipset.sh which explains how to do something like that efficiently.
With the use of ipsets, you can make port for wServer closed by default, and only accessed to whitelisted IPs.
Inside of appEngine, every time someone logs into an account, you will add their IP to the whitelist, so they can connect to the game properly.
This will make it so your wServer doesn't crash from the sheer amount of Clients it creates during SYN Flood attacks.
Check out the example file for how this system could look like: LoginExample.cs
I recommend in addition to this, making a restriction, where one account can only have one IP whitelisted, to prevent abuse.
I also recommend rate-limiting registering of accounts, for this system to be even stronger against abuse.
And on unrelated note, if you haven't already, rate-limit logging into accounts, to prevent bruteforcing.
There is a commented set of rules in the script which rate-limits connections which send too much data in a short period of time.
I haven't done enough testing with this to find good rate-limiting, and this is completely unnecessary currently.
If you want to add that to your firewall, you have to learn about packet fragmentation and do extensive testing on your server.
This script doesn't have any rules for outbound connections, which you can add as well to further protect your system.
But that would effectively only restrict yourself in what actions you can do on the system, it wouldn't directly protect you from DDoS attacks.
If you are an OVH customer, you can add some rules to your server which will filter packets before they even reach your server.
To access the firewall, go to your Dashboard, click on your server. Then:
- Click Network tab on the left panel
- Click IP
- Find your server in the list, click on three dots to the right of it
- Click "Edge Network Firewall configuration"
This is the setup that I use:
This firewall doesn't let you do anything advanced unfortunately, so you are basically only accepting specifics ports, and blocking everything else.
By default this Firewall is off, and only gets turned on when OVH detects a DDoS attack on your server. I have it always turned on.
