wafris 0.5.4 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/lua/dist/wafris_core.lua +26 -13
- data/lib/wafris/middleware.rb +17 -0
- data/lib/wafris/version.rb +1 -1
- data/lib/wafris.rb +2 -18
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8cbb8c27a7af9771ecf6c07a34fd7da75f4ebacf4fd21dba0b37551a8b2ca2cd
|
4
|
+
data.tar.gz: 492a0f193e4c976a612106b5a0bb8c25aa008f170ec8111fa9504bd1cf585faf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b50f3ad94a373c55285d5e800e55a483f7311a45d18c80d42464931f265edae1bc36a39f97ecf803a99065e5f12b106cc1739cd3716b3219f3a1a60f31b1a6c5
|
7
|
+
data.tar.gz: d23d85b065a338c454216d37755ec6d112d4392f9415e7e13df30c4610c96ab58a15a046211332a273cee3da12bdeae2fc3c4f09722239e5cd3b414fa09d4351
|
@@ -1,4 +1,4 @@
|
|
1
|
-
local function get_time_bucket_from_timestamp(unix_time_milliseconds)
|
1
|
+
local function get_time_bucket_from_timestamp(unix_time_milliseconds, minutes_flag)
|
2
2
|
local function calculate_years_number_of_days(yr)
|
3
3
|
return (yr % 4 == 0 and (yr % 100 ~= 0 or yr % 400 == 0)) and 366 or 365
|
4
4
|
end
|
@@ -45,7 +45,12 @@ local function get_time_bucket_from_timestamp(unix_time_milliseconds)
|
|
45
45
|
local hours = math.floor(unix_time / 3600 % 24)
|
46
46
|
-- local minutes, seconds = math.floor(unix_time / 60 % 60), math.floor(unix_time % 60)
|
47
47
|
-- hours = hours > 12 and hours - 12 or hours == 0 and 12 or hours
|
48
|
-
|
48
|
+
if minutes_flag == false then
|
49
|
+
return string.format("%04d-%02d-%02d-%02d", year, month, days, hours)
|
50
|
+
elseif minutes_flag == true then
|
51
|
+
local minutes = math.floor(unix_time / 60 % 60)
|
52
|
+
return string.format("%04d-%02d-%02d-%02d-%02d", year, month, days, hours, minutes)
|
53
|
+
end
|
49
54
|
end
|
50
55
|
|
51
56
|
-- For: Relationship of IP to time of Request (Stream)
|
@@ -66,6 +71,17 @@ local function increment_timebucket_for(type, timebucket, property)
|
|
66
71
|
redis.call("ZINCRBY", type .. "leader-sset:" .. timebucket, 1, property)
|
67
72
|
end
|
68
73
|
|
74
|
+
local function increment_hourly_request_counters(unix_time_milliseconds)
|
75
|
+
for i = 1, 60 do
|
76
|
+
local timebucket_in_milliseconds = unix_time_milliseconds + 60000 * (i - 1)
|
77
|
+
local timebucket = get_time_bucket_from_timestamp(timebucket_in_milliseconds, true)
|
78
|
+
local key = "w:v0:hr-ct:" .. timebucket
|
79
|
+
redis.call("INCR", key)
|
80
|
+
-- Expire the key after 61 minutes if it has no expiry
|
81
|
+
redis.call("EXPIRE", key, 3660, "NX")
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
69
85
|
-- Configuration
|
70
86
|
local max_requests = 100000
|
71
87
|
local max_requests_per_ip = 10000
|
@@ -74,14 +90,16 @@ local client_ip = ARGV[1]
|
|
74
90
|
local client_ip_to_decimal = ARGV[2]
|
75
91
|
local unix_time_milliseconds = ARGV[3]
|
76
92
|
local unix_time = ARGV[3] / 1000
|
77
|
-
local
|
78
|
-
local
|
79
|
-
local
|
80
|
-
local host = ARGV[7]
|
93
|
+
local user_agent = ARGV[4]
|
94
|
+
local request_path = ARGV[5]
|
95
|
+
local host = ARGV[6]
|
81
96
|
|
82
97
|
-- Initialize local variables
|
83
98
|
local request_id = get_request_id(nil, client_ip, max_requests)
|
84
|
-
local current_timebucket = get_time_bucket_from_timestamp(unix_time_milliseconds)
|
99
|
+
local current_timebucket = get_time_bucket_from_timestamp(unix_time_milliseconds, false)
|
100
|
+
|
101
|
+
-- CARD DATA COLLECTION
|
102
|
+
increment_hourly_request_counters(unix_time_milliseconds)
|
85
103
|
|
86
104
|
-- GRAPH DATA COLLECTION
|
87
105
|
add_to_HLL_request_count(current_timebucket, request_id)
|
@@ -89,16 +107,11 @@ add_to_HLL_request_count(current_timebucket, request_id)
|
|
89
107
|
-- LEADERBOARD DATA COLLECTION
|
90
108
|
-- TODO: breaking change will to switch to client_ip: prefix
|
91
109
|
increment_timebucket_for(nil, current_timebucket, client_ip)
|
92
|
-
if proxy_ip ~= nil and proxy_ip ~= "" then
|
93
|
-
increment_timebucket_for("proxy_ip:", current_timebucket, proxy_ip)
|
94
|
-
end
|
95
110
|
increment_timebucket_for("user_agent:", current_timebucket, user_agent)
|
96
111
|
increment_timebucket_for("request_path:", current_timebucket, request_path)
|
97
112
|
increment_timebucket_for("host:", current_timebucket, host)
|
98
113
|
|
99
|
-
|
100
|
-
|
101
|
-
redis.breakpoint()
|
114
|
+
redis.call("ZRANGEBYSCORE", "blocked_ranges", client_ip_to_decimal, client_ip_to_decimal, "LIMIT", 0, 1)
|
102
115
|
|
103
116
|
-- BLOCKING LOGIC
|
104
117
|
-- TODO: ZRANGEBYSCORE is deprecated in Redis 6.2+. Replace with ZRANGE
|
data/lib/wafris/middleware.rb
CHANGED
@@ -7,6 +7,23 @@ module Wafris
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def call(env)
|
10
|
+
user_defined_proxies = ENV['MY_PROXIES'].split(',') if ENV['MY_PROXIES']
|
11
|
+
|
12
|
+
valid_ipv4_octet = /\.(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])/
|
13
|
+
|
14
|
+
trusted_proxies = Regexp.union(
|
15
|
+
/\A127#{valid_ipv4_octet}{3}\z/, # localhost IPv4 range 127.x.x.x, per RFC-3330
|
16
|
+
/\A::1\z/, # localhost IPv6 ::1
|
17
|
+
/\Af[cd][0-9a-f]{2}(?::[0-9a-f]{0,4}){0,7}\z/i, # private IPv6 range fc00 .. fdff
|
18
|
+
/\A10#{valid_ipv4_octet}{3}\z/, # private IPv4 range 10.x.x.x
|
19
|
+
/\A172\.(1[6-9]|2[0-9]|3[01])#{valid_ipv4_octet}{2}\z/, # private IPv4 range 172.16.0.0 .. 172.31.255.255
|
20
|
+
/\A192\.168#{valid_ipv4_octet}{2}\z/, # private IPv4 range 192.168.x.x
|
21
|
+
/\Alocalhost\z|\Aunix(\z|:)/i, # localhost hostname, and unix domain sockets
|
22
|
+
*user_defined_proxies
|
23
|
+
)
|
24
|
+
|
25
|
+
Rack::Request.ip_filter = lambda { |ip| trusted_proxies.match?(ip) }
|
26
|
+
|
10
27
|
request = Rack::Request.new(env)
|
11
28
|
|
12
29
|
if Wafris.configuration.enabled? && Wafris.allow_request?(request)
|
data/lib/wafris/version.rb
CHANGED
data/lib/wafris.rb
CHANGED
@@ -33,15 +33,13 @@ module Wafris
|
|
33
33
|
configuration.connection_pool.with do |conn|
|
34
34
|
time = Time.now.to_f * 1000
|
35
35
|
puts "WAF LOG: headers with http-x-forwarded-for key #{request.get_header(Rack::Request::HTTP_X_FORWARDED_FOR)}"
|
36
|
-
puts "WAF LOG: Client IP #{
|
37
|
-
puts "WAF LOG: Proxy IP #{proxy_ip(request)}"
|
36
|
+
puts "WAF LOG: Client IP #{request.ip}"
|
38
37
|
status = conn.evalsha(
|
39
38
|
configuration.core_sha,
|
40
39
|
argv: [
|
41
|
-
|
40
|
+
request.ip,
|
42
41
|
IPAddr.new(request.ip).to_i,
|
43
42
|
time.to_i,
|
44
|
-
proxy_ip(request),
|
45
43
|
request.user_agent,
|
46
44
|
request.path,
|
47
45
|
request.host
|
@@ -55,19 +53,5 @@ module Wafris
|
|
55
53
|
end
|
56
54
|
end
|
57
55
|
end
|
58
|
-
|
59
|
-
private
|
60
|
-
|
61
|
-
def client_ip(request)
|
62
|
-
return request.ip if request.get_header(Rack::Request::HTTP_X_FORWARDED_FOR).eql?(request.ip)
|
63
|
-
|
64
|
-
request.get_header(Rack::Request::HTTP_X_FORWARDED_FOR).split(',').first
|
65
|
-
end
|
66
|
-
|
67
|
-
def proxy_ip(request)
|
68
|
-
return nil if request.get_header(Rack::Request::HTTP_X_FORWARDED_FOR).eql?(request.ip)
|
69
|
-
|
70
|
-
request.get_header(Rack::Request::HTTP_X_FORWARDED_FOR).split(',').last
|
71
|
-
end
|
72
56
|
end
|
73
57
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wafris
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Micahel Buckbee
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2023-06-
|
12
|
+
date: 2023-06-20 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: connection_pool
|