wafris 2.1.2 → 2.3.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/wafris/configuration.rb +39 -71
- data/lib/wafris/version.rb +1 -1
- data/lib/wafris.rb +57 -41
- 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: 0fad1d400c6106dc0f2f29b6b46a0ab919f4060ef45a4bde4dbb8607b95c1cae
|
4
|
+
data.tar.gz: b3b854a117e0a7021bf3194e339da5f0acdf320439f973226e850249bc445dcd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bd8e5e8109a7aa1b51c1361d7c288d11e2cca0ea4a5c0e66a198bbde30d9835b57ce2711f2869c575cc604577b4fe927836bfb0e47764f4e08a4c39c2a2e82db
|
7
|
+
data.tar.gz: fb171df540399f4a128e9bd28a1f80c3aa41e6a97e3cccc5eae0f2fa13b1de86be516d227bce3582fc9cefb35eb067e1b4ced665e79e5af89672187195eac109
|
data/lib/wafris/configuration.rb
CHANGED
@@ -1,98 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require_relative "version"
|
2
4
|
|
3
5
|
module Wafris
|
4
6
|
class Configuration
|
5
|
-
attr_accessor :api_key
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
7
|
+
attr_accessor :api_key,
|
8
|
+
:db_file_path,
|
9
|
+
:db_file_name,
|
10
|
+
:downsync_custom_rules_interval,
|
11
|
+
:downsync_data_subscriptions_interval,
|
12
|
+
:downsync_url,
|
13
|
+
:upsync_url,
|
14
|
+
:upsync_interval,
|
15
|
+
:upsync_queue_limit,
|
16
|
+
:upsync_status,
|
17
|
+
:upsync_queue,
|
18
|
+
:local_only,
|
19
|
+
:last_upsync_timestamp,
|
20
|
+
:max_body_size_mb,
|
21
|
+
:rate_limiters
|
20
22
|
|
21
23
|
def initialize
|
22
|
-
|
23
|
-
if ENV["WAFRIS_API_KEY"]
|
24
|
-
@api_key = ENV["WAFRIS_API_KEY"]
|
25
|
-
else
|
26
|
-
unless @api_key
|
27
|
-
LogSuppressor.puts_log("Firewall disabled as neither local only or API key set")
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
# DB FILE PATH LOCATION - Optional
|
24
|
+
@api_key = ENV["WAFRIS_API_KEY"]
|
32
25
|
@db_file_path = ENV["WAFRIS_DB_FILE_PATH"] || "./tmp/wafris"
|
33
|
-
|
34
|
-
# Ensure that the db_file_path exists
|
35
|
-
unless File.directory?(@db_file_path)
|
36
|
-
LogSuppressor.puts_log("DB File Path does not exist - creating it now.")
|
37
|
-
FileUtils.mkdir_p(@db_file_path) unless File.exist?(@db_file_path)
|
38
|
-
end
|
39
|
-
|
40
|
-
# DB FILE NAME - For local
|
41
26
|
@db_file_name = ENV["WAFRIS_DB_FILE_NAME"] || "wafris.db"
|
42
|
-
|
43
|
-
# DOWNSYNC
|
44
|
-
# Custom Rules are checked often (default 1 minute) - Optional
|
45
27
|
@downsync_custom_rules_interval = ENV["WAFRIS_DOWNSYNC_CUSTOM_RULES_INTERVAL"]&.to_i || 60
|
46
|
-
|
47
|
-
# Data Subscriptions are checked rarely (default 1 day) - Optional
|
48
28
|
@downsync_data_subscriptions_interval = ENV["WAFRIS_DOWNSYNC_DATA_SUBSCRIPTIONS_INTERVAL"]&.to_i || 60
|
49
|
-
|
50
|
-
# Set Downsync URL - Optional
|
51
|
-
# Used for both DataSubscription and CustomRules
|
52
29
|
@downsync_url = ENV["WAFRIS_DOWNSYNC_URL"] || "https://distributor.wafris.org/v2/downsync"
|
53
|
-
|
54
|
-
# UPSYNC - Optional
|
55
|
-
# Set Upsync URL
|
56
30
|
@upsync_url = ENV["WAFRIS_UPSYNC_URL"] || "https://collector.wafris.org/v2/upsync"
|
57
|
-
|
58
|
-
# Set Upsync Interval - Optional
|
59
31
|
@upsync_interval = ENV["WAFRIS_UPSYNC_INTERVAL"]&.to_i || 10
|
60
|
-
|
61
|
-
# Set Upsync Queued Request Limit - Optional
|
62
32
|
@upsync_queue_limit = ENV["WAFRIS_UPSYNC_QUEUE_LIMIT"]&.to_i || 250
|
63
|
-
|
64
|
-
# Set Maximium Body Size for Requests - Optional (in Megabytes)
|
65
|
-
@max_body_size_mb = if ENV["WAFRIS_MAX_BODY_SIZE_MB"] && ENV["WAFRIS_MAX_BODY_SIZE_MB"].to_i > 0
|
66
|
-
ENV["WAFRIS_MAX_BODY_SIZE_MB"].to_i
|
67
|
-
else
|
68
|
-
10
|
69
|
-
end
|
70
|
-
|
71
|
-
# Upsync Queue Defaults
|
33
|
+
@max_body_size_mb = set_max_body_size
|
72
34
|
@upsync_queue = []
|
73
35
|
@last_upsync_timestamp = Time.now.to_i
|
74
|
-
|
75
|
-
# Memory structure for rate limiting
|
76
36
|
@rate_limiters = {}
|
77
|
-
|
78
|
-
# Disable Upsync if Downsync API Key is invalid
|
79
|
-
# This prevents the client from sending upsync requests
|
80
|
-
# if the API key is known bad
|
81
37
|
@upsync_status = "Disabled"
|
82
38
|
end
|
83
39
|
|
84
|
-
def
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
40
|
+
def setup
|
41
|
+
if @api_key
|
42
|
+
create_db_file_path
|
43
|
+
else
|
44
|
+
LogSuppressor.puts_log("Firewall disabled as API key is not set.")
|
89
45
|
end
|
46
|
+
end
|
90
47
|
|
91
|
-
|
48
|
+
private
|
49
|
+
|
50
|
+
def set_max_body_size
|
51
|
+
if ENV["WAFRIS_MAX_BODY_SIZE_MB"] && ENV["WAFRIS_MAX_BODY_SIZE_MB"].to_i > 0
|
52
|
+
ENV["WAFRIS_MAX_BODY_SIZE_MB"].to_i
|
53
|
+
else
|
54
|
+
10
|
55
|
+
end
|
92
56
|
end
|
93
57
|
|
94
|
-
def
|
95
|
-
|
58
|
+
def create_db_file_path
|
59
|
+
# Ensure that the db_file_path exists
|
60
|
+
unless File.directory?(@db_file_path)
|
61
|
+
LogSuppressor.puts_log("DB File Path does not exist - creating it now.")
|
62
|
+
FileUtils.mkdir_p(@db_file_path) unless File.exist?(@db_file_path)
|
63
|
+
end
|
96
64
|
end
|
97
65
|
end
|
98
66
|
end
|
data/lib/wafris/version.rb
CHANGED
data/lib/wafris.rb
CHANGED
@@ -34,12 +34,18 @@ module Wafris
|
|
34
34
|
|
35
35
|
def configure
|
36
36
|
self.configuration ||= Wafris::Configuration.new
|
37
|
-
|
37
|
+
if block_given?
|
38
|
+
yield(configuration)
|
39
|
+
LogSuppressor.puts_log("Configuration settings created with configure block.")
|
40
|
+
else
|
41
|
+
LogSuppressor.puts_log("Configuration settings created with defaults and ENV vars.")
|
42
|
+
end
|
38
43
|
|
39
|
-
|
40
|
-
|
44
|
+
configuration.setup
|
45
|
+
|
46
|
+
return configuration
|
41
47
|
rescue => e
|
42
|
-
|
48
|
+
LogSuppressor.puts_log("Firewall disabled due to: #{e.message}. Please check your configuration settings.")
|
43
49
|
end
|
44
50
|
|
45
51
|
def zero_pad(number, length)
|
@@ -181,20 +187,25 @@ module Wafris
|
|
181
187
|
|
182
188
|
url_and_api_key = @configuration.upsync_url + "/" + @configuration.api_key
|
183
189
|
|
190
|
+
LogSuppressor.puts_log("[Upsync] Beginning request thread...")
|
191
|
+
current_time = Time.now
|
184
192
|
response = HTTParty.post(
|
185
193
|
url_and_api_key,
|
186
194
|
body: body,
|
187
195
|
headers: headers,
|
188
|
-
timeout:
|
196
|
+
timeout: 5
|
189
197
|
)
|
190
198
|
|
191
199
|
if response.code == 200
|
192
200
|
@configuration.upsync_status = "Complete"
|
193
201
|
else
|
194
|
-
LogSuppressor.puts_log("Upsync Error. HTTP Response: #{response.code}")
|
202
|
+
LogSuppressor.puts_log("[Upsync] Error. HTTP Response: #{response.code}")
|
195
203
|
end
|
196
204
|
rescue HTTParty::Error => e
|
197
|
-
LogSuppressor.puts_log("Upsync Error. Failed to send upsync requests: #{e.message}")
|
205
|
+
LogSuppressor.puts_log("[Upsync] Thread Error. Failed to send upsync requests: #{e.message}")
|
206
|
+
ensure
|
207
|
+
elapsed_time = Time.now - current_time
|
208
|
+
LogSuppressor.puts_log("[Upsync] request thread complete in #{elapsed_time.round(2)} seconds.")
|
198
209
|
end
|
199
210
|
|
200
211
|
# This method is used to queue upsync requests. It takes in several parameters including:
|
@@ -220,7 +231,7 @@ module Wafris
|
|
220
231
|
@configuration.upsync_queue = []
|
221
232
|
@configuration.last_upsync_timestamp = Time.now.to_i
|
222
233
|
|
223
|
-
send_upsync_requests(requests_array)
|
234
|
+
Thread.new { send_upsync_requests(requests_array) }
|
224
235
|
end
|
225
236
|
|
226
237
|
@configuration.upsync_status = "Enabled"
|
@@ -249,10 +260,10 @@ module Wafris
|
|
249
260
|
begin
|
250
261
|
lockfile = File.open(lockfile_path, File::RDWR | File::CREAT | File::EXCL)
|
251
262
|
rescue Errno::EEXIST
|
252
|
-
LogSuppressor.puts_log("[
|
263
|
+
LogSuppressor.puts_log("[Downsync][downsync_db] Lockfile already exists, skipping downsync.")
|
253
264
|
return
|
254
265
|
rescue Exception => e
|
255
|
-
LogSuppressor.puts_log("[
|
266
|
+
LogSuppressor.puts_log("[Downsync] Error creating lockfile: #{e.message}")
|
256
267
|
end
|
257
268
|
|
258
269
|
begin
|
@@ -274,10 +285,14 @@ module Wafris
|
|
274
285
|
# puts "Downloading from #{@configuration.downsync_url}/#{db_rule_category}/#{@configuration.api_key}?current_version=#{current_filename}&process_id=#{Process.pid}"
|
275
286
|
uri = "#{@configuration.downsync_url}/#{db_rule_category}/#{@configuration.api_key}?#{data.to_query}"
|
276
287
|
|
288
|
+
LogSuppressor.puts_log("[Downsync] Beginning request thread for #{db_rule_category}...")
|
289
|
+
current_time = Time.now
|
290
|
+
|
277
291
|
response = HTTParty.get(
|
278
292
|
uri,
|
279
293
|
follow_redirects: true, # Enable following redirects
|
280
|
-
max_redirects: 2
|
294
|
+
max_redirects: 2, # Maximum number of redirects to follow
|
295
|
+
timeout: 30
|
281
296
|
)
|
282
297
|
|
283
298
|
# TODO: What to do if timeout
|
@@ -285,13 +300,12 @@ module Wafris
|
|
285
300
|
|
286
301
|
if response.code == 401
|
287
302
|
@configuration.upsync_status = "Disabled"
|
288
|
-
LogSuppressor.puts_log("[
|
289
|
-
LogSuppressor.puts_log("[
|
303
|
+
LogSuppressor.puts_log("[Downsync] Unauthorized: Bad or missing API key")
|
304
|
+
LogSuppressor.puts_log("[Downsync] API Key: #{@configuration.api_key}")
|
290
305
|
filename = current_filename
|
291
306
|
|
292
307
|
elsif response.code == 304
|
293
308
|
@configuration.upsync_status = "Enabled"
|
294
|
-
LogSuppressor.puts_log("[Wafris][Downsync] No new rules to download")
|
295
309
|
|
296
310
|
filename = current_filename
|
297
311
|
|
@@ -326,12 +340,12 @@ module Wafris
|
|
326
340
|
# DB file is bad or empty so keep using whatever we have now
|
327
341
|
else
|
328
342
|
filename = old_file_name
|
329
|
-
LogSuppressor.puts_log("[
|
343
|
+
LogSuppressor.puts_log("[Downsync] DB Error - No tables exist in the db file #{@configuration.db_file_path}/#{filename}")
|
330
344
|
end
|
331
345
|
|
332
346
|
end
|
333
347
|
rescue => e
|
334
|
-
LogSuppressor.puts_log("[
|
348
|
+
LogSuppressor.puts_log("[Downsync] Error downloading rules: #{e.message}")
|
335
349
|
|
336
350
|
# This gets set even if the API key is bad or other issues
|
337
351
|
# to prevent hammering the distribution server on every request
|
@@ -347,42 +361,47 @@ module Wafris
|
|
347
361
|
# Ensure the lockfile is removed after operations
|
348
362
|
lockfile.close
|
349
363
|
File.delete(lockfile_path)
|
364
|
+
|
365
|
+
elapsed_time = Time.now - current_time
|
366
|
+
LogSuppressor.puts_log("[Downsync] request thread complete in #{elapsed_time.round(2)} seconds for #{db_rule_category}.")
|
350
367
|
end
|
351
368
|
|
352
369
|
filename
|
353
370
|
end
|
354
371
|
|
372
|
+
def sync_interval(db_rule_category)
|
373
|
+
if db_rule_category == "custom_rules"
|
374
|
+
@configuration.downsync_custom_rules_interval
|
375
|
+
else
|
376
|
+
@configuration.downsync_data_subscriptions_interval
|
377
|
+
end
|
378
|
+
end
|
379
|
+
|
355
380
|
# Returns the current database file,
|
356
381
|
# if the file is older than the interval, it will download the latest db
|
357
382
|
# if the file doesn't exist, it will download the latest db
|
358
383
|
# if the lockfile exists, it will return the current db
|
359
384
|
def current_db(db_rule_category)
|
360
|
-
interval = if db_rule_category == "custom_rules"
|
361
|
-
@configuration.downsync_custom_rules_interval
|
362
|
-
else
|
363
|
-
@configuration.downsync_data_subscriptions_interval
|
364
|
-
end
|
365
|
-
|
366
385
|
# Checks for existing current modfile, which contains the current db filename
|
367
386
|
if File.exist?("#{@configuration.db_file_path}/#{db_rule_category}.modfile")
|
368
387
|
|
369
|
-
LogSuppressor.puts_log("[
|
388
|
+
LogSuppressor.puts_log("[Downsync] Modfile exists, skipping downsync")
|
370
389
|
|
371
390
|
# Get last Modified Time and current database file name
|
372
391
|
last_db_synctime = File.mtime("#{@configuration.db_file_path}/#{db_rule_category}.modfile").to_i
|
373
392
|
returned_db = File.read("#{@configuration.db_file_path}/#{db_rule_category}.modfile").strip
|
374
393
|
|
375
|
-
LogSuppressor.puts_log("[
|
376
|
-
LogSuppressor.puts_log("[
|
394
|
+
LogSuppressor.puts_log("[Downsync] Modfile Last Modified Time: #{last_db_synctime}")
|
395
|
+
LogSuppressor.puts_log("[Downsync] DB in Modfile: #{returned_db}")
|
377
396
|
|
378
397
|
# Check if the db file is older than the interval
|
379
|
-
if (Time.now.to_i - last_db_synctime) >
|
398
|
+
if (Time.now.to_i - last_db_synctime) > sync_interval(db_rule_category)
|
380
399
|
|
381
|
-
LogSuppressor.puts_log("[
|
400
|
+
LogSuppressor.puts_log("[Downsync] DB is older than the interval")
|
382
401
|
|
383
402
|
# Make sure that another process isn't already downloading the rules
|
384
403
|
if !File.exist?("#{@configuration.db_file_path}/#{db_rule_category}.lockfile")
|
385
|
-
|
404
|
+
Thread.new { downsync_db(db_rule_category, returned_db) }
|
386
405
|
end
|
387
406
|
|
388
407
|
returned_db
|
@@ -390,7 +409,7 @@ module Wafris
|
|
390
409
|
# Current db is up to date
|
391
410
|
else
|
392
411
|
|
393
|
-
LogSuppressor.puts_log("[
|
412
|
+
LogSuppressor.puts_log("[Downsync] DB is up to date")
|
394
413
|
|
395
414
|
returned_db = File.read("#{@configuration.db_file_path}/#{db_rule_category}.modfile").strip
|
396
415
|
|
@@ -407,24 +426,18 @@ module Wafris
|
|
407
426
|
# No modfile exists, so download the latest db
|
408
427
|
else
|
409
428
|
|
410
|
-
LogSuppressor.puts_log("[
|
429
|
+
LogSuppressor.puts_log("[Downsync] No modfile exists, downloading latest #{db_rule_category} db")
|
411
430
|
|
412
431
|
# Make sure that another process isn't already downloading the rules
|
413
432
|
if File.exist?("#{@configuration.db_file_path}/#{db_rule_category}.lockfile")
|
414
|
-
LogSuppressor.puts_log("[
|
433
|
+
LogSuppressor.puts_log("[Downsync][current_db] Lockfile exists, skipping downsync")
|
415
434
|
# Lockfile exists, but no modfile with a db filename
|
416
435
|
nil
|
417
436
|
else
|
418
|
-
|
419
|
-
LogSuppressor.puts_log("[Wafris][Downsync] No modfile exists, downloading latest db")
|
420
437
|
# No modfile exists, so download the latest db
|
421
|
-
|
438
|
+
Thread.new { downsync_db(db_rule_category, nil) }
|
422
439
|
|
423
|
-
|
424
|
-
nil
|
425
|
-
else
|
426
|
-
returned_db
|
427
|
-
end
|
440
|
+
nil
|
428
441
|
end
|
429
442
|
end
|
430
443
|
end
|
@@ -432,15 +445,18 @@ module Wafris
|
|
432
445
|
# This is the main loop that evaluates the request
|
433
446
|
# as well as sorts out when downsync and upsync should be called
|
434
447
|
def evaluate(request)
|
435
|
-
@configuration
|
448
|
+
if @configuration.nil?
|
449
|
+
configure
|
450
|
+
end
|
436
451
|
|
437
452
|
return "Passed" if @configuration.api_key.nil?
|
438
453
|
|
454
|
+
# Now current_db can return the actual db, nil, or a future object
|
439
455
|
rules_db_filename = current_db("custom_rules")
|
440
456
|
data_subscriptions_db_filename = current_db("data_subscriptions")
|
441
457
|
|
442
458
|
# Checks to see if the filenames are present before loading the db
|
443
|
-
if rules_db_filename.to_s.strip != "" && data_subscriptions_db_filename.
|
459
|
+
if rules_db_filename.to_s.strip != "" && data_subscriptions_db_filename.to_s.strip != ""
|
444
460
|
|
445
461
|
rules_db = SQLite3::Database.new "#{@configuration.db_file_path}/#{rules_db_filename}"
|
446
462
|
data_subscriptions_db =
|
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: 2.
|
4
|
+
version: 2.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Buckbee
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2024-11-
|
12
|
+
date: 2024-11-29 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rack
|