24

One of my LAMP servers was recently brought down by some kind of script bot looking for exploits. From the looks of it, it was making so many requests a second, that it overloaded the RAM on the server and brought my entire site down for an hour. That "attacK" all came from a single IP address.

So how can I automatically and temporarily block an IP address making too many hits on my LAMP Server in a short period of time? What's the best tool for the job, and should I be solving this at the Operating System level or via PHP?

ProgrammerGirl
  • 449
  • 1
  • 4
  • 8

4 Answers4

28

Fail2Ban. The gold standard/default solution to this problem on the Linux platform.

HopelessN00b
  • 53,385
  • 32
  • 133
  • 208
  • Interesting, thanks. How does this deal with or impact web crawlers such as Google? – ProgrammerGirl Aug 21 '12 at 22:54
  • 1
    @Programmer Depends on how you configure the thing, but you wouldn't expect a web crawler to be inputting bad passwords, searching for exploits, or racking up enough hits to trigger a well-defined threshold - so just check your logs to figure out what to define your thresholds at. – HopelessN00b Aug 21 '12 at 22:58
6

You should avoid trying to do this with PHP. By the time PHP gets involved, it's already too late - the memory has already been allocated.

You can ban IP addresses at any layer, but the lowest level that uses the least amount of resources is the route you want to take. This is usually the firewall. At the very least, iptables (linux firewall) is what you want to use. There are tools that others have mentioned, such as Fail2Ban, that can automate this for you. External firewall would be better.

Besides trying to ban offending IP addresses, you should try to make better use of your resources. If a request takes less resources it will take longer for an attack to be effective.

Apache also uses a lot of memory. If you're using mod_php, it's even worse because PHP is loaded inside of every Apache child process. This means even requests to static content (css/js/images) are loading PHP even when PHP isn't being used. You can solve this problem by using FastCGI instead. mod_fcgid is a good option.

There are also other web servers that are more resource efficient. Nginx is my favorite. There's also Lighttpd. A lot of people like Litespeed (drop in replacement for Apache).

If you want to stick with Apache, consider tuning it as best you can. Consider disabling .htaccess. Here's a good explanation why.

Luke
  • 1,892
  • 4
  • 22
  • 27
4
iptables -I INPUT -p tcp --dport 80 -i eth0 -m state --state NEW -m recent --set
iptables -I INPUT -p tcp --dport 80 -i eth0 -m state --state NEW -m recent --update --seconds 60 --hitcount 4 -j DROP

ossec can do this type of thing automatically and transparently based on the syslogs.

HopelessN00b
  • 53,385
  • 32
  • 133
  • 208
gmck
  • 91
  • 1
  • 1
    Can you please explain what the first line of code does, exactly? Also, how does ossec compare with fail2ban? Thanks. – ProgrammerGirl Aug 21 '12 at 22:58
  • 3
    It's an iptables rule. I believe it counts how many new connection attempts are made and drops them after they exceed 4 attempts within 60 seconds. I encourage you to look at `man iptables` and see what each flag means, and how they work together. – Luke Sep 15 '12 at 21:12
  • Don't forget to put an ACCEPT rule after these if your default input policy is DROP/REJECT – BungleBonce Jan 31 '21 at 20:52
3

To control or block http traffic, you can use :

However, be aware that these tool might also block/slow webspiders and therefore impact SEO.