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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 16f5664939e2ff16c9741e4da47113d28535869a2f143d21fceca33caec7dbb7
4
- data.tar.gz: 54bc209bf0c7ee9d225d5623681a0d391599a51f2113343f5f9c5f3b57e044bd
3
+ metadata.gz: 8cbb8c27a7af9771ecf6c07a34fd7da75f4ebacf4fd21dba0b37551a8b2ca2cd
4
+ data.tar.gz: 492a0f193e4c976a612106b5a0bb8c25aa008f170ec8111fa9504bd1cf585faf
5
5
  SHA512:
6
- metadata.gz: e08b0d51693d3489cb5a225a50cb7241ab5f81571ef32f14c4c91cfabef861ed9fba3766477aac3d2baea81d46536c655b99d19715fb4cd496f608df43b15d85
7
- data.tar.gz: d024cbdfc8923d23b0ebe81080a0238f6741f971b0f7488db376291b5cbe3d585bda06ab7a6ad3547224a95c80e2e182434c28c1c483ed47c70300f16b226289
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
- return string.format("%04d-%02d-%02d-%02d", year, month, days, hours)
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 proxy_ip = ARGV[4]
78
- local user_agent = ARGV[5]
79
- local request_path = ARGV[6]
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
- local foobar = redis.call("ZRANGEBYSCORE", "blocked_ranges", client_ip_to_decimal, client_ip_to_decimal, "LIMIT", 0, 1)
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
@@ -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)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Wafris
4
- VERSION = "0.5.4"
4
+ VERSION = "0.7.0"
5
5
  end
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 #{client_ip(request)}"
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
- client_ip(request),
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.5.4
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-05 00:00:00.000000000 Z
12
+ date: 2023-06-20 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: connection_pool