• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

Linux Ubuntu + Nginx, simple/advanced DDOS protection

Joriku

Working in the mines, need something?
Joined
Jul 16, 2016
Messages
1,130
Solutions
15
Reaction score
425
Location
Sweden
YouTube
Joriku
Hi,
now sharing a DDOS solution for Nginx, this will not stop a major DDOS attack. However, it will stop or at least maintain an smaller / advanced one laid onto your server. ( It all depends on your servers capacity of handling data ), and can varry depending on circumstances.

You'll need to apply cloudflare to your server on your own accord, make sure to use strict mode for SSL requests.
To setup network load balancers to handle more powerful DDOS attacks: Ubutu Docs

Can you help me set this up?: click here

Q: Why can't this just solve any DDOS attack coming my way?
A: Here
And this

LUA:
# Ubuntu 24.04, Nginx running on port 57532
# Setup Cloudflare for extra protection (Not inside here, manual configuration needed!)
# Make kernel changes to add an extra limiter
# ICMP requests ( Ping ) is blocked out by:
# net.ipv4.icmp_echo_ignore_all = 1 ( Inside kernel changes )
---------------------------------------------------------------

# Set Default Policy to Deny Incoming Traffic
sudo ufw default deny incoming
sudo ufw default allow outgoing

# Allow Required TCP Ports
sudo ufw allow OpenSSH
sudo ufw allow "Nginx Full"  # Opens ports 80 and 443 for web traffic
sudo ufw allow 7171/tcp
sudo ufw allow 7172/tcp
sudo ufw allow 5753/tcp

# Apply Rate Limiting on SSH & Web Traffic
sudo ufw limit ssh/tcp  # Rate limits SSH login attempts
sudo ufw limit 80/tcp   # Limits HTTP traffic requests
sudo ufw limit 22/tcp   # Additional rate limiting for SSH

# Remove port 22, changed to other port
sudo ufw delete allow 22/tcp
sudo ufw delete limit 22/tcp

# Allow SSH on port 57532
# Has to be changed manually
sudo ufw allow 57532/tcp
sudo ufw limit 57532/tcp

# Reload UFW
sudo ufw reload

# Improve DDoS Protection with iptables
sudo iptables -A INPUT -p tcp --syn -m limit --limit 1/s --limit-burst 3 -j ACCEPT

# Block Invalid Packets
sudo iptables -A INPUT -m conntrack --ctstate INVALID -j DROP

# Prevent Ping-Based Attacks
sudo iptables -A INPUT -p icmp --icmp-type echo-request -m limit --limit 1/s --limit-burst 2 -j ACCEPT

# Persist (save) iptables Rules
sudo apt install iptables-persistent -y

# Save rules
sudo netfilter-persistent save

# What the above will not prevent completely:
1. Large-scale volumetric DDoS attacks (which flood your bandwidth).
2. Distributed attacks from multiple IPs (botnets) since UFW works at the OS level.
3. Application-layer DDoS (Layer 7) attacks, which overwhelm web servers with valid HTTP requests.

# Install Fail2Ban to mitigate attacks
sudo apt install fail2ban -y

# Create local configuration
cd /etc/fail2ban
head -20 jail.conf
sudo cp jail.conf jail.local

# Configure Fail2Ban rules for SSH, HTTP, and TCP ports
sudo nano /etc/fail2ban/jail.local

# Add these rules
# Comment out existing nginx-http-auth, or error will occur
[nginx-http-auth]
enabled = true
filter = nginx-http-auth
logpath = /var/log/nginx/access.log
maxretry = 10
findtime = 60
bantime = 600

[gameserver]
enabled  = true
port     = 7171,7172
filter   = gameserver   # You might need to create a custom filter that matches your server's log format
logpath  = /path/to/your/gameserver.log
maxretry = 10
findtime = 600
bantime  = 3600


# Restart Fail2Ban
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
sudo systemctl restart fail2ban

# Check status, in case of errors
sudo systemctl status fail2ban

---------------------------------------------------------------
# For Webpage

# Open your Nginx configuration file (modify based on your setup):
sudo nano /etc/nginx/sites-available/default

# Add these lines inside the server {} block:
limit_req_zone $binary_remote_addr zone=limit_zone:10m rate=10r/s;

server {
    listen 80;
    server_name yourwebsite.com;

    location / {
        limit_req zone=limit_zone burst=20 nodelay;
        try_files $uri $uri/ =404;
    }
}

# Restart Nginx
sudo systemctl restart nginx

# Block Bad Bots & Scrapers
sudo nano /etc/nginx/badbots.conf

# Add these lines:
if ($http_user_agent ~* (AhrefsBot|SemrushBot|MJ12bot|DotBot|Scrapy|HTTrack)) {
    return 403;
}

# Include it in Nginx config
sudo nano /etc/nginx/sites-available/default

# Add inside the server {} block:
include /etc/nginx/badbots.conf;

# Validate and restart Nginx
sudo nginx -t
sudo systemctl restart nginx

---------------------------------------------------------------
# Kernel Tweaks to Mitigate DDoS Attacks on Ubuntu 24.04

# Edit the sysctl.conf File
sudo nano /etc/sysctl.conf

# Add or modify these lines:
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_max_syn_backlog = 2048
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_syn_retries = 2
net.ipv4.tcp_max_orphans = 5000
net.ipv4.tcp_rfc1337 = 1
net.ipv4.icmp_echo_ignore_broadcasts = 1
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.icmp_echo_ignore_all = 1 # ICMP block
net.ipv4.icmp_ratelimit = 100
net.ipv4.icmp_ratemask = 88089
net.ipv4.tcp_invalid_ratelimit = 500
net.ipv4.neigh.default.gc_thresh1 = 128
net.ipv4.neigh.default.gc_thresh2 = 512
net.ipv4.neigh.default.gc_thresh3 = 1024
net.ipv4.tcp_fastopen = 3

# Apply the changes
sudo sysctl -p

# Make the Changes Persistent
sudo sysctl --system

---------------------------------------------------------------
# Limit traffic over 7171/7172 (Optimized for Game Server)

sudo iptables -A INPUT -p tcp --dport 7171 -m state --state NEW \
  -m hashlimit --hashlimit 30/s --hashlimit-burst 60 \
  --hashlimit-mode srcip --hashlimit-name gameport_7171 -j ACCEPT

sudo iptables -A INPUT -p tcp --dport 7172 -m state --state NEW \
  -m hashlimit --hashlimit 30/s --hashlimit-burst 60 \
  --hashlimit-mode srcip --hashlimit-name gameport_7172 -j ACCEPT

# Prevent excessive SYN floods
sudo iptables -A INPUT -p tcp --syn --dport 7171 -m limit --limit 10/s --limit-burst 20 -j ACCEPT
sudo iptables -A INPUT -p tcp --syn --dport 7172 -m limit --limit 10/s --limit-burst 20 -j ACCEPT

# Save iptables rules
sudo iptables-save | sudo tee /etc/iptables/rules.v4

# Restart Services
sudo systemctl restart systemd-networkd

---------------------------------------------------------------
# If UFW isn't working to display
sudo apt update && sudo apt install ufw -y
sudo ufw enable
sudo ufw status verbose

Server Block
Change out yourdomainname by using notepad++ or do a manual exchange

This will also require an SSL to be active onto the domain you're trying to apply, do that before you exchange to using this block.
LUA:
nnlimit_req_zone $binary_remote_addr zone=one:10m rate=10r/s;

server {
    if ($host = www.yourdomainname) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    if ($host = yourdomainname) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    listen 80;
    listen [::]:80;
    server_name yourdomainname www.yourdomainname;

    # Redirect all HTTP traffic to HTTPS
    return 301 https://$host$request_uri;




}

# Redirect IPv4 and IPv6 requests to the domain over HTTPS
server {
    listen 80;
    listen [::]:80;
 
    listen 443 ssl;
    listen [::]:443 ssl;

    server_name youripv4;

    ssl_certificate /etc/letsencrypt/live/yourdomainname/fullchain.pem;  # Managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/yourdomainname/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    return 301 https://yourdomainname$request_uri;
}

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    server_name yourdomainname www.yourdomainname;

    root /var/www/yourdomainname;
    index index.php;

    # SSL configuration
    ssl_certificate /etc/letsencrypt/live/yourdomainname/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/yourdomainname/privkey.pem; # managed by Certbot
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    # Block bad bots & scrapers
    include /etc/nginx/badbots.conf;

    # Increase max file upload
    client_max_body_size 10M;

    # Prevent access to logs, system files, etc.
    location ~ /system {
        deny all;
    }

    # Block sensitive files
    location ~\.(ht|md|json|dist)$ {
        deny all;
    }

    # Block git files and folders
    location ~ /.git {
        deny all;
    }

    # UFW simple DDOS prevention
    location / {
        limit_req zone=one burst=30 nodelay;
        try_files $uri $uri/ /index.php?$query_string;
    }

    # PhpMyAdmin security
    # Change the location towards your setup or remove this part
    location /phpmyadmin {
        auth_basic "Restricted Access";
        auth_basic_user_file /etc/nginx/.htpasswd;
    }

    # Do not limit CSS, JS, Images
    location ~* \.(?:css|js|jpg|jpeg|png|gif|ico|woff2|woff|ttf|svg|eot)$ {
        expires max;
        log_not_found off;
    }

    # Limit requests only for PHP files (avoid affecting CSS/JS)
   # Change the PHP version to match yours.
    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_read_timeout 240;
        fastcgi_pass unix:/var/run/php/php8.3-fpm.sock;

        limit_req zone=one burst=20 nodelay;
    }



}

If you have knowledge in the area, feel free to comment downbelow for upgrades and/or suggestions.
 
Last edited:
Update:
You can play around with the limitation.
I changed the limits, due to restrict access of entrance onto the game from the character menu.

You can try tighten the limiter, however. I put it up to avoid player restricted access onto the game. On repeat, this can be changed to tighten the limits a bit more, keep this in mind while using this setup.

The tighter the limiter, the better. Just be careful while making it tighter since it can restrict an entry for the player.
If a player spams the game, they have to await a ticker to be gone before they are allowed a new connection ( usually 60 seconds before a new tick/thread is allowed/removed )

In short words, the tighter the better. The more data it can restrain, making it harder for a DDOS to occur.

If you guys want a cloudflare settings update, let me know.
 
Update #2, move over from UFW at all. In the future, I'll post up a fully updated version of this.
Meanwhile, you can move over your own traffic fully from UFW -> Iptables.
 
Back
Top