wafris 0.5.4 → 0.7.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.
- 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
|