3 require "apache_log_regex"
9 REQUESTS_PER_SECOND = <%= node[:tile][:ratelimit][:requests_per_second] %>
10 BLOCK_AT = <%= node[:tile][:ratelimit][:maximum_backlog] %>
11 UNBLOCK_AT = BLOCK_AT / 2
13 parser = ApacheLogRegex.new('%a %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"')
14 clients = LruRedux::Cache.new(1000000)
16 def decay_count(client, time)
17 decay = (time.to_i - client[:last_update]) * REQUESTS_PER_SECOND
19 client[:request_count] = [client[:request_count] - decay, 0].max
20 client[:last_update] = time.to_i
23 def write_blocked_ips(clients)
26 File.open("/srv/tile.openstreetmap.org/conf/ip.map.new", "w") do |file|
27 clients.each do |address, client|
28 decay_count(client, time)
30 if client[:request_count] >= UNBLOCK_AT
31 file.puts "#{address} blocked"
32 elsif client.has_key?(:blocked_at)
33 puts "Unblocked #{address}"
35 client.delete(:blocked_at)
40 File.rename("/srv/tile.openstreetmap.org/conf/ip.map.new",
41 "/srv/tile.openstreetmap.org/conf/ip.map")
46 next_check = write_blocked_ips(clients)
48 File::Tail::Logfile.tail("/var/log/apache2/access.log") do |line|
50 hash = parser.parse!(line)
55 next if address == "127.0.0.1" || address == "::1"
59 client = clients.getset(address) do
60 { :request_count => 0, :last_update => 0 }
63 decay_count(client, time)
65 if request =~ %r{^(GET|POST) /cgi-bin/export.*}
66 client[:request_count] = client[:request_count] + 150
68 client[:request_count] = client[:request_count] + 1
71 if client[:request_count] > BLOCK_AT && !client.has_key?(:blocked_at)
72 puts "Blocked #{address}"
74 client[:blocked_at] = time
77 elsif client[:request_count] < UNBLOCK_AT && client.has_key?(:blocked_at)
78 puts "Unblocked #{address}"
80 client.delete(:blocked_at)
86 next_check = write_blocked_ips(clients)
88 rescue ApacheLogRegex::ParseError