tcell_agent 2.0.0 → 2.5.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/LICENSE +2 -2
- data/bin/tcell_agent +41 -150
- data/lib/tcell_agent/agent.rb +87 -52
- data/lib/tcell_agent/config_initializer.rb +63 -0
- data/lib/tcell_agent/configuration.rb +72 -267
- data/lib/tcell_agent/hooks/login_fraud.rb +1 -1
- data/lib/tcell_agent/instrument_servers.rb +14 -18
- data/lib/tcell_agent/instrumentation/cmdi.rb +47 -15
- data/lib/tcell_agent/instrumentation/lfi.rb +72 -15
- data/lib/tcell_agent/instrumentation/monkey_patches/ruby_2/file.rb +21 -0
- data/lib/tcell_agent/instrumentation/monkey_patches/ruby_2/io.rb +75 -0
- data/lib/tcell_agent/instrumentation/monkey_patches/ruby_2/kernel.rb +80 -0
- data/lib/tcell_agent/instrumentation/monkey_patches/ruby_3/file.rb +21 -0
- data/lib/tcell_agent/instrumentation/monkey_patches/ruby_3/io.rb +75 -0
- data/lib/tcell_agent/instrumentation/monkey_patches/ruby_3/kernel.rb +80 -0
- data/lib/tcell_agent/instrumentation.rb +14 -6
- data/lib/tcell_agent/logger.rb +3 -4
- data/lib/tcell_agent/policies/command_injection_policy.rb +1 -1
- data/lib/tcell_agent/policies/dataloss_policy.rb +15 -8
- data/lib/tcell_agent/policies/headers_policy.rb +2 -2
- data/lib/tcell_agent/policies/patches_policy.rb +8 -4
- data/lib/tcell_agent/policies/policies_manager.rb +1 -0
- data/lib/tcell_agent/policies/policy_polling.rb +4 -3
- data/lib/tcell_agent/rails/auth/authlogic.rb +49 -44
- data/lib/tcell_agent/rails/auth/authlogic_helper.rb +20 -0
- data/lib/tcell_agent/rails/auth/devise.rb +103 -102
- data/lib/tcell_agent/rails/auth/devise_helper.rb +29 -0
- data/lib/tcell_agent/rails/auth/doorkeeper.rb +54 -57
- data/lib/tcell_agent/{userinfo.rb → rails/auth/userinfo.rb} +0 -0
- data/lib/tcell_agent/rails/better_ip.rb +7 -19
- data/lib/tcell_agent/rails/csrf_exception.rb +0 -8
- data/lib/tcell_agent/rails/dlp/process_request.rb +5 -0
- data/lib/tcell_agent/rails/dlp.rb +58 -56
- data/lib/tcell_agent/rails/dlp_handler.rb +9 -10
- data/lib/tcell_agent/rails/js_agent_insert.rb +2 -3
- data/lib/tcell_agent/rails/middleware/context_middleware.rb +2 -1
- data/lib/tcell_agent/rails/middleware/global_middleware.rb +3 -4
- data/lib/tcell_agent/rails/middleware/headers_middleware.rb +1 -0
- data/lib/tcell_agent/rails/{on_start.rb → railties/tcell_agent_railties.rb} +9 -16
- data/lib/tcell_agent/rails/railties/tcell_agent_unicorn_railties.rb +8 -0
- data/lib/tcell_agent/rails/routes/grape.rb +5 -12
- data/lib/tcell_agent/rails/routes.rb +6 -9
- data/lib/tcell_agent/rails/settings_reporter.rb +3 -6
- data/lib/tcell_agent/rails/tcell_body_proxy.rb +4 -7
- data/lib/tcell_agent/routes/table.rb +3 -0
- data/lib/tcell_agent/rust/agent_config.rb +62 -33
- data/lib/tcell_agent/rust/{libtcellagent-4.14.0.so → libtcellagent-alpine.so} +0 -0
- data/lib/tcell_agent/rust/{libtcellagent-4.14.0.dylib → libtcellagent-x64.dll} +0 -0
- data/lib/tcell_agent/rust/{libtcellagent-alpine-4.14.0.so → libtcellagent.dylib} +0 -0
- data/lib/tcell_agent/rust/libtcellagent.so +0 -0
- data/lib/tcell_agent/rust/models.rb +9 -0
- data/lib/tcell_agent/rust/native_agent.rb +61 -51
- data/lib/tcell_agent/rust/native_library.rb +8 -10
- data/lib/tcell_agent/sensor_events/server_agent.rb +3 -100
- data/lib/tcell_agent/sensor_events/util/sanitizer_utilities.rb +1 -0
- data/lib/tcell_agent/servers/puma.rb +30 -13
- data/lib/tcell_agent/servers/rack_puma_handler.rb +33 -0
- data/lib/tcell_agent/servers/rails_server.rb +4 -4
- data/lib/tcell_agent/servers/unicorn.rb +1 -1
- data/lib/tcell_agent/servers/webrick.rb +12 -3
- data/lib/tcell_agent/settings_reporter.rb +0 -93
- data/lib/tcell_agent/sinatra.rb +1 -0
- data/lib/tcell_agent/tcell_context.rb +16 -7
- data/lib/tcell_agent/utils/headers.rb +0 -1
- data/lib/tcell_agent/utils/strings.rb +2 -2
- data/lib/tcell_agent/version.rb +1 -1
- data/lib/tcell_agent.rb +8 -16
- data/spec/cruby_spec_helper.rb +26 -0
- data/spec/lib/tcell_agent/configuration_spec.rb +62 -212
- data/spec/lib/tcell_agent/instrument_servers_spec.rb +95 -0
- data/spec/lib/tcell_agent/instrumentation/cmdi/io_cmdi_spec.rb +2 -2
- data/spec/lib/tcell_agent/{cmdi_spec.rb → instrumentation/cmdi_spec.rb} +50 -0
- data/spec/lib/tcell_agent/instrumentation/lfi/file_lfi_spec.rb +211 -272
- data/spec/lib/tcell_agent/instrumentation/lfi/io_lfi_spec.rb +213 -223
- data/spec/lib/tcell_agent/instrumentation/lfi/kernel_lfi_spec.rb +95 -61
- data/spec/lib/tcell_agent/instrumentation/lfi_spec.rb +120 -2
- data/spec/lib/tcell_agent/patches_spec.rb +2 -1
- data/spec/lib/tcell_agent/policies/clickjacking_policy_spec.rb +1 -2
- data/spec/lib/tcell_agent/policies/content_security_policy_spec.rb +5 -6
- data/spec/lib/tcell_agent/policies/patches_policy_spec.rb +21 -2
- data/spec/lib/tcell_agent/policies/policies_manager_spec.rb +1 -1
- data/spec/lib/tcell_agent/policies/secure_headers_policy_spec.rb +13 -8
- data/spec/lib/tcell_agent/rails/better_ip_spec.rb +9 -11
- data/spec/lib/tcell_agent/rails/csrf_exception_spec.rb +6 -6
- data/spec/lib/tcell_agent/rails/dlp_spec.rb +1 -0
- data/spec/lib/tcell_agent/rails/js_agent_insert_spec.rb +10 -2
- data/spec/lib/tcell_agent/rails/middleware/tcell_body_proxy_spec.rb +2 -1
- data/spec/lib/tcell_agent/rails/routes/route_id_spec.rb +4 -4
- data/spec/lib/tcell_agent/rust/agent_config_spec.rb +27 -0
- data/spec/lib/tcell_agent/settings_reporter_spec.rb +2 -89
- data/spec/lib/tcell_agent/tcell_context_spec.rb +6 -5
- data/spec/spec_helper.rb +9 -1
- data/spec/support/builders.rb +8 -7
- data/spec/support/server_mocks/passenger_mock.rb +7 -0
- data/spec/support/server_mocks/puma_mock.rb +21 -0
- data/spec/support/server_mocks/rails_mock.rb +7 -0
- data/spec/support/server_mocks/thin_mock.rb +7 -0
- data/spec/support/server_mocks/unicorn_mock.rb +11 -0
- data/spec/support/shared_spec.rb +29 -0
- data/tcell_agent.gemspec +14 -14
- metadata +46 -29
- data/Rakefile +0 -18
- data/lib/tcell_agent/authlogic.rb +0 -23
- data/lib/tcell_agent/config/unknown_options.rb +0 -119
- data/lib/tcell_agent/devise.rb +0 -33
- data/lib/tcell_agent/instrumentation/monkey_patches/file.rb +0 -25
- data/lib/tcell_agent/instrumentation/monkey_patches/io.rb +0 -123
- data/lib/tcell_agent/instrumentation/monkey_patches/kernel.rb +0 -159
- data/lib/tcell_agent/rails/start_agent_after_initializers.rb +0 -12
- data/lib/tcell_agent/rust/tcellagent-4.14.0.dll +0 -0
- data/spec/lib/tcell_agent/config/unknown_options_spec.rb +0 -195
|
@@ -9,53 +9,18 @@ require 'tcell_agent/utils/headers'
|
|
|
9
9
|
module TCellAgent
|
|
10
10
|
module Rust
|
|
11
11
|
class NativeAgent # rubocop:disable Metrics/ClassLength
|
|
12
|
-
def self.
|
|
13
|
-
|
|
14
|
-
event_sender = {
|
|
15
|
-
:uuid => config.uuid,
|
|
16
|
-
:hostname => config.host_identifier,
|
|
17
|
-
:agent_type => 'Ruby',
|
|
18
|
-
:agent_version => TCellAgent::VERSION,
|
|
19
|
-
:app_id => config.app_id,
|
|
20
|
-
:api_key => config.api_key,
|
|
21
|
-
:tcell_input_url => config.tcell_input_url,
|
|
22
|
-
:events => events
|
|
23
|
-
}
|
|
24
|
-
event_sender_pointer = FFI::MemoryPointer.from_string(
|
|
25
|
-
JSON.dump(event_sender)
|
|
26
|
-
)
|
|
27
|
-
|
|
28
|
-
buf = FFI::MemoryPointer.new(:uint8, 1024 * 8)
|
|
29
|
-
# config_pointer.size - 1: strips null terminator
|
|
30
|
-
result_size = TCellAgent::Rust::NativeLibrary.test_event_sender(
|
|
31
|
-
event_sender_pointer, event_sender_pointer.size - 1, buf, buf.size
|
|
32
|
-
)
|
|
33
|
-
|
|
34
|
-
response = NativeAgentResponse.new('test_event_sender', buf, result_size)
|
|
35
|
-
|
|
36
|
-
response.errors
|
|
37
|
-
end
|
|
12
|
+
def self.test_agent(config)
|
|
13
|
+
agent_config = TCellAgent::Rust::AgentConfig.new(config)
|
|
38
14
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
policies_info = {
|
|
42
|
-
:app_id => config.app_id,
|
|
43
|
-
:api_key => config.api_key,
|
|
44
|
-
:tcell_api_url => config.tcell_api_url
|
|
45
|
-
}
|
|
46
|
-
policies_info_pointer = FFI::MemoryPointer.from_string(
|
|
47
|
-
JSON.dump(policies_info)
|
|
15
|
+
config_pointer = FFI::MemoryPointer.from_string(
|
|
16
|
+
JSON.dump(agent_config)
|
|
48
17
|
)
|
|
49
18
|
|
|
50
19
|
buf = FFI::MemoryPointer.new(:uint8, 1024 * 8)
|
|
51
20
|
# config_pointer.size - 1: strips null terminator
|
|
52
|
-
|
|
53
|
-
|
|
21
|
+
TCellAgent::Rust::NativeLibrary.test_agent(
|
|
22
|
+
config_pointer, config_pointer.size - 1, buf, buf.size
|
|
54
23
|
)
|
|
55
|
-
|
|
56
|
-
response = NativeAgentResponse.new('test_event_sender', buf, result_size)
|
|
57
|
-
|
|
58
|
-
response.errors
|
|
59
24
|
end
|
|
60
25
|
|
|
61
26
|
def self.free_agent(agent_ptr)
|
|
@@ -88,6 +53,9 @@ module TCellAgent
|
|
|
88
53
|
return nil
|
|
89
54
|
end
|
|
90
55
|
|
|
56
|
+
return unless response['config'] && response['agent_enabled']
|
|
57
|
+
|
|
58
|
+
TCellAgent.configuration.populate_configuration(response['config'])
|
|
91
59
|
NativeAgent.new(response['agent_ptr'])
|
|
92
60
|
end
|
|
93
61
|
|
|
@@ -116,6 +84,7 @@ module TCellAgent
|
|
|
116
84
|
:headers => header_params,
|
|
117
85
|
:cookies => cookie_params,
|
|
118
86
|
:path_params => path_params,
|
|
87
|
+
:reverse_proxy_header_value => appsensor_meta.reverse_proxy_header_value,
|
|
119
88
|
:remote_address => appsensor_meta.remote_address,
|
|
120
89
|
:full_uri => appsensor_meta.location,
|
|
121
90
|
:session_id => appsensor_meta.session_id,
|
|
@@ -126,7 +95,6 @@ module TCellAgent
|
|
|
126
95
|
:content_type => appsensor_meta.content_type,
|
|
127
96
|
:request_body => appsensor_meta.raw_request_body
|
|
128
97
|
}
|
|
129
|
-
|
|
130
98
|
request_response_json[:sql_exceptions] = appsensor_meta.sql_exceptions if appsensor_meta.sql_exceptions
|
|
131
99
|
request_response_json[:database_result_sizes] = appsensor_meta.database_result_sizes if appsensor_meta.database_result_sizes
|
|
132
100
|
|
|
@@ -167,13 +135,15 @@ module TCellAgent
|
|
|
167
135
|
:method => appsensor_meta.method,
|
|
168
136
|
:path => appsensor_meta.path,
|
|
169
137
|
:remote_address => appsensor_meta.remote_address,
|
|
138
|
+
:reverse_proxy_header_value => appsensor_meta.reverse_proxy_header_value,
|
|
170
139
|
:request_bytes_length => appsensor_meta.request_content_bytes_len,
|
|
171
140
|
:query_params => query_params,
|
|
172
|
-
:post_params =>
|
|
141
|
+
:post_params => post_params,
|
|
173
142
|
:headers => header_params,
|
|
174
143
|
:cookies => cookie_params,
|
|
175
144
|
:content_type => appsensor_meta.content_type,
|
|
176
|
-
:full_uri => appsensor_meta.location
|
|
145
|
+
:full_uri => appsensor_meta.location,
|
|
146
|
+
:request_body => appsensor_meta.raw_request_body
|
|
177
147
|
}
|
|
178
148
|
|
|
179
149
|
patches_request_pointer = FFI::MemoryPointer.from_string(
|
|
@@ -196,6 +166,37 @@ module TCellAgent
|
|
|
196
166
|
response.response
|
|
197
167
|
end
|
|
198
168
|
|
|
169
|
+
def apply_suspicious_quick_check(appsensor_meta)
|
|
170
|
+
return {} unless appsensor_meta
|
|
171
|
+
|
|
172
|
+
sus_quick_check_request_json = {
|
|
173
|
+
:reverse_proxy_header_value => appsensor_meta.reverse_proxy_header_value,
|
|
174
|
+
:method => appsensor_meta.method,
|
|
175
|
+
:path => appsensor_meta.path,
|
|
176
|
+
:full_uri => appsensor_meta.location,
|
|
177
|
+
:request_bytes_length => appsensor_meta.request_content_bytes_len
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
if appsensor_meta.reverse_proxy_header_value.nil?
|
|
181
|
+
sus_quick_check_request_json.merge(
|
|
182
|
+
{
|
|
183
|
+
:client_ip_override => appsensor_meta.remote_address
|
|
184
|
+
}
|
|
185
|
+
)
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
sus_quick_check_request_ptr = FFI::MemoryPointer.from_string(
|
|
189
|
+
JSON.dump(sus_quick_check_request_json)
|
|
190
|
+
)
|
|
191
|
+
|
|
192
|
+
# sus_quick_check_request_ptr.size - 1: strips null terminator
|
|
193
|
+
TCellAgent::Rust::NativeLibrary.suspicious_quick_check_apply(
|
|
194
|
+
FFI::Pointer.new(@agent_ptr),
|
|
195
|
+
sus_quick_check_request_ptr,
|
|
196
|
+
sus_quick_check_request_ptr.size - 1
|
|
197
|
+
)
|
|
198
|
+
end
|
|
199
|
+
|
|
199
200
|
def apply_cmdi(command, tcell_context)
|
|
200
201
|
return unless TCellAgent::Utils::Strings.present?(command)
|
|
201
202
|
|
|
@@ -203,12 +204,14 @@ module TCellAgent
|
|
|
203
204
|
:command => command,
|
|
204
205
|
:method => tcell_context.request_method,
|
|
205
206
|
:path => tcell_context.path,
|
|
207
|
+
:reverse_proxy_header_value => tcell_context.reverse_proxy_header_value,
|
|
206
208
|
:remote_address => tcell_context.remote_address,
|
|
207
209
|
:route_id => tcell_context.route_id,
|
|
208
210
|
:session_id => tcell_context.session_id,
|
|
209
211
|
:user_id => tcell_context.user_id,
|
|
210
212
|
:full_uri => tcell_context.uri
|
|
211
213
|
}
|
|
214
|
+
|
|
212
215
|
command_pointer = FFI::MemoryPointer.from_string(
|
|
213
216
|
JSON.dump(command_info)
|
|
214
217
|
)
|
|
@@ -229,10 +232,11 @@ module TCellAgent
|
|
|
229
232
|
response.response
|
|
230
233
|
end
|
|
231
234
|
|
|
232
|
-
def get_headers(tcell_context)
|
|
235
|
+
def get_headers(content_type, tcell_context)
|
|
233
236
|
return unless tcell_context
|
|
234
237
|
|
|
235
238
|
headers_request = {
|
|
239
|
+
:content_type => content_type,
|
|
236
240
|
:method => tcell_context.request_method,
|
|
237
241
|
:path => tcell_context.path,
|
|
238
242
|
:route_id => tcell_context.route_id.to_s,
|
|
@@ -270,8 +274,9 @@ module TCellAgent
|
|
|
270
274
|
:status_code => status_code,
|
|
271
275
|
:method => tcell_context.request_method,
|
|
272
276
|
:path => tcell_context.path,
|
|
277
|
+
:reverse_proxy_header_value => tcell_context.reverse_proxy_header_value,
|
|
273
278
|
:remote_addr => tcell_context.remote_address,
|
|
274
|
-
:full_uri => tcell_context.
|
|
279
|
+
:full_uri => tcell_context.uri,
|
|
275
280
|
:route_id => tcell_context.route_id,
|
|
276
281
|
:session_id => tcell_context.session_id,
|
|
277
282
|
:user_id => tcell_context.user_id
|
|
@@ -335,11 +340,12 @@ module TCellAgent
|
|
|
335
340
|
:event_name => event_name,
|
|
336
341
|
:user_id => user_id,
|
|
337
342
|
:user_agent => tcell_context.user_agent,
|
|
343
|
+
:reverse_proxy_header_value => tcell_context.reverse_proxy_header_value,
|
|
338
344
|
:remote_address => tcell_context.remote_address,
|
|
339
345
|
:header_keys => header_keys,
|
|
340
|
-
:
|
|
346
|
+
:password => password,
|
|
341
347
|
:session_id => tcell_context.session_id,
|
|
342
|
-
:full_uri => tcell_context.
|
|
348
|
+
:full_uri => tcell_context.uri,
|
|
343
349
|
:referrer => tcell_context.referrer,
|
|
344
350
|
:user_valid => user_valid
|
|
345
351
|
}
|
|
@@ -377,11 +383,14 @@ module TCellAgent
|
|
|
377
383
|
if tcell_context
|
|
378
384
|
file_access_info = file_access_info.merge(
|
|
379
385
|
{
|
|
380
|
-
:full_uri => tcell_context.
|
|
386
|
+
:full_uri => tcell_context.uri,
|
|
387
|
+
:reverse_proxy_header_value => tcell_context.reverse_proxy_header_value,
|
|
381
388
|
:remote_address => tcell_context.remote_address,
|
|
382
389
|
:route_id => tcell_context.route_id,
|
|
383
390
|
:session_id => tcell_context.session_id,
|
|
384
|
-
:user_id => tcell_context.user_id
|
|
391
|
+
:user_id => tcell_context.user_id,
|
|
392
|
+
:method => tcell_context.request_method,
|
|
393
|
+
:request_path => tcell_context.path
|
|
385
394
|
}
|
|
386
395
|
)
|
|
387
396
|
end
|
|
@@ -453,6 +462,7 @@ module TCellAgent
|
|
|
453
462
|
:session_id => tcell_context && tcell_context.session_id,
|
|
454
463
|
:user_id => tcell_context && tcell_context.user_id,
|
|
455
464
|
:user_agent => tcell_context && tcell_context.user_agent,
|
|
465
|
+
:reverse_proxy_header_value => tcell_context.reverse_proxy_header_value,
|
|
456
466
|
:remote_address => tcell_context && tcell_context.remote_address
|
|
457
467
|
}
|
|
458
468
|
message_pointer = FFI::MemoryPointer.from_string(
|
|
@@ -504,7 +514,7 @@ module TCellAgent
|
|
|
504
514
|
end
|
|
505
515
|
end
|
|
506
516
|
|
|
507
|
-
#
|
|
517
|
+
# NOTE: for tests
|
|
508
518
|
def update_policies(policies)
|
|
509
519
|
return {} unless TCellAgent::Utils::Strings.present?(policies)
|
|
510
520
|
|
|
@@ -6,22 +6,20 @@ module TCellAgent
|
|
|
6
6
|
require 'ffi'
|
|
7
7
|
extend FFI::Library
|
|
8
8
|
|
|
9
|
-
VERSION = '4.14.0'.freeze
|
|
10
|
-
prefix = 'lib'
|
|
11
9
|
extension = '.so'
|
|
12
10
|
variant = ''
|
|
13
11
|
if /cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM
|
|
12
|
+
variant = '-x64'
|
|
14
13
|
extension = '.dll'
|
|
15
|
-
prefix = ''
|
|
16
14
|
elsif /darwin/ =~ RUBY_PLATFORM
|
|
17
15
|
extension = '.dylib'
|
|
18
16
|
elsif /musl/ =~ RUBY_PLATFORM
|
|
19
|
-
variant = 'alpine
|
|
17
|
+
variant = '-alpine'
|
|
20
18
|
end
|
|
21
19
|
|
|
22
20
|
begin
|
|
23
21
|
ffi_lib File.join(File.dirname(__FILE__),
|
|
24
|
-
"#{
|
|
22
|
+
"libtcellagent#{variant}#{extension}")
|
|
25
23
|
|
|
26
24
|
# All the rust library calls have the following response api:
|
|
27
25
|
#
|
|
@@ -36,6 +34,7 @@ module TCellAgent
|
|
|
36
34
|
attach_function :poll_new_policies, %i[pointer pointer size_t], :int
|
|
37
35
|
attach_function :appfirewall_apply, %i[pointer pointer size_t pointer size_t], :int
|
|
38
36
|
attach_function :patches_apply, %i[pointer pointer size_t pointer size_t], :int
|
|
37
|
+
attach_function :suspicious_quick_check_apply, %i[pointer pointer size_t], :int
|
|
39
38
|
attach_function :cmdi_apply, %i[pointer pointer size_t pointer size_t], :int
|
|
40
39
|
attach_function :get_headers, %i[pointer pointer size_t pointer size_t], :int
|
|
41
40
|
attach_function :get_js_agent_script_tag, %i[pointer pointer size_t pointer size_t], :int
|
|
@@ -48,16 +47,15 @@ module TCellAgent
|
|
|
48
47
|
attach_function :log_message, %i[pointer pointer size_t pointer size_t], :int
|
|
49
48
|
|
|
50
49
|
attach_function :update_policies, %i[pointer pointer size_t pointer size_t], :int
|
|
51
|
-
attach_function :
|
|
52
|
-
attach_function :test_policies, %i[pointer size_t pointer size_t], :int
|
|
50
|
+
attach_function :test_agent, %i[pointer size_t pointer size_t], :int
|
|
53
51
|
|
|
54
52
|
def self.common_lib_available?
|
|
55
53
|
true
|
|
56
54
|
end
|
|
57
|
-
rescue LoadError =>
|
|
55
|
+
rescue LoadError => e
|
|
58
56
|
logger = TCellAgent::ModuleLogger.new(TCellAgent::RubyLogger.new, name)
|
|
59
|
-
logger.error("Failed loading agent library. #{
|
|
60
|
-
logger.exception(
|
|
57
|
+
logger.error("Failed loading agent library. #{e.message}")
|
|
58
|
+
logger.exception(e)
|
|
61
59
|
|
|
62
60
|
def self.common_lib_available? # rubocop:disable Lint/DuplicateMethods
|
|
63
61
|
false
|
|
@@ -7,59 +7,6 @@ require 'etc'
|
|
|
7
7
|
|
|
8
8
|
module TCellAgent
|
|
9
9
|
module SensorEvents
|
|
10
|
-
class ServerAgentDetailsSensorEvent < TCellSensorEvent
|
|
11
|
-
include TCellAgent::ModuleLoggerAccess
|
|
12
|
-
|
|
13
|
-
def initialize
|
|
14
|
-
super('server_agent_details')
|
|
15
|
-
@flush = true
|
|
16
|
-
@ensure = true
|
|
17
|
-
|
|
18
|
-
self['user'] = 'unknown'
|
|
19
|
-
self['group'] = 'unknown'
|
|
20
|
-
|
|
21
|
-
begin
|
|
22
|
-
login = Etc.getlogin
|
|
23
|
-
if login
|
|
24
|
-
self['user'] = login
|
|
25
|
-
begin
|
|
26
|
-
info = Etc.getpwnam(login)
|
|
27
|
-
self['group'] = info.gid.to_s
|
|
28
|
-
rescue StandardError => te
|
|
29
|
-
module_logger.debug("Could not get group id: #{te.message}")
|
|
30
|
-
module_logger.exception(te)
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
rescue StandardError => to
|
|
34
|
-
module_logger.debug("Could not get user & group: #{to.message}")
|
|
35
|
-
module_logger.exception(te)
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
module_logger.debug("User #{self['user']}")
|
|
39
|
-
module_logger.debug("Group #{self['group']}")
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
class ServerAgentDetailsLanguageEvent < TCellSensorEvent
|
|
44
|
-
def initialize(language, language_version)
|
|
45
|
-
super('server_agent_details')
|
|
46
|
-
@flush = true
|
|
47
|
-
@ensure = true
|
|
48
|
-
self['language'] = language
|
|
49
|
-
self['language_version'] = language_version
|
|
50
|
-
end
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
class ServerAgentAppFrameworkEvent < TCellSensorEvent
|
|
54
|
-
def initialize(framework_name, framework_version)
|
|
55
|
-
super('server_agent_details')
|
|
56
|
-
@flush = true
|
|
57
|
-
@ensure = true
|
|
58
|
-
self['app_framework'] = framework_name
|
|
59
|
-
self['app_framework_version'] = framework_version
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
|
|
63
10
|
class ServerAgentPackagesSensorEvent < TCellSensorEvent
|
|
64
11
|
include TCellAgent::ModuleLoggerAccess
|
|
65
12
|
|
|
@@ -75,59 +22,15 @@ module TCellAgent
|
|
|
75
22
|
packages.push(package)
|
|
76
23
|
module_logger.debug("Adding packages #{x.name}")
|
|
77
24
|
end
|
|
78
|
-
rescue StandardError =>
|
|
79
|
-
module_logger.error("Exception adding package: #{
|
|
80
|
-
module_logger.exception(
|
|
25
|
+
rescue StandardError => e
|
|
26
|
+
module_logger.error("Exception adding package: #{e.message}")
|
|
27
|
+
module_logger.exception(e)
|
|
81
28
|
end
|
|
82
29
|
end
|
|
83
30
|
self['packages'] = packages
|
|
84
31
|
end
|
|
85
32
|
end
|
|
86
33
|
|
|
87
|
-
class AppFramework < TCellSensorEvent
|
|
88
|
-
def initialize(name, version)
|
|
89
|
-
super('appserver_framework')
|
|
90
|
-
@flush = false
|
|
91
|
-
@ensure = true
|
|
92
|
-
self['n'] = name
|
|
93
|
-
self['v'] = version
|
|
94
|
-
end
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
class AppAuthFramework < TCellSensorEvent
|
|
98
|
-
def initialize(name, version)
|
|
99
|
-
super('appserver_auth_framework')
|
|
100
|
-
@flush = false
|
|
101
|
-
@ensure = true
|
|
102
|
-
self['n'] = name
|
|
103
|
-
self['v'] = version
|
|
104
|
-
end
|
|
105
|
-
end
|
|
106
|
-
|
|
107
|
-
class AppFrameworkSetting < TCellSensorEvent
|
|
108
|
-
def initialize(framework_name, setting, value)
|
|
109
|
-
super('appserver_framework_setting')
|
|
110
|
-
@flush = false
|
|
111
|
-
@ensure = true
|
|
112
|
-
self['framework'] = framework_name
|
|
113
|
-
self['s'] = setting
|
|
114
|
-
self['v'] = value
|
|
115
|
-
end
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
class AppCookie < TCellSensorEvent
|
|
119
|
-
def initialize(name, value, secure, http_only, session)
|
|
120
|
-
super('appserver_framework_setting')
|
|
121
|
-
@flush = false
|
|
122
|
-
@ensure = true
|
|
123
|
-
self['n'] = name
|
|
124
|
-
self['v'] = value
|
|
125
|
-
self['http_only'] = http_only
|
|
126
|
-
self['secure'] = secure
|
|
127
|
-
self['session'] = session
|
|
128
|
-
end
|
|
129
|
-
end
|
|
130
|
-
|
|
131
34
|
class AppRoutesSensorEvent < TCellSensorEvent
|
|
132
35
|
def initialize(uri, method, route_id, params = nil, destination = nil)
|
|
133
36
|
super('appserver_routes')
|
|
@@ -1,38 +1,55 @@
|
|
|
1
1
|
if defined?(Puma.cli_config)
|
|
2
2
|
if Puma.cli_config.options[:preload_app]
|
|
3
|
-
if Puma.cli_config.options[:workers] == 0
|
|
3
|
+
if Puma.cli_config.options[:workers] == 0
|
|
4
4
|
# Puma is running in single mode, so run both the initial instrumentation and
|
|
5
5
|
# start the agent
|
|
6
6
|
Puma::Runner.class_eval do
|
|
7
|
-
alias_method :
|
|
7
|
+
alias_method :tcell_original_start_server, :start_server
|
|
8
8
|
def start_server
|
|
9
|
-
TCellAgent.thread_agent.start('Puma
|
|
9
|
+
TCellAgent.thread_agent.start('Puma')
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
tcell_original_start_server
|
|
12
12
|
end
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
else
|
|
16
16
|
Puma::Server.class_eval do
|
|
17
|
-
alias_method :
|
|
18
|
-
def run(background = true)
|
|
19
|
-
TCellAgent.thread_agent.start('Puma Cluster Mode (Worker)')
|
|
17
|
+
alias_method :tcell_original_run, :run
|
|
20
18
|
|
|
21
|
-
|
|
19
|
+
if defined?(Gem::Version) &&
|
|
20
|
+
defined?(Puma::Const::PUMA_VERSION) &&
|
|
21
|
+
(Gem::Version.new(Puma::Const::PUMA_VERSION) < Gem::Version.new('5.1.0'))
|
|
22
|
+
def run(background = true)
|
|
23
|
+
TCellAgent.thread_agent.start('Puma')
|
|
24
|
+
original_run(background, options)
|
|
25
|
+
end
|
|
26
|
+
else
|
|
27
|
+
def run(background = true, thread_name: 'server')
|
|
28
|
+
TCellAgent.thread_agent.start('Puma')
|
|
29
|
+
original_run(background, :thread_name => thread_name)
|
|
30
|
+
end
|
|
22
31
|
end
|
|
23
32
|
end
|
|
24
33
|
end
|
|
25
|
-
|
|
26
34
|
else
|
|
27
35
|
# this ensures instrumentation runs for preload_app = false.
|
|
28
36
|
# Instrumentation will run for each worker but there's
|
|
29
37
|
# nothing we can do about that (Unicorn's preload_app behaves the same way)
|
|
30
38
|
Puma::Server.class_eval do
|
|
31
|
-
alias_method :
|
|
32
|
-
def run(background = true)
|
|
33
|
-
TCellAgent.thread_agent.start('Puma Cluster Mode (Worker)')
|
|
39
|
+
alias_method :tcell_original_run, :run
|
|
34
40
|
|
|
35
|
-
|
|
41
|
+
if defined?(Gem::Version) &&
|
|
42
|
+
defined?(Puma::Const::PUMA_VERSION) &&
|
|
43
|
+
(Gem::Version.new(Puma::Const::PUMA_VERSION) < Gem::Version.new('5.1.0'))
|
|
44
|
+
def run(background = true)
|
|
45
|
+
TCellAgent.thread_agent.start('Puma')
|
|
46
|
+
tcell_original_run(background)
|
|
47
|
+
end
|
|
48
|
+
else
|
|
49
|
+
def run(background = true, thread_name: 'server')
|
|
50
|
+
TCellAgent.thread_agent.start('Puma')
|
|
51
|
+
original_run(background, :thread_name => thread_name)
|
|
52
|
+
end
|
|
36
53
|
end
|
|
37
54
|
end
|
|
38
55
|
end
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
Rack::Handler::Puma.class_eval do
|
|
4
|
+
class << self
|
|
5
|
+
alias_method :tcell_original_config, :config
|
|
6
|
+
def config(app, options = {})
|
|
7
|
+
conf = tcell_original_config(app, options)
|
|
8
|
+
|
|
9
|
+
if defined?(Puma::Server) && !Puma::Server.instance_methods.include?(:tcell_original_run)
|
|
10
|
+
Puma::Server.class_eval do
|
|
11
|
+
alias_method :tcell_original_run, :run
|
|
12
|
+
|
|
13
|
+
if defined?(Gem::Version) &&
|
|
14
|
+
defined?(Puma::Const::PUMA_VERSION) &&
|
|
15
|
+
(Gem::Version.new(Puma::Const::PUMA_VERSION) >= Gem::Version.new('5.1.0'))
|
|
16
|
+
def run(background = true, thread_name: 'server')
|
|
17
|
+
TCellAgent.thread_agent.start('Puma')
|
|
18
|
+
original_run(background, :thread_name => thread_name)
|
|
19
|
+
end
|
|
20
|
+
else
|
|
21
|
+
def run(background = true)
|
|
22
|
+
TCellAgent.thread_agent.start('Puma')
|
|
23
|
+
|
|
24
|
+
tcell_original_run(background)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
conf
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
@@ -5,17 +5,17 @@
|
|
|
5
5
|
Rails::Server.class_eval do
|
|
6
6
|
alias_method :tcell_build_app, :build_app
|
|
7
7
|
def build_app(app)
|
|
8
|
+
require('tcell_agent/servers/rack_puma_handler') if defined?(Rack::Handler::Puma)
|
|
8
9
|
require('tcell_agent/servers/unicorn') if defined?(Unicorn::HttpServer)
|
|
9
10
|
require('tcell_agent/servers/webrick') if defined?(Rack::Handler::WEBrick)
|
|
10
11
|
require('tcell_agent/servers/thin') if defined?(Thin::Server)
|
|
11
12
|
|
|
12
13
|
if defined?(Puma::Server)
|
|
13
14
|
Puma::Server.class_eval do
|
|
14
|
-
alias_method :
|
|
15
|
+
alias_method :tcell_original_run, :run
|
|
15
16
|
def run(background = true)
|
|
16
|
-
TCellAgent.thread_agent.start('Puma
|
|
17
|
-
|
|
18
|
-
original_run(background)
|
|
17
|
+
TCellAgent.thread_agent.start('Puma')
|
|
18
|
+
tcell_original_run(background)
|
|
19
19
|
end
|
|
20
20
|
end
|
|
21
21
|
end
|
|
@@ -3,7 +3,7 @@ Unicorn::HttpServer.class_eval do
|
|
|
3
3
|
# - This check also ensures that a server is running as opposed to a different command such
|
|
4
4
|
# as `bundle exec rails runner User.count`.
|
|
5
5
|
unless Unicorn::HttpServer::START_CTX && Unicorn::HttpServer::START_CTX[0]
|
|
6
|
-
require 'tcell_agent/rails/
|
|
6
|
+
require 'tcell_agent/rails/railties/tcell_agent_unicorn_railties'
|
|
7
7
|
end
|
|
8
8
|
|
|
9
9
|
# This only gets instrumented when preload_app is true
|
|
@@ -1,10 +1,19 @@
|
|
|
1
1
|
Rack::Handler::WEBrick.class_eval do
|
|
2
2
|
class << self
|
|
3
3
|
alias_method :original_run, :run
|
|
4
|
-
def run(app, options = {})
|
|
5
|
-
TCellAgent.thread_agent.start('WEBrick')
|
|
6
4
|
|
|
7
|
-
|
|
5
|
+
if defined?(Gem::Version) &&
|
|
6
|
+
defined?(Rack.release) &&
|
|
7
|
+
Gem::Version.new(Rack.release) < Gem::Version.new('2.2.0')
|
|
8
|
+
def run(app, options = {})
|
|
9
|
+
TCellAgent.thread_agent.start('WEBrick')
|
|
10
|
+
original_run(app, options)
|
|
11
|
+
end
|
|
12
|
+
else
|
|
13
|
+
def run(app, **options)
|
|
14
|
+
TCellAgent.thread_agent.start('WEBrick')
|
|
15
|
+
original_run(app, **options)
|
|
16
|
+
end
|
|
8
17
|
end
|
|
9
18
|
end
|
|
10
19
|
end
|
|
@@ -7,25 +7,11 @@ require 'thread'
|
|
|
7
7
|
module TCellAgent
|
|
8
8
|
def self.report_settings
|
|
9
9
|
Thread.new do
|
|
10
|
-
TCellAgent::Instrumentation.safe_block('Instrumenting Agent Details') do
|
|
11
|
-
event = TCellAgent::SensorEvents::ServerAgentDetailsSensorEvent.new
|
|
12
|
-
TCellAgent.send_event(event)
|
|
13
|
-
end
|
|
14
|
-
|
|
15
10
|
TCellAgent::Instrumentation.safe_block('Instrumenting Server Packages') do
|
|
16
11
|
event = TCellAgent::SensorEvents::ServerAgentPackagesSensorEvent.new
|
|
17
12
|
TCellAgent.send_event(event)
|
|
18
13
|
end
|
|
19
14
|
|
|
20
|
-
TCellAgent::Instrumentation.safe_block('Instrumenting Language Info') do
|
|
21
|
-
TCellAgent.send_event(
|
|
22
|
-
TCellAgent::SensorEvents::ServerAgentDetailsLanguageEvent.new(
|
|
23
|
-
'Ruby',
|
|
24
|
-
RUBY_VERSION
|
|
25
|
-
)
|
|
26
|
-
)
|
|
27
|
-
end
|
|
28
|
-
|
|
29
15
|
TCellAgent::Instrumentation.safe_block('Instrumenting Native Lib Status') do
|
|
30
16
|
require 'tcell_agent/rust/native_agent'
|
|
31
17
|
|
|
@@ -37,85 +23,6 @@ module TCellAgent
|
|
|
37
23
|
)
|
|
38
24
|
end
|
|
39
25
|
|
|
40
|
-
TCellAgent::Instrumentation.safe_block('Instrumenting Initial Config') do
|
|
41
|
-
TCellAgent.send_event(
|
|
42
|
-
TCellAgent::SensorEvents::AgentSettingEvent.new(
|
|
43
|
-
'allow_payloads',
|
|
44
|
-
(!!TCellAgent.configuration.allow_payloads).to_s # rubocop:disable Style/DoubleNegation
|
|
45
|
-
)
|
|
46
|
-
)
|
|
47
|
-
|
|
48
|
-
TCellAgent.send_event(
|
|
49
|
-
TCellAgent::SensorEvents::AgentSettingEvent.new(
|
|
50
|
-
'reverse_proxy',
|
|
51
|
-
(!!TCellAgent.configuration.reverse_proxy).to_s # rubocop:disable Style/DoubleNegation
|
|
52
|
-
)
|
|
53
|
-
)
|
|
54
|
-
|
|
55
|
-
# Because of all the diff ways to initialize the agent
|
|
56
|
-
# some some of the following vars might not be set until
|
|
57
|
-
# we call this method, so call this method to set all
|
|
58
|
-
# the variables
|
|
59
|
-
TCellAgent.configuration.log_filename
|
|
60
|
-
|
|
61
|
-
TCellAgent.send_event(
|
|
62
|
-
TCellAgent::SensorEvents::AgentSettingEvent.new(
|
|
63
|
-
'config_filename',
|
|
64
|
-
TCellAgent.configuration.config_filename
|
|
65
|
-
)
|
|
66
|
-
)
|
|
67
|
-
TCellAgent.send_event(
|
|
68
|
-
TCellAgent::SensorEvents::AgentSettingEvent.new(
|
|
69
|
-
'logging_directory',
|
|
70
|
-
TCellAgent.configuration.agent_log_dir
|
|
71
|
-
)
|
|
72
|
-
)
|
|
73
|
-
|
|
74
|
-
TCellAgent.send_event(
|
|
75
|
-
TCellAgent::SensorEvents::AgentSettingEvent.new(
|
|
76
|
-
'agent_home_directory',
|
|
77
|
-
TCellAgent.configuration.agent_home_dir
|
|
78
|
-
)
|
|
79
|
-
)
|
|
80
|
-
|
|
81
|
-
logging_options = TCellAgent.configuration.logging_options || {}
|
|
82
|
-
use_default_setting = !logging_options.key?(:enabled) && !logging_options.key?('enabled')
|
|
83
|
-
if use_default_setting || logging_options[:enabled] || logging_options['enabled']
|
|
84
|
-
TCellAgent.send_event(
|
|
85
|
-
TCellAgent::SensorEvents::AgentSettingEvent.new('logging_enabled', 'true')
|
|
86
|
-
)
|
|
87
|
-
|
|
88
|
-
TCellAgent.send_event(
|
|
89
|
-
TCellAgent::SensorEvents::AgentSettingEvent.new(
|
|
90
|
-
'logging_level',
|
|
91
|
-
logging_options[:level] || logging_options['level'] || 'INFO'
|
|
92
|
-
)
|
|
93
|
-
)
|
|
94
|
-
else
|
|
95
|
-
TCellAgent.send_event(
|
|
96
|
-
TCellAgent::SensorEvents::AgentSettingEvent.new('logging_enabled', 'false')
|
|
97
|
-
)
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
if TCellAgent.configuration.hmac_key
|
|
101
|
-
TCellAgent.send_event(
|
|
102
|
-
TCellAgent::SensorEvents::AgentSettingEvent.new(
|
|
103
|
-
'hmac_key_present',
|
|
104
|
-
(!!TCellAgent.configuration.hmac_key).to_s # rubocop:disable Style/DoubleNegation
|
|
105
|
-
)
|
|
106
|
-
)
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
if TCellAgent.configuration.reverse_proxy
|
|
110
|
-
TCellAgent.send_event(
|
|
111
|
-
TCellAgent::SensorEvents::AgentSettingEvent.new(
|
|
112
|
-
'reverse_proxy_ip_address_header',
|
|
113
|
-
TCellAgent.configuration.reverse_proxy_ip_address_header
|
|
114
|
-
)
|
|
115
|
-
)
|
|
116
|
-
end
|
|
117
|
-
end
|
|
118
|
-
|
|
119
26
|
if defined?(::Rails)
|
|
120
27
|
TCellAgent::Instrumentation.safe_block('Instrumenting routes') do
|
|
121
28
|
TCellAgent::Instrumentation::Rails.instrument_routes
|