Can Your Web Server Be Toppled with a Single Command?

You've carefully considered the hardware you need for your new web server. You've spent time meticulously tuning your database, and your colleagues have spent weeks developing your cutting-edge application. Let's not fail to mention the weeks of work that your top-dollar designers have tirelessly put in so they can break the mold and produce a ground-breaking website. You think that your job's done, and you're even looking forward to a holiday. Your site goes live and receives all the coveted praise you'd hoped for. Your testy boss is even verging on looking happy for a change.

Then disaster strikes. One afternoon somebody in another country with too much time on their hands, using a perfectly legitimate and commonplace testing tool, brings your precious site to its knees with a simple command line of just a few characters, using a single broadband connection.

The threat of such an attack is very real. Even a well designed, purpose-built and high-capacity infrastructure can be crippled by a simple attack. That worried expression on your face needn't last for long, because thankfully, a simple set of security rules will automatically mitigate such attacks. Surprisingly, these rules are not commonly deployed by all accounts.

Benchmarking

The attack tool to which I'm referring is well-intentioned Apache Benchmarking tool ab (http://httpd.apache.org/docs/2.0/programs/ab.html). Apache documentation states that ab "...is designed to give you an impression of how your current Apache installation performs. This especially shows you how many requests per second your Apache installation is capable of serving."

Okay, it sounds innocuous enough, but of course, the power that this little piece of software can wield is available to any miscreant capable of cutting and pasting a single command line. What's more, ab is usually already bundled with most Apache installations on Linux, so this tool is freely available to anyone who wants it. Also of concern is that you don't even need to be a superuser to run such a command.

Figure 1 shows the ab tool running on the command line configured with the parameters to set 2500 total requests and 300 concurrent connections; more than enough to cause serious headaches for any single web server. Anyone familiar with Apache to even a minor extent is most likely aware of the plethora of configuration options and modules it supports, undoubtedly the ability to construct such a finely tuned web server configuration is one of the reasons it is so popular. The mighty Apache benchmarking tool ab is no exception, and you can finely tune it to offer a very specific set of testing criteria, which I'll leave you to discover (for White Hat penetration testing purposes, these tests will be on your own servers only, needless to say).

Running ab at the command line.

Abbreviated results of the test that was run on www.domain.com are shown below in Figure 2. It is worth pointing out that I stopped this test after two or three seconds, so it had no impact whatsoever on the test subject's website. The results would be slightly fuller if I had let it run.

The bottom of Figure 2 shows the "Percentage of the requests served within a certain time," which depicts the slow down on the web server's responses that your attack is causing as it is ramped up. Essentially, the lower section is running through the length of time, in milliseconds, the longest responses took to complete as the concurrency of connections was increased.

Abbreviated ab results.

HTTP Requests Overload

Rather than spending (sometimes, tens of) thousands of pounds, dollars, or Euros on a corporate DoS solution, you might want to try one highly effective workaround against Apache ab tool attacks. This solution requires only a single Linux machine, running the ever trusty IPtables firewall.

If you have even basic IPtables knowledge, the following ruleset won't be too much effort to decipher:

iptables -A INPUT -p tcp -m multiport --dport 80,443 -m state --state NEW -m limit --limit 100/minute --limit-burst 300 -j ACCEPT

iptables -A INPUT -p tcp -m multiport --dport 80,443 -m state --state NEW -m limit --limit 100/minute --limit-burst 300 -j LOG --log-level info --log-prefix NEW-CONNECTION-DROP:

iptables -A INPUT -p tcp -m multiport --dport 80,443 -m state --state RELATED,ESTABLISHED -m limit --limit 100/second --limit-burst 100 -j ACCEPT

iptables -A INPUT -p tcp -m multiport --dport 80,443 -m state --state RELATED,ESTABLISHED -m limit --limit 100/second --limit-burst 100 -j LOG --log-level info --log-prefix ESTABLISHED-CONNECTION-DROP:

iptables -A INPUT -p tcp -m multiport --dport 80,443 -j DROP

The only prerequisites that might trip you up (if you're running Gentoo, for example, and compiling your own kernel) is that the usually built-in-as-standard multiport and state modules must be installed and available to IPtables for this ruleset to work. (I've seen a similar solution that uses the recent module, but I prefer the granular tweaking this approach offers.

 The preceding commands differentiate between an offender flooding the ports 80 and 443 (HTTP and HTTPS) with both new connections and repeating established connections. This approach leads to more effective logging. A more primitive approach might be to limit only new connections, but such a solution might be more suited to a SYN Flood attack, where you are purely limiting TCP/IP connections, most of which are of the new variety. That won't work for us because our poor, old Apache server actively tries to keep the connections to the visitor's browsers open so that it can consume less bandwidth and web server resource per transaction. As a result, we also have to keep established connections in mind too. With some testing, you can gather a better understanding, and see in great detail how the ratio of new and established traffic is rate limited, as your dmesg or Syslog fills up with reports from the ruleset.

The fundamental purpose of this IPtables ruleset is to throttle any offenders accordingly but still keep your web server available to wanted visitor requests. In my tests, this worked well, although the laboratory web server was a little sticky when responding.

The first line has the parameter that mentions --limit 100/minute , which is relatively straightforward, and it simply means that if the destination ports 80 or 443 are requested with more than 100 packets a minute, the packets are dropped.

The second switch on that first line --limit-burst isn't quite as clear as you might think. Essentially, 300 new packets are allowed through the first parameter before the limit of 100 new packets per minute is applied, effectively giving a bit of leeway for legitimate traffic before the rate limiting even thinks about kicking in its 100/minute rule.
When I was experimenting with the limit and limit-burst values, I was surprised at how little traffic was actually let through. Be warned that the limit values are strict and may be too punitive for your Apache configuration. Simply increase them globally within the ruleset to loosen them up. As with all things firewall-based, I'd definitely recommend testing these rules on a desktop or a laboratory server before deploying them.

After you have locked down the allowed rates of inbound traffic for ports 80 and 443 with the rules in Listing 1, you can then usually open up outbound traffic. Please be aware that these examples are part of my comprehensive, site-specific IPtables script and you need to keep your own IPtables configurations specific to your needs. This small ruleset works if you have other settings in place but, for example, completely opening up ports 80 and 443 as below might not be what you're looking for.

Related content

comments powered by Disqus