Tutorial Custom IPTables for Debian

ikfes

Member
Joined
Apr 15, 2016
Messages
62
Points
40
Age
26
Reference thread to my original post @ https://stresserforums.net/showthread.php?tid=132

I've only ran this on Debian 7, so while this might work on other systems, I will not give any guarantees on it.
For example, the log messages might bug on Ubuntu systems.
This should be run along with DDoS Protected network. This script acts only as a secondary layer of defence. By no means this script alone will block DDoS attack.
You should have network level protected system for this to have any meaningful effect. If you don't have network level protection of any kind, at most this will be able to block attacks which are equal or bellow your advertised port speed.

Most (if not all) firewall guides about "blocking DDoS attacks with iptables" use the filter table and the INPUT chain for Anti-DDoS rules. The issue with this approach is that the INPUT chain is only processed after the PREROUTING and FORWARD chains. This causes a delay in the filtering of the packet which consumes resources.The first chain that can apply to a packet is the PREROUTING chain, so ideally we'll want to filter the bad packets in this chain already. In this script we'll be filtering in PREROUTING and allowing in INPUT chain.

The most obvious upsides of this guide is the fact, there is no connection tracking in these rules which reduce CPU load during the attack and instead of "DENY" rules which sends an rejection message back to the attacker for each packet, we will be using "DROP" which does not bother answering to the attacker and thus wasting your already precious bandwidth and CPU power.

Using a "DENY" rules in a firewall script is the most retarded thing ever when expecting DDoS attacks.


Code:
# Flush rules
iptables -F
iptables -X
iptables -t nat -F
iptables -t nat -X
iptables -t mangle -F
iptables -t mangle -X
iptables -t raw -F PREROUTING
iptables -t raw -F OUTPUT
# List policies first
iptables -P INPUT DROP; iptables -P FORWARD DROP; iptables -P OUTPUT ACCEPT;
# Disable connection tracking on voice server ports
iptables -A PREROUTING -t raw -p udp --dport 9987 -j NOTRACK
iptables -A OUTPUT -t raw -p udp --sport 9987 -j NOTRACK
# Allow TCP (SSH, FTP, SFTP) inbound
iptables -A INPUT -p tcp -m state --state NEW -m multiport --dports 21,22 -j ACCEPT
# Drop invalid UDP (UDP packet with a total size less than 28 bytes is never legit.)
iptables -A PREROUTING -t raw -p udp --dport 9987 -m length --length 0:32 -j DROP
iptables -A PREROUTING -t raw -p udp --dport 9987 -m length --length 2521:65535 -j DROP
# Drop *some* TS3 booter methods *I* experienced.
iptables -A PREROUTING -t raw -p udp --dport 9987 -m string --hex-string '|fa163eb402096ac8|' --algo kmp -j DROP
iptables -A PREROUTING -t raw -p udp --dport 9987 -m string --hex-string '|71f63813d5422309|' --algo kmp -j DROP
# Allow incoming packets related to outgoing ones.
iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
# Allow some TS3 inbound traffic (9987=TS3 Virtualserver 1, 30033=TS3 Fileserver[icons,etc], 10011=TS3 Queryport)
iptables -A INPUT -p udp --dport 9987 -j ACCEPT
iptables -A INPUT -p tcp --dport 30033 -j ACCEPT
iptables -A INPUT -p tcp --dport 10011 -j ACCEPT
# Allow ICMP
iptables -A INPUT -p icmp -j ACCEPT
# Log all dropped packets to /var/log/messages
iptables -N LOGGING
iptables -A INPUT -j LOGGING
iptables -A LOGGING -m limit --limit 2/min -j LOG --log-prefix "IPTables-Dropped: " --log-level 4
iptables -A LOGGING -j DROP
Paste the above to: firewall.sh file with nano or vi
run the firewall.sh file as root with command: "./firewall.sh"

The above script (as it is) only allows SSH 22 and FTP 21, and TS3 ports by default.
Any additional service/port has to be allowed manually in the rules.


How to block a new DDoS attack and add it to existing firewall script:
1. During a DDoS attack, run "tcpdump -s 0 -i eth0 -w dump.pcap" (Note: your network interface can be something else than eth0, such as ens18, venet0:0 and so on, depending on your system. check it by running ifconfig)
2. Your machine is now recording all incoming and outgoing traffic to a .pacp file that can be downloaded and opened with wireshark.
3. Verify that your dump.pcap file is at least several megabytes.. (1-3 is the usual amount, but can be higher too). If it's any lower, you likely missed the attack as you started recording too late. (or too early if youre the one attacking your own server)
4. Download dump.pcap and open it with wireshark on your local computer.
Here is an example of what you might find inside:

This is normal traffic between the server and the users.
https://i.gyazo.com/8f56ee362e4cd92d7bf92147e9a5ca2f.png

After that starts the obvious pattern which lasts till the end.
https://i.gyazo.com/572580a1a3707540fe5a9570dda4a31a.png
Looking closely you can see that the length of this invalid UDP packet is 34

Counting up the header, the total length would be 62
https://i.gyazo.com/b3dc2a22734d29a631e4e6264ebd8205.png

What you can do now is to drop UDP packets by length or drop them more accurately by hex.
Theres upside and downside on both.

Dropping packets by length takes no CPU power but there can be false positives if some legit traffic happens to have exact same packet length later on as the one you have blocked before because of an attack.
Dropping packets by hex drops the packets based on their payload. This is more CPU heavy as it has to search for the hex value in every packet. But also very accurate with zero false positives that could result into packet loss in TS3.

If you want to drop the above example by length, simply add:

Code:
iptables -A PREROUTING -t raw -p udp --dport 9987 -m length --length 62 -j DROP
under "Drop invalid UDP" section of the script above.

If you want to drop by hex, you have to search for the hex value of the DDoS packet. (Usually all DDoS traffic has the exact same hex)

In this case:

https://i.gyazo.com/49eeb9b2902e712e12e6a8452259f45a.png
Which is basically: "545333494e495431006500008802fd66d30"

We can shorten the hex to a rule:

Code:
iptables -A PREROUTING -t raw -p udp --dport 9987 -m string --hex-string '|545333494e4954310|' --algo kmp -j DROP
which can be added under "TS3 booter methods" of the script for example.

Also, do not short the hex value too much or it will generate false positives. If it's too long, it will eat all the CPU.
Generally the rule is: Shorter hex == less CPU heavy filtering but more false positives, while longer hex == more CPU heavy filtering but less false positives.
From original hex of:
545333494e495431006500008802fd66d30
Shortening it to:
545333494e4954310
Is generally in area where it's long enough to leave zero chances for false positives (the chance of some other person having exact same hex later on) but still short enough to be CPU friendly during DDoS.
If I used the full string, it my server would certainly lag out, while if I used only 5 numbers of the hex, there could begin to happen random packet loss and connection issues in normal everyday usage.
 
Last edited:

Obada

Member
Joined
Jun 5, 2016
Messages
3
Points
33
Age
24
iptables -A PREROUTING -t raw -p udp --dport 9987 -m length --length 62 -j DROP
For this command line, i need to ask if the packet length is more than 62 will be drop or not? i mean if the length is 66 this packet will be drop and any small packet will pass?
 

ikfes

Member
Joined
Apr 15, 2016
Messages
62
Points
40
Age
26
For this command line, i need to ask if the packet length is more than 62 will be drop or not? i mean if the length is 66 this packet will be drop and any small packet will pass?
It will only drop udp packets with total length 62 to port 9987. Not anything else.
 

Top