rack-ip_blocker 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e1cde53db8f74081aaae9d3d7c5dc1bed5f48f67
4
+ data.tar.gz: 536d91be4862c8c7749f26f82a79d8ed3d3d1f96
5
+ SHA512:
6
+ metadata.gz: 531b70a316c92fd1fb6a02be98cbd2cf362560b43b5826c4c5e505e9a6e4543eb5fcb4587fb63424d28bb85a4cc73fa4e1225b6bb124776181137d6ccdf26b4a
7
+ data.tar.gz: 38deb075a87340677217fdc32c97892136d30bf0f452027ef632688ff433de1de95ede3ebe792aa488392a67c0028975d0123e86eddd1549d5fa542ed532c242
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,24 @@
1
+ This is free and unencumbered software released into the public domain.
2
+
3
+ Anyone is free to copy, modify, publish, use, compile, sell, or
4
+ distribute this software, either in source code form or as a compiled
5
+ binary, for any purpose, commercial or non-commercial, and by any
6
+ means.
7
+
8
+ In jurisdictions that recognize copyright laws, the author or authors
9
+ of this software dedicate any and all copyright interest in the
10
+ software to the public domain. We make this dedication for the benefit
11
+ of the public at large and to the detriment of our heirs and
12
+ successors. We intend this dedication to be an overt act of
13
+ relinquishment in perpetuity of all present and future rights to this
14
+ software under copyright law.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19
+ IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20
+ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21
+ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
+ OTHER DEALINGS IN THE SOFTWARE.
23
+
24
+ For more information, please refer to <http://unlicense.org/>
@@ -0,0 +1,53 @@
1
+ # IP Blocker Middleware
2
+
3
+ `IpBlocker::Middleware` provides a simple manner of blocking specific
4
+ IP's from ever reaching your Rack/Rails application. It does this by
5
+ reading from a list of IP's specified in a plain text file.
6
+
7
+ ## Installation
8
+
9
+ Put this in your Gemfile:
10
+
11
+ ```ruby
12
+ gem "rack-ip_blocker", require: "ip_blocker"
13
+ ```
14
+
15
+ Create your blacklist file:
16
+
17
+ ```sh
18
+ touch config/blocked_ips.txt
19
+ ```
20
+
21
+ ## Usage and configuration
22
+
23
+ ### Rails
24
+
25
+ When using IpBlocker with Rails, the middleware is automatically loaded.
26
+ By default, IpBlocker will try to read blocked IP's from `config/blocked_ips.txt`.
27
+
28
+ To specify the location of your IP blacklist file, put this in your
29
+ enviroment files (`config/environments/production.rb`, etc):
30
+
31
+ ```ruby
32
+ YourApp::Application.configure do
33
+
34
+ # ...
35
+
36
+ config.ip_blocker.file_path = Rails.root.join("config/my_blacklist.txt").to_s
37
+
38
+ # ...
39
+
40
+ end
41
+ ```
42
+
43
+ ### Other Rack applications
44
+
45
+ The middleware can be manually included like so:
46
+
47
+ ```ruby
48
+ use IpBlocker::Middleware, file_path: "/path/to/my/blacklist.txt"
49
+ ```
50
+
51
+ ## License
52
+
53
+ See LICENSE.
@@ -0,0 +1,29 @@
1
+ require "bundler/gem_tasks"
2
+ require_relative "lib/ip_blocker/version"
3
+
4
+ require 'rake/testtask'
5
+ Rake::TestTask.new(:test) do |test|
6
+ test.libs << 'lib' << 'test'
7
+ test.pattern = 'test/**/*_test.rb'
8
+ test.verbose = true
9
+ end
10
+
11
+ task :default => :test
12
+
13
+ desc 'Builds the gem'
14
+ task :build do
15
+ sh 'gem build rack-ip_blocker.gemspec'
16
+ end
17
+
18
+ desc 'Builds and installs the gem'
19
+ task :install => :build do
20
+ sh "gem install rack-ip_blocker-#{IpBlocker::VERSION}"
21
+ end
22
+
23
+ desc 'Tags version, pushes to remote, and pushes gem'
24
+ task :release => :build do
25
+ sh "git tag v#{IpBlocker::VERSION}"
26
+ sh 'git push origin master'
27
+ sh "git push origin v#{IpBlocker::VERSION}"
28
+ sh "gem push rack-ip_blocker-#{IpBlocker::VERSION}.gem"
29
+ end
@@ -0,0 +1,5 @@
1
+ module IpBlocker
2
+ end
3
+
4
+ require "ip_blocker/middleware"
5
+ require "ip_blocker/railtie" if defined?(Rails)
@@ -0,0 +1,65 @@
1
+ module IpBlocker
2
+ class Middleware
3
+ # List of blocked IPs. Use Set instead of Array for faster
4
+ # +include?+ lookups, as order or uniqueness doesn't matter here.
5
+ @@blocked_ips = nil
6
+ def self.blocked_ips(file_path)
7
+ @@blocked_ips ||= Set.new(
8
+ # Remove newlines at the end of each line.
9
+ File.readlines(file_path).map { |line|
10
+ line.chomp.strip
11
+ }.reject { |line|
12
+ # Skip empty lines or comments.
13
+ line.empty? || line.start_with?("#")
14
+ }.freeze.map(&:freeze)
15
+ )
16
+ rescue Errno::ENOENT
17
+ warn "IpBlocker: File with blocked IP's '#{file_path}' doesn't exist. " \
18
+ "Not blocking anything."
19
+ @@blocked_ips = []
20
+ end
21
+
22
+ # Response to return when the request IP is blocked.
23
+ BLOCKED_RESPONSE = [
24
+ 403,
25
+ {"Content-Type".freeze => "text/html".freeze},
26
+ ["<h1>403 Forbidden</h1>".freeze]
27
+ ]
28
+ RACK_IP_ENV_KEY = "REMOTE_ADDR".freeze
29
+ RAILS_IP_ENV_KEY = "action_dispatch.remote_ip".freeze
30
+
31
+ def initialize(app, options = {})
32
+ @app = app
33
+ @options = options
34
+
35
+ if rails?
36
+ @options[:file_path] ||= Rails.configuration.ip_blocker.file_path
37
+ end
38
+ end
39
+
40
+ def call(env)
41
+ ip = env.fetch(
42
+ rails? ? RAILS_IP_ENV_KEY : RACK_IP_ENV_KEY,
43
+ "".freeze
44
+ ).to_s
45
+
46
+ # IP is blocked, return the blocked response.
47
+ if blocked_ips.include?(ip)
48
+ BLOCKED_RESPONSE
49
+ # Let the request through.
50
+ else
51
+ @app.call(env)
52
+ end
53
+ end
54
+
55
+ protected
56
+
57
+ def blocked_ips
58
+ self.class.blocked_ips(@options[:file_path])
59
+ end
60
+
61
+ def rails?
62
+ defined?(Rails)
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,14 @@
1
+ module IpBlocker
2
+ class Railtie < Rails::Railtie
3
+ config.ip_blocker = ActiveSupport::OrderedOptions.new
4
+
5
+ initializer :"ip_blocker.set_default_file_path" do
6
+ config.ip_blocker.file_path ||= Rails.root.join("config/blocked_ips.txt").to_s
7
+ end
8
+
9
+ initializer :"ip_blocker.insert_middleware" do |app|
10
+ app.middleware.insert_after ActionDispatch::RemoteIp,
11
+ IpBlocker::Middleware
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,3 @@
1
+ module IpBlocker
2
+ VERSION = "1.0.0".freeze
3
+ end
@@ -0,0 +1,22 @@
1
+ $:.push File.expand_path("../lib", __FILE__)
2
+ require 'ip_blocker/version'
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "rack-ip_blocker"
6
+ s.version = IpBlocker::VERSION
7
+ s.authors = ["Kenneth De Winter"]
8
+ s.email = ["kdwinter@protonmail.com"]
9
+ s.homepage = "https://gitlab.com/gigamo/ip_blocker"
10
+ s.summary = "Simple Rack middleware that blocks manually blacklisted IP's."
11
+ s.description = s.summary
12
+
13
+ s.files = `git ls-files`.split($/).reject { |f| f == '.gitignore' or f =~ /^examples/ }
14
+ s.executables = s.files.grep(%r{^bin/}) { |f| File.basename(f) }
15
+ s.test_files = s.files.grep(%r{^(test|spec|features)/})
16
+ s.require_paths = ["lib"]
17
+
18
+ s.add_development_dependency "bundler", "~> 1.3"
19
+ s.add_development_dependency "rake"
20
+ s.add_development_dependency "minitest", ">= 5.3.0"
21
+ s.add_development_dependency "rack-test", ">= 0"
22
+ end
@@ -0,0 +1 @@
1
+ # Nothing in here.
@@ -0,0 +1,2 @@
1
+ # Localhost should be blocked in here.
2
+ 127.0.0.1
@@ -0,0 +1,41 @@
1
+ require "ip_blocker"
2
+ require "minitest/autorun"
3
+ require "rack/test"
4
+
5
+ describe IpBlocker::Middleware do
6
+ include Rack::Test::Methods
7
+
8
+ def load_app(file_path)
9
+ Rack::Builder.new do
10
+ use IpBlocker::Middleware, file_path: File.join(Dir.pwd, file_path)
11
+ map("/") do
12
+ run ->(env) { [200, {"Content-Type" => "text/plain"}, ["OK"]] }
13
+ end
14
+ end
15
+ end
16
+
17
+ def teardown
18
+ # Don't cache
19
+ IpBlocker::Middleware.class_variable_set(:@@blocked_ips, nil)
20
+ end
21
+
22
+ describe "with IP not in blacklist" do
23
+ let(:app) { load_app("test/blacklist_empty.txt") }
24
+
25
+ it "should let requests through" do
26
+ get "/"
27
+ assert_equal 200, last_response.status
28
+ assert_equal "OK", last_response.body
29
+ end
30
+ end
31
+
32
+ describe "with IP in blacklist" do
33
+ let(:app) { load_app("test/blacklist_localhost.txt") }
34
+
35
+ it "should block requests" do
36
+ get "/"
37
+ assert_equal 403, last_response.status
38
+ assert_equal "<h1>403 Forbidden</h1>", last_response.body
39
+ end
40
+ end
41
+ end
metadata ADDED
@@ -0,0 +1,114 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rack-ip_blocker
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Kenneth De Winter
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-05-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: 5.3.0
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: 5.3.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: rack-test
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: Simple Rack middleware that blocks manually blacklisted IP's.
70
+ email:
71
+ - kdwinter@protonmail.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - Gemfile
77
+ - LICENSE
78
+ - README.md
79
+ - Rakefile
80
+ - lib/ip_blocker.rb
81
+ - lib/ip_blocker/middleware.rb
82
+ - lib/ip_blocker/railtie.rb
83
+ - lib/ip_blocker/version.rb
84
+ - rack-ip_blocker.gemspec
85
+ - test/blacklist_empty.txt
86
+ - test/blacklist_localhost.txt
87
+ - test/ip_blocker_test.rb
88
+ homepage: https://gitlab.com/gigamo/ip_blocker
89
+ licenses: []
90
+ metadata: {}
91
+ post_install_message:
92
+ rdoc_options: []
93
+ require_paths:
94
+ - lib
95
+ required_ruby_version: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ required_rubygems_version: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ requirements: []
106
+ rubyforge_project:
107
+ rubygems_version: 2.4.5.2
108
+ signing_key:
109
+ specification_version: 4
110
+ summary: Simple Rack middleware that blocks manually blacklisted IP's.
111
+ test_files:
112
+ - test/blacklist_empty.txt
113
+ - test/blacklist_localhost.txt
114
+ - test/ip_blocker_test.rb