rack-ip_blocker 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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