FEATURE: Rate limit exceptions via ENV (#14033)
Allow admins to configure exceptions to our Rails rate limiter. Configuration happens in the environment variables, and work with both IPs and CIDR blocks. Example: ``` env: DISCOURSE_MAX_REQS_PER_IP_EXCEPTIONS: >- 14.15.16.32/27 216.148.1.2 ```
This commit is contained in:
parent
621892ea30
commit
b136375582
|
@ -8,6 +8,16 @@ class Middleware::RequestTracker
|
|||
@@detailed_request_loggers = nil
|
||||
@@ip_skipper = nil
|
||||
|
||||
# You can add exceptions to our app rate limiter in the app.yml ENV section.
|
||||
# example:
|
||||
#
|
||||
# env:
|
||||
# DISCOURSE_MAX_REQS_PER_IP_EXCEPTIONS: >-
|
||||
# 14.15.16.32/27
|
||||
# 216.148.1.2
|
||||
#
|
||||
STATIC_IP_SKIPPER = ENV['DISCOURSE_MAX_REQS_PER_IP_EXCEPTIONS']&.split&.map { |ip| IPAddr.new(ip) }
|
||||
|
||||
# register callbacks for detailed request loggers called on every request
|
||||
# example:
|
||||
#
|
||||
|
@ -234,6 +244,7 @@ class Middleware::RequestTracker
|
|||
end
|
||||
|
||||
return false if @@ip_skipper&.call(ip)
|
||||
return false if STATIC_IP_SKIPPER&.any? { |entry| entry.include?(ip) }
|
||||
|
||||
limiter10 = RateLimiter.new(
|
||||
nil,
|
||||
|
|
|
@ -245,6 +245,38 @@ describe Middleware::RequestTracker do
|
|||
end
|
||||
end
|
||||
|
||||
it "blocks if the ip isn't static skipped" do
|
||||
global_setting :max_reqs_per_ip_per_10_seconds, 1
|
||||
global_setting :max_reqs_per_ip_mode, 'block'
|
||||
|
||||
env1 = env("REMOTE_ADDR" => "1.1.1.1")
|
||||
status, _ = middleware.call(env1)
|
||||
status, _ = middleware.call(env1)
|
||||
expect(status).to eq(429)
|
||||
end
|
||||
|
||||
it "doesn't block if rate limiter is enabled but IP is on the static exception list" do
|
||||
stub_const(Middleware::RequestTracker, "STATIC_IP_SKIPPER", "177.33.14.73 191.209.88.192/30"&.split&.map { |ip| IPAddr.new(ip) }) do
|
||||
global_setting :max_reqs_per_ip_per_10_seconds, 1
|
||||
global_setting :max_reqs_per_ip_mode, 'block'
|
||||
|
||||
env1 = env("REMOTE_ADDR" => "177.33.14.73")
|
||||
env2 = env("REMOTE_ADDR" => "191.209.88.194")
|
||||
|
||||
status, _ = middleware.call(env1)
|
||||
expect(status).to eq(200)
|
||||
|
||||
status, _ = middleware.call(env1)
|
||||
expect(status).to eq(200)
|
||||
|
||||
status, _ = middleware.call(env2)
|
||||
expect(status).to eq(200)
|
||||
|
||||
status, _ = middleware.call(env2)
|
||||
expect(status).to eq(200)
|
||||
end
|
||||
end
|
||||
|
||||
describe "register_ip_skipper" do
|
||||
before do
|
||||
Middleware::RequestTracker.register_ip_skipper do |ip|
|
||||
|
|
Loading…
Reference in New Issue