Commit 2826aa82 authored by Thong Kuah's avatar Thong Kuah

Merge branch 'hly-skip-redis-calls-when-ip-is-trusted' into 'master'

Skip redis call when IP is whitelisted

See merge request gitlab-org/gitlab!19521
parents eb7a76fd ff33c910
# Tell the Rack::Attack Rack middleware to maintain an IP blacklist. # Tell the Rack::Attack Rack middleware to maintain an IP blacklist.
# We update the blacklist in Gitlab::Auth::IpRateLimiter. # We update the blacklist in Gitlab::Auth::IpRateLimiter.
Rack::Attack.blocklist('Git HTTP Basic Auth') do |req| Rack::Attack.blocklist('Git HTTP Basic Auth') do |req|
next false unless Gitlab.config.rack_attack.git_basic_auth.enabled rate_limiter = Gitlab::Auth::IpRateLimiter.new(req.ip)
next false if !rate_limiter.enabled? || rate_limiter.trusted_ip?
Rack::Attack::Allow2Ban.filter(req.ip, Gitlab.config.rack_attack.git_basic_auth) do Rack::Attack::Allow2Ban.filter(req.ip, Gitlab.config.rack_attack.git_basic_auth) do
# This block only gets run if the IP was not already banned. # This block only gets run if the IP was not already banned.
......
...@@ -21,11 +21,12 @@ module Gitlab ...@@ -21,11 +21,12 @@ module Gitlab
end end
def register_fail! def register_fail!
return false if trusted_ip?
# Allow2Ban.filter will return false if this IP has not failed too often yet # Allow2Ban.filter will return false if this IP has not failed too often yet
@banned = Rack::Attack::Allow2Ban.filter(ip, config) do @banned = Rack::Attack::Allow2Ban.filter(ip, config) do
# If we return false here, the failure for this IP is ignored by Allow2Ban # We return true to increment the count for this IP
# If we return true here, the count for the IP is incremented. true
ip_can_be_banned?
end end
end end
...@@ -33,20 +34,16 @@ module Gitlab ...@@ -33,20 +34,16 @@ module Gitlab
@banned @banned
end end
def trusted_ip?
trusted_ips.any? { |netmask| netmask.include?(ip) }
end
private private
def config def config
Gitlab.config.rack_attack.git_basic_auth Gitlab.config.rack_attack.git_basic_auth
end end
def ip_can_be_banned?
!trusted_ip?
end
def trusted_ip?
trusted_ips.any? { |netmask| netmask.include?(ip) }
end
def trusted_ips def trusted_ips
strong_memoize(:trusted_ips) do strong_memoize(:trusted_ips) do
config.ip_whitelist.map do |proxy| config.ip_whitelist.map do |proxy|
......
...@@ -452,7 +452,7 @@ describe 'Git HTTP requests' do ...@@ -452,7 +452,7 @@ describe 'Git HTTP requests' do
context "when authentication fails" do context "when authentication fails" do
context "when the user is IP banned" do context "when the user is IP banned" do
before do before do
stub_rack_attack_setting(enabled: true) stub_rack_attack_setting(enabled: true, ip_whitelist: [])
end end
it "responds with status 403" do it "responds with status 403" do
......
...@@ -83,7 +83,7 @@ describe 'Rack Attack global throttles' do ...@@ -83,7 +83,7 @@ describe 'Rack Attack global throttles' do
expect(response).to have_http_status 200 expect(response).to have_http_status 200
end end
expect_any_instance_of(Rack::Attack::Request).to receive(:ip).and_return('1.2.3.4') expect_any_instance_of(Rack::Attack::Request).to receive(:ip).at_least(:once).and_return('1.2.3.4')
# would be over limit for the same IP # would be over limit for the same IP
get url_that_does_not_require_authentication get url_that_does_not_require_authentication
......
...@@ -74,7 +74,7 @@ shared_examples_for 'rate-limited token-authenticated requests' do ...@@ -74,7 +74,7 @@ shared_examples_for 'rate-limited token-authenticated requests' do
expect(response).to have_http_status 200 expect(response).to have_http_status 200
end end
expect_any_instance_of(Rack::Attack::Request).to receive(:ip).and_return('1.2.3.4') expect_any_instance_of(Rack::Attack::Request).to receive(:ip).at_least(:once).and_return('1.2.3.4')
expect_rejection { get(*get_args) } expect_rejection { get(*get_args) }
end end
...@@ -194,7 +194,7 @@ shared_examples_for 'rate-limited web authenticated requests' do ...@@ -194,7 +194,7 @@ shared_examples_for 'rate-limited web authenticated requests' do
expect(response).to have_http_status 200 expect(response).to have_http_status 200
end end
expect_any_instance_of(Rack::Attack::Request).to receive(:ip).and_return('1.2.3.4') expect_any_instance_of(Rack::Attack::Request).to receive(:ip).at_least(:once).and_return('1.2.3.4')
expect_rejection { get url_that_requires_authentication } expect_rejection { get url_that_requires_authentication }
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment