1

a (linux) webserver I administer (on a VPS) for a low volume website has just been subjected to about 5 SYN requests/second on port 80, with no other traffic coming from the remote host. It was more of a drip than a flood, but it went on for something like an hour after I first noticed it. I don't know if this was an amplification attack or not.

I have no desire to be part of that sort of thing, and in any case, all those half-opened connections clogging up netstat were annoying, even if there was no real harm done. (SYN-cookies are enabled, the link was a long way from saturated, and apache was coping, though I think memory usage was up and responses a bit slower than normal.)

So, this one, I 'mitigated' by manually blocking the spoofed / actual originating IP address, and then kept an eye on it with tcpdump, which is how I knew they'd given up. I'd like an automatic solution...

As it's a public-facing webserver, there are SUPPOSED to be connections! And some pages have a lot of pictures/CSS files, etc. on them. I therefore fully expect that genuine users will far exceeding the 5 'attack' requests per second, and that therefore things like

iptables -A INPUT -m state --state NEW -m limit --limit 4/second --limit-burst 20 ....

will just catch out genuine users but barely catch the attack, if at all.

Other than something crude like a script counting SYN_RCVD entries in the output of netstat every so often and then feeding the results into a log for fail2ban to respond to, is there an effective solution to drop packets if the cumulative total of half-open connections from a given IP exceeds some number? I can't see anything in iptables, but maybe I'm missing something.

EDIT: Forgot to say, the VPS is openVZ-based (built on RHEL6), so the kernel I'm stick with is 2.6.32 at the moment. Answers that work on kernels that ancient would be great!

EDIT2: Conntrack timeouts, as requested:

net.netfilter.nf_conntrack_generic_timeout = 120
net.netfilter.nf_conntrack_tcp_timeout_syn_sent = 30
net.netfilter.nf_conntrack_tcp_timeout_syn_recv = 15
net.netfilter.nf_conntrack_tcp_timeout_established = 86400
net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 30
net.netfilter.nf_conntrack_tcp_timeout_close_wait = 15
net.netfilter.nf_conntrack_tcp_timeout_last_ack = 10
net.netfilter.nf_conntrack_tcp_timeout_time_wait = 30
net.netfilter.nf_conntrack_tcp_timeout_close = 5
net.netfilter.nf_conntrack_tcp_timeout_max_retrans = 60
net.netfilter.nf_conntrack_tcp_timeout_unacknowledged = 60
net.netfilter.nf_conntrack_udp_timeout = 10
net.netfilter.nf_conntrack_udp_timeout_stream = 60
net.netfilter.nf_conntrack_icmpv6_timeout = 30
net.netfilter.nf_conntrack_icmp_timeout = 10
net.netfilter.nf_conntrack_events_retry_timeout = 15
net.ipv6.nf_conntrack_frag6_timeout = 4194

But as I wrote above, I'm not so much interested in impact on the server (so far it's been minimal) as blocking script-kiddies and the like, just like when they try to see if I've got phpmyAdmin, a dlink-router, (etc) that's about the last packet of theirs I get.

1 Answers1

2

Yes, you can do that Kernel settings (e.g. setting timeouts via conntrack module) in combination with iptables limits and SYNPROXY.

Basically what synproxy does is to check if a full TLS connection is established and if not drop the request. It has a much better performance than other solutions that came before (hashlimits etc.).

And you're right, a limit of 4 connections/second will block a lot of legitimate connections, around 60-80/s is more realistic. For your use case synproxy is definitely the way to go.

When playing around with DDoS protection with built in Linux tools earlier this year myself I found a great anti-DoS guide here: https://javapipe.com/ddos/blog/iptables-ddos-protection/

This guide basically is a how-to to all of the things I mentioned above. It explains what every rule does, why you should or shouldn't implement it, how it works, how it affects performance and tells you if it's optional, a really great guide.

Broco
  • 1,999
  • 13
  • 21
  • This is a wonderful answer and I'd love to be able to accept it. I hadn't seen anything about SYNPROXY, and it looks great. Unfortunately since the VPS uses a 2.6 series 'stable' kernel (Qn now edited to mention that), and so sadly I cannot use SYNPROXY. – somloigaluska Oct 01 '18 at 14:18
  • 1
    @somloigaluska Can't you upgrade OpenVZ to 7? It has been available for a couple of years now. – Michael Hampton Oct 01 '18 at 14:28
  • @somloigaluska well, I would strongly advise you to upgrade. If that is not an option at all you can try fiddling around with conntrack timeout and list size values (carefully). Can you give the output of `sysctl -a | grep conntrack | grep timeout`? – Broco Oct 01 '18 at 15:20
  • Oh and another thing, 2.6.32 has reached end of life in March 2016, you really shouldn't leave an outdated kernel deployed on a web server, an upgrade is really overdue. – Broco Oct 01 '18 at 15:29
  • The VPS is on a commercial hosting company, not my hardware, not my call to upgrade etc. (this isn't a core-business site, as you can probably guess). Since openVZ 6 is still supported, I can't even moan at the hosting company much. (Apache and the rest of the OS image - the bit I can fix - is more modern than the kernel, I assure you!). – somloigaluska Oct 01 '18 at 16:56
  • Ok I get that. Also get your point about the script kids but when you provide services on the internet you have to expect that. As long as your security is not threatened and your server is coping with the traffic you shouldn't take out the big guns. The "blocking" part depends, you can use fail2ban for that, e.g. https://serverfault.com/questions/640873/how-to-ban-syn-flood-attacks-using-fail2ban – Broco Oct 01 '18 at 18:05