Skip to content

Instantly share code, notes, and snippets.

@josnidhin
Created April 25, 2017 06:27
Show Gist options
  • Save josnidhin/91d1ea9cd71fde386c27a9228476834e to your computer and use it in GitHub Desktop.
Save josnidhin/91d1ea9cd71fde386c27a9228476834e to your computer and use it in GitHub Desktop.
A simple mod security config for IP Rate limiting Apache server behind a load balancer.
# assumes libapache2-modsecurity is installed
# Reference Mannual - https://github.com/SpiderLabs/ModSecurity/wiki
SecRuleEngine On
<LocationMatch "^/.*">
# initialise the state based on X-Forwarded-For ip address
SecRule REQUEST_HEADERS:X-Forwarded-For "@unconditionalMatch" "phase:2,initcol:ip=%{MATCHED_VAR},pass,nolog,id:100"
# if greater then burst_rate_limit then pause set RATELIMITED var and then return 503
SecRule IP:ACCESS_COUNT "@gt {{ burst_rate_limit }}" "phase:2,pause:300,deny,status:503,setenv:RATELIMITED,skip:1,nolog,id:102"
# if above rule doesnt match increment the count
SecAction "phase:2,setvar:ip.access_count=+1,pass,nolog,id:103"
# set the base rate to one per second
SecAction "phase:5,deprecatevar:ip.access_count=1/1,pass,nolog,id:104"
# set a header when ratelimited
Header always set Retry-After "10" env=RATELIMITED
</LocationMatch>
ErrorDocument 503 "Service Unavailable"
@micahlagrange
Copy link

micahlagrange commented Aug 5, 2018

@jmroth I just implemented this kind of rule and having deny and pause:300 in the same rule actually does appear to work just fine, I'm seeing 401s in the log and when I tested this earlier the delay was actually kicking in too.

@MattyShires
Copy link

Rule isn't working due to error ModSecurity: Could not set variable "ip.access_count" as the collection does not exist.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment