diff --git a/config/initializers/rack_attack.rb b/config/initializers/rack_attack.rb index 935afa73..1e29ae4d 100644 --- a/config/initializers/rack_attack.rb +++ b/config/initializers/rack_attack.rb @@ -1,27 +1,41 @@ # frozen_string_literal: true -unless %w(development test).include? Rails.env +unless ENV["CDTB_RACK_ATTACK_DISABLED"].to_i.positive? || %w(development test).include?(Rails.env) require "rack/attack" - limit= ENV["RACK_ATTACK_THROTTLE_LIMIT"] || 30 - period= ENV["RACK_ATTACK_THROTTLE_PERIOD"] || 60 - Rails.logger.info("Configuring Rack::Attack.throttle with limit: #{limit}, period: #{period}") - Rack::Attack.throttle("requests by (forwarded) ip", limit: limit.to_i, period: period.to_i) do |request| - # ignore requests to assets - next if request.path.start_with?("/rails/active_storage") - - # x_forwarded_for= request.get_header('X-Forwarded-For') + def extract_ip(request) x_forwarded_for= request.get_header("HTTP_X_FORWARDED_FOR") - Rails.logger.debug { ">>>>>>>>>>>>>>>>>>>> X-Forwarded-For: #{x_forwarded_for}" } + Rails.logger.info { ">>>>>>>>>>>>>>>>>>>> X-Forwarded-For: #{x_forwarded_for}" } if x_forwarded_for.present? ip= x_forwarded_for.split(":").first - Rails.logger.info { ">>>>>>>>>>>>>>>>>>>> X-Forwarded-For IP: #{ip}" } ip else request.ip end end + limit= ENV.fetch("RACK_ATTACK_THROTTLE_LIMIT", 30) + period= ENV.fetch("RACK_ATTACK_THROTTLE_PERIOD", 60) + Rails.logger.info("Configuring Rack::Attack.throttle with limit: #{limit}, period: #{period}") + Rack::Attack.throttle("requests by ip", limit: limit.to_i, period: period.to_i) do |request| + # ignore requests to assets + next if request.path.start_with?("/rails/active_storage") + + extract_ip(request) + end + + limit= ENV.fetch("RACK_ATTACK_THROTTLE_RANGE_LIMIT", 10) + period= ENV.fetch("RACK_ATTACK_THROTTLE_RANGE_PERIOD", 20) + Rails.logger.info("Configuring Rack::Attack.throttle with limits for IP Ranges: #{limit}, period: #{period}") + Rack::Attack.throttle("requests by ip range", limit: limit.to_i, period: period.to_i) do |request| + # ignore requests to assets + next if request.path.start_with?("/rails/active_storage") + + ip= extract_ip(request) + # extract the 32bit range + ip.split(".")[0, 2] + end + if ENV["RACK_ATTACK_BLOCKED_IPS"].present? ENV["RACK_ATTACK_BLOCKED_IPS"].split(",").each do |ip_or_subnet| Rack::Attack.blocklist_ip(ip_or_subnet)