Late night admin is indeed not a good idea.
Indeed Virtualmin doesn’t immediately configure mod_qos. You’d download it via your package manager (it should be available there, if not already installed), and activate it through Webmin’s Apache module.
Detailed documentation about its directives you find here: http://opensource.adnovum.ch/mod_qos/
NOTE: In the following code excerpts, “[em]” needs to be an asterisk! The forum software here thinks I want to format something in italics and replaces the asterisks.
I personally have for one a global limit for concurrent connections and connections per second to any given URL from all clients cumulative, in /etc/apache2/mods-available/qos.conf:
QS_LocRequestLimitMatch ^.\*$ 100
QS_LocRequestPerSecLimitMatch ^.\*$ 10
“LimitMatch” is a hard limit to 100 global connections to any given URL. “RequestsPerSec” operates by inducing increasing delays if the number of requests per second given is exceeded.
Then, for specific “flooding-prone” URLs I have per-client limits. I.e. each remote IP can only have a certain number of concurrent requests before delay is induced:
SetEnvIfNoCase Host DOMAIN1\\.TLD QS_Event=yes
SetEnvIfNoCase Host DOMAIN2\\.TLD QS_Event=yes
QS_ClientEventPerSecLimit 2
Mind the “\.”, those lines are regular expressions.
Then, for specific URLs in certain domains (primarily administration pages of CMSes that sometimes get dictionary-attacked), I have this in the domain’s virtual host configuration:
QS_LocRequestLimitMatch ^/administrator.\*$ 10
QS_LocRequestPerSecLimitMatch ^/administrator.\*$ 1
QS_LocRequestLimitMatch ^.\*$ 30
QS_LocRequestPerSecLimitMatch ^.\*$ 5
This limits requests to URLs starting with “/administrator” to 10 global, and 1 per second. Other URLs of that domain are limited to 30 requests global and 5 per second. This is client-global, not per client IP.