I experienced such attack ... in the middle of midsummer (23th of June), where you are supposed to be in the countryside and drink beer :>
I put my Apache behind Varnish, which not only protected from slowloris, but also accelerated web requests quite a bit.
Also, iptables
helped me:
iptables -I INPUT -p tcp --dport 80 \
-m connlimit --connlimit-above 20 --connlimit-mask 40 -j DROP
This rule limits one host to 20 connections to port 80, which should not affect non-malicious user, but would render slowloris unusable from one host.
should I use fail2ban or iptables?
You use fail2ban in addition to a firewall solution, to extend on-demand those existing firewall rules with rules to block the specific ip-addresses of systems that perform undesirable actions on otherwise public services. They work in concert with each other.
Simplified: a firewall only sees network connections and packets and can make some sense of the patterns therein but it doesn't have the application level insight to distinguish desired and valid requests from malicious, malformed and undesirable requests. For instance your firewall can't tell the difference between a bunch of HTTP API requests and a number incorrect login attempts caused by brute force password guessing on your Wordpress admin page, to the firewall they both are only TCP connections to port 80 or 443.
Fail2ban is a generic and extensible approach to provide that application level insight to your firewall, albeit somewhat indirectly.
Frequently applications will register and log malicious, malformed and undesirable requests as such, but only rarely will they have the native ability to prevent further abuse. Although it is slightly decoupled Fail2ban can then act on those logged malicious events and limit the damage and prevent further abuse, typically by dynamically reconfiguring your firewall to deny further access. In other words Fail2ban gives your existing applications, without modifying them, the means to fend off abuse.
A different method to provide firewalls with application level insights would be by means of a intrusion detection/prevention system.
For instance a webserver is a common public service and in your firewall TCP ports 80 and 443 are open for the internet at large.
Typically you don't have any rate-limiting on the HTTP/HTTPS ports because multiple valid users can have a single origin when they are for instance behind a NAT gateway or a web proxy.
When you detect undesirable and/or malicious actions towards your webserver you use fail2ban to automate blocking such an offender (either block them completely or by only locking their access to ports 80 & 443).
On the other hand SSH access is not a public service, but if you're not in a position to restrict SSH access in your firewall to only white-listed ip-address ranges, rate-limiting incoming connections is one way to slow down brute-force attacks. But your firewall still can't distinguish between user bob successfully logging in 5 times because he's running ansible playbooks and 5 failed attempts to log in as root by a bot.
Best Answer
Fail2Ban is most effective in banning IPs for 'failed attempts'. As such, it's really not the most appropriate tool for watching for actual DoS attacks. I set Fail2Ban to watch Apache's httpd-error log file. IPs that have 20 "bad" requests within 5 minutes get banned for 5 minutes. This cuts down on script kiddies and the like, but really wouldn't protect at all against a targeted attack.
Mod_evasive and mod_security cam help cut down on potential DoS vectors, but without knowing how your site works I couldn't provide any silver bullet solutions.