rack-dedos 0.4.0 → 0.4.2
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +14 -0
- data/README.md +59 -10
- data/lib/rack/dedos/filters/base.rb +14 -3
- data/lib/rack/dedos/filters/country.rb +1 -1
- data/lib/rack/dedos/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 13b363d6e2ef672affc0c451da8b7209cba8dcf99922ecf4ee852df9f72f2427
|
|
4
|
+
data.tar.gz: ccd78d96fd078ecb549778809abc85cc8063d0ec0018fa111484e4571158751b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 21cc53bde60003177c38cf0db3ea19b83a6cd47ca4b23cc0d3b40fac43e13b141b8d4186eef7fc6feecde39a9733fa5af621ba4cad1521d381c25166d2dc251d
|
|
7
|
+
data.tar.gz: 1976ab0c669f8e222759251a45e502b2e7e62419bdfef21e7f184bb58dd7d23088a03e9ea3ab4fde20b70b1d651161923e448d9ed98ae14f1edb702098ebd5aa
|
data/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
Nothing so far
|
|
4
4
|
|
|
5
|
+
## 0.4.2
|
|
6
|
+
|
|
7
|
+
### Changes
|
|
8
|
+
* Use [BreakVer](https://www.taoensso.com/break-versioning) from this point forward
|
|
9
|
+
|
|
10
|
+
### Additions
|
|
11
|
+
* Include the requested URL in warnings
|
|
12
|
+
* Add `only_paths` and `except_paths` options
|
|
13
|
+
|
|
14
|
+
## 0.4.1
|
|
15
|
+
|
|
16
|
+
### Fixes
|
|
17
|
+
* Correctly include details in warnings (i.e. country code)
|
|
18
|
+
|
|
5
19
|
## 0.4.0
|
|
6
20
|
|
|
7
21
|
### Changes
|
data/README.md
CHANGED
|
@@ -31,14 +31,56 @@ And then install the bundle:
|
|
|
31
31
|
bundle install
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
⚠️ This gem initially followed [SemVer](https://semver.org) loosely but transitioned to [BreakVer](https://www.taoensso.com/break-versioning) starting from version 0.4.2 onwards.
|
|
35
35
|
|
|
36
|
-
|
|
36
|
+
## Usage
|
|
37
|
+
|
|
38
|
+
You should use an environment variable such as `UNDER_ATTACK` to enable Rack::Dedos only when your app is actually under attack.
|
|
39
|
+
|
|
40
|
+
### Rackup
|
|
41
|
+
|
|
42
|
+
```ruby
|
|
43
|
+
#!/usr/bin/env rackup
|
|
44
|
+
require 'rack/dedos'
|
|
45
|
+
|
|
46
|
+
if %w(true t on 1).include? ENV['UNDER_ATTACK']
|
|
47
|
+
use Rack::Dedos
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
run lambda { |env| [200, {'Content-Type' => 'text/plain'}, "Hello, world!\n"] }
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Hanami
|
|
54
|
+
|
|
55
|
+
```ruby
|
|
56
|
+
# config/settings.rb
|
|
57
|
+
|
|
58
|
+
module MyApp
|
|
59
|
+
class Settings < Hanami::Settings
|
|
60
|
+
setting :under_attack, default: false, constructor: Types::Params::Bool
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
```ruby
|
|
66
|
+
# config/app.rb
|
|
67
|
+
|
|
68
|
+
module MyApp
|
|
69
|
+
class App < Hanami::App
|
|
70
|
+
environment(:production) do
|
|
71
|
+
if setting.under_attack
|
|
72
|
+
middleware.use Rack::Dedos
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
```
|
|
37
78
|
|
|
38
79
|
### Rails
|
|
39
80
|
|
|
40
81
|
```ruby
|
|
41
82
|
# config/application.rb
|
|
83
|
+
|
|
42
84
|
class Application < Rails::Application
|
|
43
85
|
if Rails.env.production? && ActiveModel::Type::Boolean.new.cast(ENV['UNDER_ATTACK'])
|
|
44
86
|
config.middleware.use Rack::Dedos
|
|
@@ -46,19 +88,26 @@ class Application < Rails::Application
|
|
|
46
88
|
end
|
|
47
89
|
```
|
|
48
90
|
|
|
49
|
-
|
|
91
|
+
## Configuration
|
|
50
92
|
|
|
51
|
-
|
|
52
|
-
#!/usr/bin/env rackup
|
|
53
|
-
require 'rack/dedos'
|
|
93
|
+
Given the drastic nature of the filters, you should use this middleware for production environments only and/or if an environment variable like `UNDER_ATTACK` is set to true.
|
|
54
94
|
|
|
55
|
-
|
|
56
|
-
use Rack::Dedos
|
|
57
|
-
end
|
|
95
|
+
### Request
|
|
58
96
|
|
|
59
|
-
|
|
97
|
+
By default, filters are applied to all request paths. You can norrow this to only certain request paths:
|
|
98
|
+
|
|
99
|
+
```ruby
|
|
100
|
+
use Rack::Dedos,
|
|
101
|
+
only_paths: [%r(^/search), %r(%r(\.xml)$)]
|
|
102
|
+
|
|
103
|
+
use Rack::Dedos,
|
|
104
|
+
except_paths: [%r(^/$)]
|
|
60
105
|
```
|
|
61
106
|
|
|
107
|
+
If you set both `only_paths` and `except_paths`, the latter take precedence.
|
|
108
|
+
|
|
109
|
+
⚠️ The request path does not include GET parameters.
|
|
110
|
+
|
|
62
111
|
### Response
|
|
63
112
|
|
|
64
113
|
If a request is classified as malicious by at least one filter, the middleware responds with:
|
|
@@ -6,27 +6,32 @@ module Rack
|
|
|
6
6
|
class Base
|
|
7
7
|
|
|
8
8
|
DEFAULT_OPTIONS = {
|
|
9
|
+
only_paths: [],
|
|
10
|
+
except_paths: [],
|
|
9
11
|
status: 403,
|
|
10
12
|
text: 'Forbidden (Temporarily Blocked by Rules)'
|
|
11
|
-
}
|
|
13
|
+
}.freeze
|
|
12
14
|
|
|
13
15
|
attr_reader :app
|
|
14
16
|
attr_reader :options
|
|
17
|
+
attr_reader :details
|
|
15
18
|
|
|
16
19
|
# @param app [#call]
|
|
17
20
|
# @param options [Hash{Symbol => Object}]
|
|
18
21
|
def initialize(app, options = {})
|
|
19
22
|
@app = app
|
|
20
23
|
@options = DEFAULT_OPTIONS.merge(options)
|
|
24
|
+
@details = nil
|
|
21
25
|
end
|
|
22
26
|
|
|
23
27
|
def call(env)
|
|
24
28
|
request = Rack::Request.new(env)
|
|
25
29
|
ip = real_ip(request)
|
|
26
|
-
if allowed?(request, ip)
|
|
30
|
+
if !apply?(request) || allowed?(request, ip)
|
|
27
31
|
app.call(env)
|
|
28
32
|
else
|
|
29
|
-
|
|
33
|
+
message = "rack-dedos: request #{request.path} from #{ip} blocked by #{self.class}"
|
|
34
|
+
warn([message, details].compact.join(": "))
|
|
30
35
|
[options[:status], { 'Content-Type' => 'text/plain' }, [options[:text]]]
|
|
31
36
|
end
|
|
32
37
|
end
|
|
@@ -37,6 +42,12 @@ module Rack
|
|
|
37
42
|
Rack::Dedos.config
|
|
38
43
|
end
|
|
39
44
|
|
|
45
|
+
def apply?(request)
|
|
46
|
+
return false if @options[:except_paths].any? { request.path.match? _1 }
|
|
47
|
+
return true if @options[:only_paths].none?
|
|
48
|
+
@options[:only_paths].any? { request.path.match? _1 }
|
|
49
|
+
end
|
|
50
|
+
|
|
40
51
|
# Get the real IP of the client
|
|
41
52
|
#
|
|
42
53
|
# If containers and/or proxies such as Cloudflare are in the mix, the
|
|
@@ -23,7 +23,7 @@ module Rack
|
|
|
23
23
|
|
|
24
24
|
def allowed?(request, ip)
|
|
25
25
|
if country = maxmind_db&.get(ip)
|
|
26
|
-
country_code = country.dig('country', 'iso_code').to_sym
|
|
26
|
+
country_code = @details = country.dig('country', 'iso_code').to_sym
|
|
27
27
|
@countries.include?(country_code) ? @allowed : !@allowed
|
|
28
28
|
else # not found in database
|
|
29
29
|
true
|
data/lib/rack/dedos/version.rb
CHANGED