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 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