Linux - SecurityThis forum is for all security related questions.
Questions, tips, system compromises, firewalls, etc. are all included here.
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 have been victim of what I think is a Syn flood attack. All my servers have gigabit connections but at one moment I saw about 2 - 3 mB/s coming in and the entire server became unresponsive. I couldn't even SSH anymore into the server and even typing through KVM didn't work.
My firewall logs showed a lot of IP addresses which are probably all spoofed?
Now, I've been trying to block these attacks by using various iptables scripts found with Google, but none of them seem to work and I don't even know if it's really a syn flood attack. I have syncookies enabled in the kernel, I tried running floodmon but all without success.
Anybody know how to deal with these type of attacks? Thanks!
The source and destination ports are always the same, 1234 to 80, I replaced my IP btw with a fake one:
that should take care of any TCP traffic with source port 1234 and destination port 80 for now. You should however block invalid traffic and limit traffic some more. Regardling the latter I just posted some iptables rules here (do adapt to ports in use) and apparently my remark about not using any kludges seemed right on the mark... Also please be aware there's only so much an end point can manage: do discuss with your provider.
that should take care of any TCP traffic with source port 1234 and destination port 80 for now. You should however block invalid traffic and limit traffic some more. Regardling the latter I just posted some iptables rules here (do adapt to ports in use) and apparently my remark about not using any kludges seemed right on the mark... Also please be aware there's only so much an end point can manage: do discuss with your provider.
Thanks for this! I'll add the rule see if it works. The thing is, these servers run game servers and only use UDP (except for SSH). I am blocking all traffic except for the UDP game server ports, so how come an attack on port 80 is still working? Is it because connection tracking is overloading the machine? In that case can I just change your rule to apply it to all ports except 22? (or some other port I run SSH on).
You're right it's a SYN flood. Different IPs sending tons of SYNs per second, that also have the same TTL and same source port, and the IPID field is slowly increasing. It's certainly possible it's a single host flooding rather than many zombies. This one could be pretty easy to stop using the filter unspawn has given you. Unfortunately, it is likely also easy for the attacker to change source ports so you'd have to create a new rule.
so how come an attack on port 80 is still working? Is it because connection tracking is overloading the machine?
I don't like speculating or guessing so you best post your rule set as in 'iptables-save > /some/file.txt' then post the contents between [code]vBB code tags[/code] or attach as plain text file.
I don't like speculating or guessing so you best post your rule set as in 'iptables-save > /some/file.txt' then post the contents between [code]vBB code tags[/code] or attach as plain text file.
Thanks for your help I really appreciate it! Here's my output:
Code:
# Generated by iptables-save v1.4.7 on Sun Sep 23 18:56:51 2012
*raw
:PREROUTING ACCEPT [201945564:180966096462]
:OUTPUT ACCEPT [38746979:25310771882]
-A PREROUTING -p tcp -m tcp --sport 1234 --dport 80 -j NOTRACK
-A PREROUTING -p tcp -m tcp --sport 1234 --dport 80 -j DROP
COMMIT
# Completed on Sun Sep 23 18:56:51 2012
# Generated by iptables-save v1.4.7 on Sun Sep 23 18:56:51 2012
*filter
:INPUT DROP [28374:2225410]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
:syn_flood - [0:0]
-A INPUT -s 204.188.252.0/24 -p tcp -m state --state NEW -m tcp --dport 27015 -j ACCEPT
-A INPUT -s 84.26.143.0/32 -p tcp -m state --state NEW -m tcp --dport 27015 -j ACCEPT
-A INPUT -s 213.247.35.0/24 -p tcp -m state --state NEW -m tcp --dport 27015 -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -j syn_flood
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -p udp -m state --state NEW -m udp --dport 27015 -j ACCEPT
-A INPUT -s 213.247.35.0/24 -p tcp -m state --state NEW -m tcp --dport 3306 -j ACCEPT
-A INPUT -s 216.185.114.0/24 -p tcp -m state --state NEW -m tcp --dport 3306 -j ACCEPT
-A INPUT -s 204.188.252.0/24 -p tcp -m state --state NEW -m tcp --dport 3306 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 27015 -m limit --limit 1/min --limit-burst 1 -j LOG --log-prefix "SRCDS-RCON "
-A INPUT -p tcp -m tcp --dport 27015 -j DROP
-A INPUT -p udp -m udp --dport 27015 -m length --length 0:32 -m limit --limit 1/min --limit-burst 1 -j LOG --log-prefix "SRCDS-XSQUERY " --log-ip-options
-A INPUT -p udp -m udp --dport 27015 -m length --length 0:32 -j DROP
-A INPUT -p udp -m udp --dport 27015 -m length --length 2521:65535 -m limit --limit 1/min --limit-burst 1 -j LOG --log-prefix "SRCDS-XLFRAG " --log-ip-options
-A INPUT -p udp -m udp --dport 27015 -m length --length 2521:65535 -j DROP
-A INPUT -p udp -m state --state NEW -m hashlimit --hashlimit-upto 1/sec --hashlimit-burst 3 --hashlimit-mode srcip --hashlimit-name StopDoS -j ACCEPT
-A INPUT -p udp -m limit --limit 1/min --limit-burst 1 -j LOG --log-prefix "UDP-SPAM " --log-ip-options
-A INPUT -p udp -j DROP
-A INPUT -j LOG --log-prefix "IN_LEFTOVERS "
-A OUTPUT -j ACCEPT
-A syn_flood -m limit --limit 1/sec --limit-burst 3 -j RETURN
-A syn_flood -j DROP
COMMIT
# Completed on Sun Sep 23 18:56:51 2012
Indeed odd since you have a filter table INPUT chain DROP policy. I have no explanation for it.
*BTW since your focus is on HLDS / UDP/27015, maybe this rule order is more efficient:
Code:
*raw
:PREROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
-A PREROUTING -m udp -p udp --dport 27015 -m length --length 0:32 -j DROP
-A PREROUTING -m udp -p udp --dport 27015 -m length --length 2521:65535 -j DROP
-A PREROUTING -m tcp -p tcp --sport 1234 --dport 80 -j NOTRACK
COMMIT
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -i lo -j ACCEPT
-A INPUT -m conntrack --ctstate ESTABLISHED -j ACCEPT
-A INPUT -m conntrack --ctstate INVALID -j DROP
-A INPUT -m conntrack --ctstate NEW -m udp -p udp --dport 27015 -j ACCEPT
-A INPUT -m conntrack --ctstate NEW -m tcp -p tcp --dport 27015 -j TRUSTED_1
-A TRUSTED_1 -s 84.26.143.0/32 -j ACCEPT
-A TRUSTED_1 -s 204.188.252.0/24 -j ACCEPT
-A TRUSTED_1 -s 213.247.35.0/24 -j ACCEPT
-A TRUSTED_1 -j RETURN
-A INPUT -m conntrack --ctstate NEW -m tcp -p tcp --dport 3306 -j TRUSTED_2
-A TRUSTED_2 -s 204.188.252.0/24 -j ACCEPT
-A TRUSTED_2 -s 213.247.35.0/24 -j ACCEPT
-A TRUSTED_2 -s 216.185.114.0/24 -j ACCEPT
-A TRUSTED_2 -j RETURN
-A INPUT -m conntrack --ctstate NEW -m tcp -p tcp --dport 22 -j TRUSTED_3
-A TRUSTED_3 -j ACCEPT # This chain should only allow trusted ranges just like in the MySQL and HDLS chains.
-A TRUSTED_3 -j RETURN
-A INPUT -j LOG --log-prefix "IN_LEFTOVERS "
-A INPUT -j DROP
-A OUTPUT -j ACCEPT
COMMIT
If you want to try it save the rule set as /etc/sysconfig/iptables.new and then:
Code:
# Ensure old rule set is current and save a copy
/sbin/iptables-save > /etc/sysconfig/iptables | tee /etc/sysconfig/iptables.sav
# Change to new rule set and activate
/sbin/service iptables stop
cat /etc/sysconfig/iptables.new > /etc/sysconfig/iptables
/sbin/service iptables start
# Run some tests
sleep 15m
# Restore and activate previous rule set
/sbin/service iptables stop
cat /etc/sysconfig/iptables.sav > /etc/sysconfig/iptables
/sbin/service iptables start || /sbin/service iptables stop
**There's quicker ways to do this but I'm trying to avoid any "IPTABLES_SAVE_ON.*="yes" options in /etc/sysconfig/iptables-config and if it doesn't work at least try to ensure you can get back in over SSH.
-A INPUT -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -j syn_flood
-A syn_flood -m limit --limit 1/sec --limit-burst 3 -j RETURN
-A syn_flood -j DROP
Please correct me if I'm wrong, but it seems like the above is a global rule limiting every new TCP connection to 1/sec with a burst of 3. If that's right, during a SYN flood, that could explain why you weren't able to connect to your server using SSH. When you say the server became unresponsive, I'm not sure if you're referring to just being able to connect to the SSH service, or the entire server.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.