immunio 1.1.7 → 1.1.10

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
  SHA1:
3
- metadata.gz: b00b1a9669f4e9f0ec6b571a88b2d1df883cbf94
4
- data.tar.gz: 6fdf549ca4de7c8bf912a1fdcaf7bc00521c4e4b
3
+ metadata.gz: 8c73cecf0da251ae6c4e8fc65c1215a84cca2a9a
4
+ data.tar.gz: cc1742b1789f90dce3c6a2ad8a698c7e4e4730da
5
5
  SHA512:
6
- metadata.gz: d947098d70f20d0a073789d8742570bb64373fce01429f2207133ac603d612d25534dd362dad87ebfacb57ed0bde6c34038355e336238b28b42a0678bed42f7d
7
- data.tar.gz: f4a9b98cce16ba098561bb64bafcadf5fe50f1f9becbbc87549c5df9234f1f55062715274a59c44eadcb37088dc60a19bfe61ce44d59214f5056e9d733579b62
6
+ metadata.gz: 6ba46ef732b848a7bddce203578b91b801ad5c8571b5b49443c300b9f74bcbba3519ecffac8e0bd25476e2de40d7d8b8f16ae4a4bc45cf4aa93f3d26270c7291
7
+ data.tar.gz: d127335b24855d7b3cdd4725bca45b946e13d5712bc203fa972d0c79b16e719986b3d1c114bcb12df6ece8524c0af032c79f7fffd4ec46208dd03bb90d738c43
data/README.md CHANGED
@@ -39,6 +39,25 @@ gem immunio', group: :production
39
39
 
40
40
  You can also modify the secret and key for different environments to report to different apps, or you can disable the agent by setting `agent_enabled: false` in the configuration or `IMMUNIO_AGENT_ENABLED=0` in the environment.
41
41
 
42
+
43
+ ### Unicorn configuration
44
+
45
+ In order for the agent to function correctly in a pre-forked environment, use the `Immunio.reset!` method.
46
+ For example, in your `config/unicorn.rb`:
47
+
48
+ ```
49
+ after_fork do |server, worker|
50
+ Signal.trap 'TERM' do
51
+ puts 'Unicorn worker intercepting TERM and doing nothing. Wait for master to send QUIT'
52
+ end
53
+
54
+ defined?(ActiveRecord::Base) and ActiveRecord::Base.establish_connection
55
+
56
+ Immunio.reset!
57
+ end
58
+ ```
59
+
60
+
42
61
  ## Handling blocked requests
43
62
 
44
63
  By default, Immunio will return a plain text *403 Forbidden* response whenever it blocks a request for security reasons.
@@ -55,6 +74,7 @@ Immunio.blocked_app = -> env do
55
74
  end
56
75
  ```
57
76
 
77
+
58
78
  ## Authentication API
59
79
 
60
80
  If you're using [Devise](https://github.com/plataformatec/devise) or [Authlogic](https://github.com/binarylogic/authlogic), Immunio will automatically hook into your authentication system to protect you against attacks.
@@ -26,6 +26,10 @@ module Immunio
26
26
  # Load and activate Rails engine
27
27
  require_relative "immunio/rails"
28
28
  end
29
+
30
+ def self.reset!
31
+ agent.reset if agent
32
+ end
29
33
  end
30
34
 
31
35
  Immunio.activate!
@@ -153,6 +153,7 @@ module Immunio
153
153
  end
154
154
 
155
155
  @processor = Processor.new(@channel, @vmfactory, config)
156
+ @process_id = Process.pid
156
157
  end
157
158
 
158
159
  def load_config
@@ -17,6 +17,7 @@ module Immunio
17
17
  attr_reader :rejected_message_count
18
18
 
19
19
  def initialize(config)
20
+ Immunio.logger.debug { "Creating channel" }
20
21
  @config = config
21
22
 
22
23
  @agent_uuid = nil
@@ -42,6 +43,13 @@ module Immunio
42
43
  @started = false
43
44
  @ready = false
44
45
 
46
+ # In the case of a forking web server like Unicorn,
47
+ # we need to remember the process id because it may
48
+ # happen that the master process starts its polling
49
+ # thread first, for example when a request is sent
50
+ # before forking the workers.
51
+ @process_id = Process.pid
52
+
45
53
  @callbacks = []
46
54
 
47
55
  # Anything looking to add to the messages sent to the server:
@@ -67,8 +75,18 @@ module Immunio
67
75
  def start
68
76
  return if @started
69
77
 
78
+ Immunio.logger.debug { "Starting channel" }
79
+
80
+ Immunio.logger.trace { "Thread count is: #{Thread.list.size}" }
81
+ Immunio.logger.trace { "Threads: #{Thread.list.map(&:object_id)}" }
82
+ Immunio.logger.trace { "@thread in thread list?: #{Thread.list.include? @thread}" }
83
+ Immunio.logger.trace { "@process_id is: #{@process_id}" }
84
+ Immunio.logger.trace { "@thread is: #{@thread.inspect}" }
85
+
70
86
  @started = true
71
87
  @thread = Thread.new { run }
88
+
89
+ Immunio.logger.trace { "Thread count is now: #{Thread.list.size}" }
72
90
  end
73
91
 
74
92
  # Stop and wait for the last messages to be sent.
@@ -86,22 +104,45 @@ module Immunio
86
104
  end
87
105
  end
88
106
 
107
+ def needs_reset?
108
+ @process_id != Process.pid
109
+ end
110
+
111
+ def reset
112
+ Immunio.logger.debug { "Resetting channel" }
113
+
114
+ stop
115
+
116
+ @process_id = Process.pid
117
+ @message_queue.clear
118
+ end
119
+
89
120
  def send_message(message)
90
121
  send_encoded_message message.to_msgpack
91
122
  end
92
123
 
93
124
  def send_encoded_message(message)
125
+ Immunio.logger.debug do
126
+ "Queueing message: (queue size: #{@message_queue.size}, max: #{@config.max_send_queue_size})"
127
+ end
128
+
94
129
  if @message_queue.size > @config.max_send_queue_size
95
130
  Immunio.logger.warn { "Dropping message for agent manager due to queue overflow (#{@message_queue.size} > #{@config.max_send_queue_size})" }
96
- Immunio.logger.debug { "Dropped message: (#{message})" }
97
131
  # No room for this message on the queue. Discard.
98
132
  @dropped_message_count += 1
133
+ Immunio.logger.debug { "Dropped message: (#{message}, dropped count: #{@dropped_message_count})" }
99
134
  return
100
135
  end
101
136
 
102
- Immunio.logger.debug {"Sending message to backend: #{MessagePack.unpack(message)}"}
137
+ Immunio.logger.debug do
138
+ "Queueing message: message.size: #{message.size}, #{MessagePack.unpack(message)}"
139
+ end
103
140
 
104
141
  @message_queue << message
142
+
143
+ Immunio.logger.debug do
144
+ "Queueing message: (queue size now: #{@message_queue.size}, max: #{@config.max_send_queue_size})"
145
+ end
105
146
  end
106
147
 
107
148
  def on_message(&block)
@@ -140,6 +181,7 @@ module Immunio
140
181
  # Core method running in a thread
141
182
  def run
142
183
  Immunio.logger.debug { "Starting channel on thread #{Thread.current.object_id}" }
184
+
143
185
  # Create an empty cert_store to prevent Faraday from using the system default OpenSSL store.
144
186
  cert_store = OpenSSL::X509::Store.new
145
187
  # Setup the connection for making requests to the server.
@@ -263,8 +305,10 @@ module Immunio
263
305
  end
264
306
 
265
307
  def add_to_send_buffer(message)
308
+ Immunio.logger.debug { "Adding message to send buffer (bytesize: #{message.bytesize})" }
266
309
  @send_buffer_bytes += message.bytesize
267
310
  @send_buffer << message
311
+ Immunio.logger.debug { "Adding message to send buffer (send buffer size: #{@send_buffer.size})" }
268
312
  end
269
313
 
270
314
  # Fill send_buffer with messages to send
@@ -276,8 +320,10 @@ module Immunio
276
320
  add_to_send_buffer @next_message
277
321
  else
278
322
  Immunio.logger.warn { "Dropped message over max byte send size, next message size #{@next_message.bytesize}" }
279
- Immunio.logger.debug { "Dropped next message used: #{used_bytes} over max byte: #{@next_message}" }
280
323
  @dropped_message_count += 1
324
+ Immunio.logger.debug do
325
+ "Dropped next message (used: #{used_bytes} over max byte: #{@next_message}, dropped count: #{@dropped_message_count})"
326
+ end
281
327
  end
282
328
  @next_message = nil
283
329
  end
@@ -285,6 +331,9 @@ module Immunio
285
331
  # Empty the queue as much as possible.
286
332
  while !@message_queue.empty?
287
333
  @next_message = @message_queue.pop
334
+
335
+ Immunio.logger.debug { "Emptying message queue: (queue size: #{@message_queue.size})" }
336
+
288
337
  if !send_buffer_has_room used_bytes
289
338
  break
290
339
  end
@@ -303,6 +352,9 @@ module Immunio
303
352
  while @send_buffer.size < @config.min_report_size
304
353
  # If there are no messages in the queue, this will block until one arrives.
305
354
  @next_message = @message_queue.pop
355
+
356
+ Immunio.logger.debug { "Waiting for messages: (queue size: #{@message_queue.size})" }
357
+
306
358
  if !send_buffer_has_room used_bytes
307
359
  break
308
360
  end
@@ -329,6 +381,8 @@ module Immunio
329
381
 
330
382
  # Poll the server sending queued messages at the same time.
331
383
  def poll
384
+ Immunio.logger.trace { "Polling" }
385
+
332
386
  # Prep data
333
387
  body = {
334
388
  send_seq: @send_seq,
@@ -382,28 +436,35 @@ module Immunio
382
436
 
383
437
  req.body = gzip(encoded_body)
384
438
 
439
+ Immunio.logger.debug do
440
+ "Sending request to agent manager (size: #{req.body.size})"
441
+ end
385
442
  Immunio.logger.trace {"Sending request to agent manager (data: #{MessagePack.unpack(encoded_body)}, request: #{req})"}
386
443
  end
387
444
 
388
445
  if response.status >= 400 and response.status < 500 then
389
446
  # 4XX response codes should NOT be retried. Discard the report.
390
447
  @rejected_message_count += @send_buffer.size
448
+ Immunio.logger.debug { "Rejected message count is: #{@rejected_message_count}" }
391
449
  Immunio.logger.trace { "Rejecting #{@send_buffer.size} messages" }
392
450
  @send_buffer = []
393
451
  @send_buffer_bytes = 0
394
452
 
453
+ Immunio.logger.debug {"Received response from agent manager (status: #{response.status})"}
395
454
  Immunio.logger.trace {"Received response from agent manager (status: #{response.status}, raw body: #{raw_log response.body})"}
396
455
  raise Error, "Bad response from Immunio server: #{response.status} #{response.body}"
397
456
  end
398
457
 
399
458
  if response.status >= 500 then
400
459
  # 5XX response codes are treated like errors.
460
+ Immunio.logger.debug {"Received response from agent manager (status: #{response.status})"}
401
461
  Immunio.logger.trace {"Received response from agent manager (status: #{response.status}, raw body: #{raw_log response.body})"}
402
462
  raise Error, "Bad response from Immunio server: #{response.status} #{response.body}"
403
463
  end
404
464
 
405
465
  body = MessagePack.unpack(response.body)
406
466
 
467
+ Immunio.logger.debug {"Received response from agent manager (status: #{response.status})"}
407
468
  Immunio.logger.trace {"Received response from agent manager (status: #{response.status}, body: #{body}, raw body: #{raw_log response.body})"}
408
469
 
409
470
  # Update local data from response
@@ -426,7 +487,6 @@ module Immunio
426
487
  if received_messages
427
488
  received_messages.each { |message| notify message }
428
489
  end
429
-
430
490
  end
431
491
  end
432
492
  end
@@ -34,7 +34,7 @@ module Immunio
34
34
 
35
35
  def self.setup_logger_formatter
36
36
  logger.formatter = proc do |severity, datetime, _progname, msg|
37
- "[#{datetime}] #{severity}: #{msg}\n"
37
+ "[#{datetime}] [#{Process.pid} (#{Thread.current.object_id})]: #{severity}: #{msg}\n"
38
38
  end
39
39
  end
40
40
 
@@ -50,6 +50,11 @@ module Immunio
50
50
  end
51
51
 
52
52
  def new_request(request)
53
+ Immunio.logger.debug { "New request: (started: #{@channel.started?})" }
54
+
55
+ # Reset channel if it was created by parent process
56
+ @channel.reset if @channel.needs_reset?
57
+
53
58
  # Start channel on first request
54
59
  @channel.start unless @channel.started?
55
60
 
@@ -1,5 +1,5 @@
1
1
  module Immunio
2
2
  AGENT_TYPE = "agent-ruby"
3
- VERSION = "1.1.7"
3
+ VERSION = "1.1.10"
4
4
  VM_VERSION = "2.2.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: immunio
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.7
4
+ version: 1.1.10
5
5
  platform: ruby
6
6
  authors:
7
7
  - Immunio
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-01-16 00:00:00.000000000 Z
11
+ date: 2017-02-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails