The ruleset(s) provided by modsecurity/modsececurity2 will affect NATS processes and these rules are enabled by default. These default ruleset(s) need to be disabled so they will not get used.
Host can create custom rules that only apply for things outside of NATS
Host's responsibility to ensure that these rules don't affect NATS functions on NATS domain & linkdomains
You can create customized rules with modsecurity2, to rate-limit by ip, request vars being sent, etc. These are example rules that will rate-limit requests and prevent bot spam. You can use these rulesets as a reference, but be aware that you are responsible for your configuration and that you should NOT use the default rulesets provided by modsececurity2.
Member Signup Throttling
Rate-limit to 75 requests to signup/signup.php using the same password or email within a 10 minute period.
Plus Script Throttling
Rate-limit the *plus scripts (as well as approved, upgraded, duplicate, and submit scripts) to 75 requests from the same ip address within a 10 minute period.
Affiliate Login Throttling
Rate-limit affiliate login attempts to 100, but also dynamically increase rate-limiting to 5 if there are more than 1000 login attempts within a 5 minute period.
<Location /signup/signup.php>
# needs to be enabled to read POST data
SecRequestBodyAccess On
# jump to SecMarker if signup[password] variable is not passed in request
SecRule ARGS:signup[password] "^$" "phase:2,id:'981041',t:none,nolog,pass,skipAfter:END_BRUTE_FORCE_PROTECTION_CHECKS1"
# set 'RESOURCE' to value of signup[password] if it is not blank
SecRule ARGS:signup[password] ".*" "phase:2,id:'1',chain,t:none,nolog,pass"
SecAction initcol:RESOURCE=%{ARGS.signup[password]}
# enforce an existing block
SecRule RESOURCE:bf_block "@eq 1" \
"id:2,phase:2,deny,\
msg:'Password \"%{ARGS.signup[password]}\" blocked because of suspected brute-force attack'"
# set or increase count of how many times a signup[password] value was used and have it expire after 600 seconds
SecRule ARGS:signup[password] ".*" "phase:5,id:3,t:none,nolog,pass,setvar:RESOURCE.bf_counter=+1,expirevar:RESOURCE.bf_counter=600"
# check for too many requests for a single signup[password] value and block future requests that contain that value
SecRule RESOURCE:bf_counter "@ge 75" \
"id:4,phase:5,t:none,pass,\
setvar:RESOURCE.bf_block,\
setvar:!RESOURCE.bf_counter,\
expirevar:RESOURCE.bf_block=600"
# jump to this point if signup[password] is not passed in request
SecMarker END_BRUTE_FORCE_PROTECTION_CHECKS1
# jump to SecMarker if signup[password:1:6:16:::password_check] variable is not passed in request
SecRule ARGS:signup[password:1:6:16:::password_check] "^$" "phase:2,id:'981042',t:none,nolog,pass,skipAfter:END_BRUTE_FORCE_PROTECTION_CHECKS2"
# set 'RESOURCE' to value of signup[password:1:6:16:::password_check] if it is not blank
SecRule ARGS:signup[password:1:6:16:::password_check] ".*" "phase:2,id:'5',chain,t:none,nolog,pass"
SecAction initcol:RESOURCE=%{ARGS.signup[password:1:6:16:::password_check]}
# enforce an existing block
SecRule RESOURCE:bf_block "@eq 1" \
"id:6,phase:2,deny,\
msg:'Password \"%{ARGS.signup[password:1:6:16:::password_check]}\" blocked because of suspected brute-force attack'"
# set or increase count of how many times a signup[password:1:6:16:::password_check] value was used and have it expire after 600 seconds
SecRule ARGS:signup[password:1:6:16:::password_check] ".*" "phase:5,id:7,t:urlDecode,nolog,pass,setvar:RESOURCE.bf_counter=+1,expirevar:RESOURCE.bf_counter=600"
# check for too many requests for a single signup[password:1:6:16:::password_check] value and block future requests that contain that value
SecRule RESOURCE:bf_counter "@ge 75" \
"id:8,phase:5,t:none,pass,\
setvar:RESOURCE.bf_block,\
setvar:!RESOURCE.bf_counter,\
expirevar:RESOURCE.bf_block=600"
# jump to this point if signup[password:1:6:16:::password_check] is not passed in request
SecMarker END_BRUTE_FORCE_PROTECTION_CHECKS2
# jump to SecMarker if signup[email] variable is not passed in request
SecRule ARGS:signup[email] "^$" "phase:2,id:'981043',t:none,nolog,pass,skipAfter:END_BRUTE_FORCE_PROTECTION_CHECKS3"
# set 'RESOURCE' to value of signup[email] if it is not blank
SecRule ARGS:signup[email] ".*" "phase:2,id:'9',chain,t:none,nolog,pass"
SecAction initcol:RESOURCE=%{ARGS.signup[email]}
# enforce an existing block
SecRule RESOURCE:bf_block "@eq 1" \
"id:10,phase:2,deny,\
msg:'Email \"%{ARGS.signup[email]}\" blocked because of suspected brute-force attack'"
# set or increase count of how many times a signup[email] value was used and have it expire after 600 seconds
SecRule ARGS:signup[email] ".*" "phase:5,id:11,t:none,nolog,pass,setvar:RESOURCE.bf_counter=+1,expirevar:RESOURCE.bf_counter=600"
# check for too many requests for a single signup[email] value and block future requests that contain that value
SecRule RESOURCE:bf_counter "@ge 75" \
"id:12,phase:5,t:none,pass,\
setvar:RESOURCE.bf_block,\
setvar:!RESOURCE.bf_counter,\
expirevar:RESOURCE.bf_block=600"
# jump to this point if signup[email] is not passed in request
SecMarker END_BRUTE_FORCE_PROTECTION_CHECKS3
# jump to SecMarker if signup[email:1:1:128:::email_check] variable is not passed in request
SecRule ARGS:signup[email:1:1:128:::email_check] "^$" "phase:2,id:'981044',t:none,nolog,pass,skipAfter:END_BRUTE_FORCE_PROTECTION_CHECKS4"
# set 'RESOURCE' to value of signup[email:1:1:128:::email_check] if it is not blank
SecRule ARGS:signup[email:1:1:128:::email_check] ".*" "phase:2,id:'13',chain,t:none,nolog,pass"
SecAction initcol:RESOURCE=%{ARGS.signup[email:1:1:128:::email_check]}
# enforce an existing block
SecRule RESOURCE:bf_block "@eq 1" \
"id:14,phase:2,deny,\
msg:'Email \"%{ARGS.signup[email:1:1:128:::email_check]}\" blocked because of suspected brute-force attack'"
# set or increase count of how many times a signup[email:1:1:128:::email_check] value was used and have it expire after 600 seconds
SecRule ARGS:signup[email:1:1:128:::email_check] ".*" "phase:5,id:15,t:none,nolog,pass,setvar:RESOURCE.bf_counter=+1,expirevar:RESOURCE.bf_counter=600"
# check for too many requests for a single signup[email:1:1:128:::email_check] and block future requests that contain that value
SecRule RESOURCE:bf_counter "@ge 75" \
"id:16,phase:5,t:none,pass,\
setvar:RESOURCE.bf_block,\
setvar:!RESOURCE.bf_counter,\
expirevar:RESOURCE.bf_block=600"
# jump to this point if signup[email:1:1:128:::email_check] is not passed in request
SecMarker END_BRUTE_FORCE_PROTECTION_CHECKS4
</Location>
#Bruteforce checking for affiliate login
#Block ip if X amount of hits to internal.php containing user and pass params
<Location /internal.php>
# needs to be enabled to read POST data
SecRequestBodyAccess On
# jump to SecMarker if user variable is not passed in request
SecRule &ARGS:user "@eq 0" "phase:2,id:'30',t:none,nolog,pass,skipAfter:END_BRUTE_FORCE_PROTECTION_CHECKS6"
SecRule ARGS:user "^$" "phase:2,id:'31',t:none,nolog,pass,skipAfter:END_BRUTE_FORCE_PROTECTION_CHECKS6"
# jump to SecMarker if pass variable is not passed in request
SecRule &ARGS:pass "@eq 0" "phase:2,id:'32',t:none,nolog,pass,skipAfter:END_BRUTE_FORCE_PROTECTION_CHECKS6"
SecRule ARGS:pass "^$" "phase:2,id:'33',t:none,nolog,pass,skipAfter:END_BRUTE_FORCE_PROTECTION_CHECKS6"
SecAction initcol:IP=%{REMOTE_ADDR},pass,nolog,id:34
# enforce an existing block
SecRule IP:bf_block "@eq 1" \
"id:35,phase:2,deny,msg:'IP \"%{REMOTE_ADDR}\" is being throttled, too many affiliate login attempts'"
# check if we're getting a ton of login attempts
SecAction initcol:RESOURCE=%{REQUEST_FILENAME},pass,nolog,id:39
SecRule REQUEST_FILENAME ".*" "phase:5,id:41,t:none,nolog,pass,setvar:RESOURCE.bf_counter=+1,expirevar:RESOURCE.bf_counter=300"
SecRule REMOTE_ADDR ".*" "phase:5,id:36,t:none,nolog,pass,setvar:IP.bf_counter=+1,expirevar:IP.bf_counter=300"
# increase throttling if we're under attack
# start throttling after 5 requests
SecRule RESOURCE:bf_block "@eq 1" "id:38,phase:5,chain,msg:'too many login attempts occuring, increase throttling',t:none"
SecRule IP:bf_counter "@ge 5" "t:none,\
setvar:IP.bf_block,\
setvar:!IP.bf_counter,\
expirevar:IP.bf_block=300"
# increase throttling if more than 1000 login attempts total
SecRule RESOURCE:bf_counter "@ge 1000" \
"id:40,phase:5,t:none,pass,\
setvar:RESOURCE.bf_block,\
setvar:!RESOURCE.bf_counter,\
expirevar:RESOURCE.bf_block=300"
# throttle ip after 100 requests
SecRule IP:bf_counter "@ge 100" \
"id:37,phase:5,t:none,pass,\
setvar:IP.bf_block,\
setvar:!IP.bf_counter,\
expirevar:IP.bf_block=300"
# jump to this point if user or pass is not passed in request
SecMarker END_BRUTE_FORCE_PROTECTION_CHECKS6
</Location>