How to protect against a DDOS
In order to block a distributed denial of service DDOS attack you have several ways to go about it.
1) Block the requests at the reverse proxy level
You can stop a DDOS attack at the the application layer depending on your stack. If you’re running a kubernetes cluster on bare metal with haproxy as an ingress it should be able to drop the incoming traffic according to their website
For more traditional setups however, you can’t really stop such an attack at the application layer. You could at most thottle requests so that a script gets a 403 when it calls your api 10 times per second but that’s about it. The traffic made it all the way through your firewall, your proxmox host who then acting as a layer 2 switch, sets up a bridge to your virtual machine VM who then forwards the traffic to your reverse proxy.
You could prevent your website from being queried with curl or wget but those can easily be bypassed by changing the user agent. Additionally you won’t actually be blocking anything in this case since your web server will still try to reply to every incoming request.
2) Block the requests at the hypervisor level
If your proxmox is nating the traffic to your machine you might be able to drop requests coming from IPs that try to flood your site. But since i’ve set up the web server in a VM who is connected to the host as a bridge I won’t be able to see the traffic with iptables and apply custom rules.
3) Block the requests at the VM level
Yes, you can limit the requests by dropping some of them by using the ip table rule below. But then again, the traffic made it all the way through your firewall, your proxmox host who then forwarded the traffic to your VM. Even if you drop most of the requests at the VM level before they reach your web server, you will still experience slowness
1
2
3
4
5
6
7
8
9
10
11
12
13
root@tutorial:$ iptables -N DDOS_PROTECT
root@tutorial:$ iptables -I DOCKER-USER -p tcp --dport 80 -m state --state NEW -j DDOS_PROTECT
root@tutorial:$ iptables -I DOCKER-USER -p tcp --dport 443 -m state --state NEW -j DDOS_PROTECT
root@tutorial:$ iptables -A DDOS_PROTECT -m recent --name bad_conn --set
root@tutorial:$ iptables -A DDOS_PROTECT -m recent --name bad_conn --update --seconds 10 --hitcount 20 -j DROP
root@tutorial:$ apt install iptables-persistent
root@tutorial:$ iptables-save | sudo tee /etc/iptables/rules.v4
root@tutorial:$ ip6tables-save | sudo tee /etc/iptables/rules.v6
This should make the rules persistent. The iptables-persistent daemon should load the rules like this on every boot:
1
2
root@tutorial:$ iptables-restore < /etc/iptables/rules.v4
root@tutorial:$ ip6tables-restore < /etc/iptables/rules.v6
4) Block the requests at the firewall level
In pfsense go to Firewall>Rules>and edit the NAT rules that forward the traffic to the VM. I’ve simply set the “Max. connections” parameter to 10 and it does the job by blocking the requests from ever entering your network.
5) Use a cloud proxy
Instead of NAT-ing the traffic to your web server you could simply set up your own vpn that routes the internet traffic into a cloud instance first and then routes it to your web server. Cloud providers have ways to detect those attacks and will simply ban the perpetrator’s IP. This solution has the advantage of hidding the real IP address of your servers as well.
If you’re extremely lazy you could even use cloudflare as a CDN/reverse proxy but i’m not sure it’s free.