Skip to content

Instantly share code, notes, and snippets.

@postmodern
Created October 12, 2009 01:24
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save postmodern/208035 to your computer and use it in GitHub Desktop.
Save postmodern/208035 to your computer and use it in GitHub Desktop.
A Rack middleware app that bans specified IPv4/IPv6 addresses and ranges.
require 'ipaddr'
module Rack
#
# BanHammer is a Rack middleware app that restricts access to your server
# using a black-list of IPv4/IPv6 addresses and ranges.
#
# MIT License - Hal Brodigan (postmodern.mod3 at gmail.com)
#
class BanHammer
DEFAULT_MESSAGE = %{
<html>
<head>
<title>Banned</title>
</head>
<body>
<h1>Banned</h1>
<p>Your IP address has been banned by BanHammer. Please contact the site administrators for information on why you were banned.</p>
</body>
</html>
}
#
# Initializes the ban hammer.
#
# @param [#call] app
# The Rack application to protect.
#
# @param [Hash] options
# Additional options.
#
# @option options [Array<String>] :banned ([])
# The list of IPv4/IPv6 addresses and netmasked ranges that are banned.
#
# @option options [String] :message ('')
# A message to display to those banned.
#
# @option options [String] :content_type ('text/html')
# The Content-Type of the ban message.
#
# @example
# use BanHammer, :banned => ['219.140.118.33/24'],
# :message => %{
# <html>
# <head>
# <title>Banned</title>
# </head>
#
# <body>
# <h1>Not even seven proxies can protect you from the BAN HAMMER.</h1>
# </body>
# </html>
# }
#
def initialize(app,options={})
@app = app
@banned = []
if options[:banned]
options[:banned].each do |ip|
@banned << IPAddr.new(ip)
end
end
@response = [
403,
{'Content-Type' => (options[:content_type] || 'text/html')},
[options[:message] || DEFAULT_MESSAGE]
]
end
def call(env)
remote_addr = IPAddr.new(env['REMOTE_ADDR'])
@banned.each do |range|
return @response if range.include?(remote_addr)
end
@app.call(env)
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment