-
-
Save ratbeard/211542 to your computer and use it in GitHub Desktop.
saw at http://coderack.org/users/Postmodern/entries/26-banhammer and felt like tweaking the code :)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | |
# | |
# Needlessly modified by Mike Frawley | |
# | |
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={}) | |
defaults = { | |
:banned => [], | |
:content_type => 'text/html', | |
:message => DEFAULT_MESSAGE | |
} | |
options = defaults.merge(options) | |
@app = app | |
@banned_ips = options[:banned].map {|ip| IpAddr.new(ip) } | |
@banned_response = [ | |
403, | |
{'Content-Type' => options[:content_type]}, | |
[ options[:message] ] | |
] | |
end | |
def call(env) | |
stop_if_remote_addr_banned || @app.call(env) | |
end | |
private | |
def stop_if_remote_addr_banned | |
remote_addr = IPAddr.new(env['REMOTE_ADDR']) | |
@banned_response if banned? remote_addr | |
end | |
def banned?(ip) | |
@banned_ips.any {|ip_range| ip_range.include? ip } | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment