Linux - NetworkingThis forum is for any issue related to networks or networking.
Routing, network cards, OSI, etc. Anything is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
My servers is constantly getting hit by a DDoS using random source ports, and spoofed addresses. The DDoS consist of empty packets, length 60.
The server is hosted with OVH, and their so called "DDoS protection" is proving useless in this matter. The attack is 50 Mbit, and is not even picked up by their systems.
I was hoping that some good old IPTables could sort it for me
If anybody can help me write a firewall that I can put on all my servers, that you will occasionally help me with.
Please contact me in a PM, and we can figure something out. At this point I am willing to pay.
The server is hosted with OVH, and their so called "DDoS protection" is proving useless in this matter. The attack is 50 Mbit, and is not even picked up by their systems.
I was hoping that some good old IPTables could sort it for me
How would an iptables ruleset prevent an attacker from using a botnet to send vast amounts of traffic in your direction?
There are two things to consider when dealing with these types of (D)DoS attacks:
The strategy of the attacker is simply to use up all available bandwidth at your end, thus preventing legitimate requests from reaching your servers
The attacker does not care if your servers respond or not
In short, there's nothing you can do at your end to reduce the effectiveness of these attacks. Once the packets arrive at your server, bandwidth has already been consumed. What your servers choose to do with the traffic is of no consequence.
DDoS attacks must be filtered upstream. A relatively simple access list on as router might do the job. You need to speak with your hosting provider (again).
How would an iptables ruleset prevent an attacker from using a botnet to send vast amounts of traffic in your direction?
There are two things to consider when dealing with these types of (D)DoS attacks:
The strategy of the attacker is simply to use up all available bandwidth at your end, thus preventing legitimate requests from reaching your servers
The attacker does not care if your servers respond or not
In short, there's nothing you can do at your end to reduce the effectiveness of these attacks. Once the packets arrive at your server, bandwidth has already been consumed. What your servers choose to do with the traffic is of no consequence.
DDoS attacks must be filtered upstream. A relatively simple access list on as router might do the job. You need to speak with your hosting provider (again).
It's only 50 Mbit, I dont want to block the traffic. I wish to block the traffic from reaching the application and thereby crashing it.
It should indeed be possible to block it, like block anything but the port we expect to reach it.
Legit traffic comes by port 27005, the theirs are random. Is there a way to only allow a specific source port to reach the destination port?
I think of this as being a more targeted, probably somewhere in the range of a layer 7 attack.
EDIT: be cautious when trying to match source ports though. If the user is using a web browser, there's a excellent chance that 20000 is not the source port as web browsers choose random ports on outbound connections.
If a 50 Mbps attack still leaves sufficient free bandwidth for the application in question, and the problem is that the attack brings the server and/or application to a standstill then yes, an iptables rule should help.
For both UDP and TCP, random source ports are the norm. Unless the client process is bound to a specific port (and it rarely is), the IP stack will simply pick a free port from withing the "high" (>1023) range whenever a packet needs to be sent (UDP) or a session is to be initiated (TCP). Unless you're absolutely certain that legitimate traffic should come from a specific port, blocking certain source ports is likely to cause problems.
An iptables rule for blocking a specific UDP source port would look like this:
Code:
iptables -t filter -A INPUT -p udp --dport your_application_port --sport port_number -j DROP
Of course, if only one specific source port is ever involved, it would make more sense to allow that single port and filter the rest:
Code:
iptables -t filter -A INPUT -p udp --dport your_application_port --sport fixed_source_port -j ACCEPT
iptables -t filter -A INPUT -p udp --dport your_application_port -j DROP
Note that I used the "-A" (add) parameter in the examples above. That will add a rule to the bottom of any existing ruleset, something that might not yield the desired results if a rule further up the chain actually allows the traffic in question.
If your ruleset is currently blank, the rules above will work as they stand. If you already have a ruleset, you will need to insert the above rules in the correct place. You could also test the rules by inserting them at the top of the existing ruleset; replace the first "-A" with "-I 1" (insert at position 1) and the second with "-I 2".
(I haven't really looked at your hex dumps, since I'd have to paste the data into a hex editor and then somehow convert that into a capture file. If you could dump the offending traffic to a capture file with tcpdump and either post it here or make it available online, I could have a closer look.)
You can set policies with -F. It will accept either DROP or ACCEPT
Code:
iptables -P INPUT DROP
Something like this:
Code:
iptables -F INPUT DROP
iptables -A INPUT -p udp --sport 27005 --dport 27035 -j ACCEPT
will only permit udp packets coming from port 27005, heading to port 27035 (from any ip to any ip) to be accepted.
If the OP doesn't currently have an iptables ruleset, the above policy and rule will prevent the server from doing anything other than serving incoming requests on that specific UDP port. Absolutely nothing else will work, including DNS lookups, remote administration, downloading of updates etc. etc.
If a 50 Mbps attack still leaves sufficient free bandwidth for the application in question, and the problem is that the attack brings the server and/or application to a standstill then yes, an iptables rule should help.
For both UDP and TCP, random source ports are the norm. Unless the client process is bound to a specific port (and it rarely is), the IP stack will simply pick a free port from withing the "high" (>1023) range whenever a packet needs to be sent (UDP) or a session is to be initiated (TCP). Unless you're absolutely certain that legitimate traffic should come from a specific port, blocking certain source ports is likely to cause problems.
An iptables rule for blocking a specific UDP source port would look like this:
Code:
iptables -t filter -A INPUT -p udp --dport your_application_port --sport port_number -j DROP
Of course, if only one specific source port is ever involved, it would make more sense to allow that single port and filter the rest:
Code:
iptables -t filter -A INPUT -p udp --dport your_application_port --sport fixed_source_port -j ACCEPT
iptables -t filter -A INPUT -p udp --dport your_application_port -j DROP
Note that I used the "-A" (add) parameter in the examples above. That will add a rule to the bottom of any existing ruleset, something that might not yield the desired results if a rule further up the chain actually allows the traffic in question.
If your ruleset is currently blank, the rules above will work as they stand. If you already have a ruleset, you will need to insert the above rules in the correct place. You could also test the rules by inserting them at the top of the existing ruleset; replace the first "-A" with "-I 1" (insert at position 1) and the second with "-I 2".
(I haven't really looked at your hex dumps, since I'd have to paste the data into a hex editor and then somehow convert that into a capture file. If you could dump the offending traffic to a capture file with tcpdump and either post it here or make it available online, I could have a closer look.)
Yeah, seems like "most" traffic is from a specific source port, however some connections are from random ports..
I sent you a tcpdump in PM.
Edit: I tried to do so.
Last edited by Skidprevention; 02-22-2015 at 09:14 AM.
Sounds like this might be a job for u32. Assuming a header length of 40 bytes, the following rule should reject any packets where the first 8 bytes of the payload are zero (warning: untested):
Code:
iptables -t filter -A INPUT -p udp --dport 27035 -u32 --u32 "40&0xffff=0x0 && 44&0xffff=0x0" -j DROP
The filter syntax for u32 is "start_byte&mask_value=result", where & indicates a logical AND operation between the 32-bit word and the 32-bit mask. Multiple filter conditions can be specified with &&.
Sounds like this might be a job for u32. Assuming a header length of 40 bytes, the following rule should reject any packets where the first 8 bytes of the payload are zero (warning: untested):
Code:
iptables -t filter -A INPUT -p udp --dport 27035 -u32 --u32 "40&0xffff=0x0 && 44&0xffff=0x0" -j DROP
The filter syntax for u32 is "start_byte&mask_value=result", where & indicates a logical AND operation between the 32-bit word and the 32-bit mask. Multiple filter conditions can be specified with &&.
Looks like that for some reason, one cannot use both "-p" and "-u32" in the same rule. To match UDP packets to a specific destination port, additional u32 filters must be created.
Try the rule without the "-p udp --dport 27035" part. It'll still only match packets with a 8-byte sequence of zeros at offset 40. I'll get back to you with an updated filter.
Edit: Try this:
Code:
iptables -t filter -A INPUT -m u32 --u32 "0&0xf000=0x4000 && 6&0x00ff=17 && 0>>22&0x3C@0&0xFFFF=27035 && 0>>22&0x3C@8&0xffff=0x0 && 0>>22&0x3C@12&0xffff=0x0" -j DROP
This first filter checks for IPv4 (there's a surprising amount on link-local IPv6 activity in many networks), the next checks for protocol number 17 (UDP), and the third filter will match destination port 27035.
I've altered the filter to take into account the (very remote) possibility that the IPv4 header may have a non-standard length.
Edit 2: The error message from the command in my previous post was somewhat misleading. As it happens, it was just a syntax error. One can indeed combine u32 with other match mechanisms, so this will also work:
Code:
iptables -t filter -A INPUT -p udp --dport 27035 -m u32 --u32 "0>>22&0x3C@8&0xffff=0x0 && 0>>22&0x3C@12&0xffff=0x0" -j DROP
Looks like that for some reason, one cannot use both "-p" and "-u32" in the same rule. To match UDP packets to a specific destination port, additional u32 filters must be created.
Try the rule without the "-p udp --dport 27035" part. It'll still only match packets with a 8-byte sequence of zeros at offset 40. I'll get back to you with an updated filter.
Edit: Try this:
Code:
iptables -t filter -A INPUT -m u32 --u32 "0&0xf000=0x4000 && 6&0x00ff=17 && 0>>22&0x3C@0&0xFFFF=27035 && 0>>22&0x3C@8&0xffff=0x0 && 0>>22&0x3C@12&0xffff=0x0" -j DROP
This first filter checks for IPv4 (there's a surprising amount on link-local IPv6 activity in many networks), the next checks for protocol number 17 (UDP), and the third filter will match destination port 27035.
I've altered the filter to take into account the (very remote) possibility that the IPv4 header may have a non-standard length.
Edit 2: The error message from the command in my previous post was somewhat misleading. As it happens, it was just a syntax error. One can indeed combine u32 with other match mechanisms, so this will also work:
Code:
iptables -t filter -A INPUT -p udp --dport 27035 -m u32 --u32 "0>>22&0x3C@8&0xffff=0x0 && 0>>22&0x3C@12&0xffff=0x0" -j DROP
That blocked way too much, it ended up freezing players and making them unable to connect.
Is there any way, that you can be contacted more directly?
The challenge here is to find a fingerprint that matches the DDoS packets while at the same time excludes all legitimate traffic. It seems that checking the first 8 bytes of the payload for zeroes wasn't specific enough. I guess you could add a few more checks for consecutive zeroes:
...or find a specific byte in a legitimate packet that is guaranteed to always be non-zero (or perhaps even to have a specific value) and check for that specifically.
I think you need to look more closely at the application traffic.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.