Provide a Ruby Wrapper for Trend Micro's DeepSecurity SOAP API. Also includes a command line binary dsc which exposes
some of the functionality to shell scripts.
The library wraps the Deep Security Manager SOAP web service (https://<manager>:4119/webservice/Manager?WSDL) with
Savon and maps the WSDL transport types onto plain Ruby objects. dsc uses that wrapper to dump computer inventory and
Anti-Malware events as CSV.
Unmaintained. The last release is 0.0.25 (October 2013) and it targets the Deep Security Manager SOAP API as it existed
then, on the Ruby 1.9.x / savon 2.x stack of that time. It has not been tested against later Deep Security versions.
Coverage is partial even for its own era: hosts, host groups, host details and Anti-Malware events work end to end.
The Manager methods for security profiles, DPI rules, application types, system events and the HTML screen-scraping
helpers (vulnerabilities, *_dpi_rule_identifiers) are leftovers from an earlier refactoring and call methods that
no longer exist on Manager; they raise NoMethodError. Their transport object classes are still defined and are used
for type mapping.
Add this line to your application's Gemfile:
gem 'deepsecurity'
And then execute:
$ bundle
Or install it yourself as:
$ gem install deepsecurity
Runtime dependencies, from the gemspec: savon, ruby-cache, gli, progressbar, json.
If you are using Windows and do feel familiar with the command line you may also download a bundled installer under http://deepsecurity-gem.s3.amazonaws.com/index.html
The bundled installer allows you to install a current Ruby version and the deepsecurity gem using a simple graphical installer.
The installer is built by rake windows_installer from windows-installer/dsc.iss (Inno Setup) and bundles Ruby
1.9.3-p448. The S3 index it is published to is generated by rake s3_index. Both date from 2013 and the download link
may no longer be live.
DeepSecurity::Manager.server builds the SOAP client; Manager#connect authenticates and stores the session ID that
is then passed implicitly to every subsequent call.
require 'deepsecurity'
# hostname, port (default 4119), log level (nil, :debug, :info, :warn, :error, :fatal), logger
manager = DeepSecurity::Manager.server('dsm.example.com', 4119)
manager.connect('', 'MasterAdmin', ENV['DSM_PASSWORD'])
begin
# ... calls ...
ensure
manager.disconnect
endDetails:
- The endpoint is hardcoded as
https://<hostname>:<port>/webservice/Manager?WSDL. Only host and port are configurable; the scheme and path are not. - TLS certificates are not verified.
:ssl_verify_mode => :noneis passed to both Savon and HTTPI and cannot be overridden through the public API. connect(tenant, username, password)calls the SOAPauthenticateoperation whentenantis empty andauthenticateTenantotherwise. Failure raisesDeepSecurity::AuthenticationFailedException.- Calling an authenticated operation before
connectraisesDeepSecurity::AuthenticationRequiredException. disconnectcallsendSession; it is a no-op when not authenticated.- Retrieved objects are memoised in a process-wide cache (10000 entries, 5 minute TTL), so repeated
hosts,host(id),host_group(id)andhost_detailscalls within that window do not hit the manager again. - Logging goes to STDERR. Passing a log level also enables Savon/HTTPI request logging, which includes the SOAP request bodies.
Unauthenticated calls:
manager.api_version # => Integer, the web service API version
manager.manager_time # => TimeHosts and host groups:
manager.hosts # => Array<DeepSecurity::Host>
manager.host(42) # => DeepSecurity::Host
manager.host_by_name('web01.example.com') # => DeepSecurity::Host
manager.host_groups # => Array<DeepSecurity::HostGroup>
manager.host_group(3) # => DeepSecurity::HostGroup
manager.host_group_by_name('Production') # => DeepSecurity::HostGroup
host = manager.host_by_name('web01.example.com')
host.id
host.name
host.display_name
host.platform
host.host_type # => :standard, :esx, :appliance or :vm
host.host_group # resolves host_group_id through the managerHost details, the richer per-computer record (DeepSecurity::HostDetail < Host):
filter = DeepSecurity::HostFilter.all_hosts
details = manager.host_details(filter, :low) # detail level: :low, :medium or :high
details.each do |d|
puts [d.name,
d.platform,
d.overall_status,
d.anti_malware_engine_version,
d.overall_last_successful_communication].join("\t")
endAnti-Malware events:
events = manager.anti_malware_events_by_time_host_event(
DeepSecurity::TimeFilter.last_24_hours,
DeepSecurity::HostFilter.all_hosts,
DeepSecurity::IDFilter.greater_than(0))
events.each do |e|
puts [e.log_date, e.host.name, e.malware_name, e.malware_type, e.infected_file_path].join("\t")
endDeepSecurity::HostFilter:
all_hostsmy_hostsspecific_host(host_id)hosts_in_group(host_group_id)hosts_in_group_and_all_subgroups(host_group_id)hosts_using_security_profile(security_profile_id)
DeepSecurity::TimeFilter:
last_hourlast_24_hourslast_7_dayslast_day— yesterday 00:00:00 to 23:59:59, expressed as a custom rangecustom_range(datetime_range)specific_time(datetime)
DeepSecurity::IDFilter:
equals(id)less_than(id)greater_than(id)
All API types derive from DeepSecurity::TransportObject and declare their attributes through a small DSL
(attr_string_accessor, attr_integer_accessor, attr_datetime_accessor, attr_enum_accessor,
array_object_accessor, ...) that carries the Savon type conversion and a description string. The schema of any class
is available programmatically:
DeepSecurity::HostDetail.all_type_mappings.each do |name, mapping|
puts "#{name} (#{mapping.type_string}): #{mapping.description}"
endClasses defined: Host, HostDetail, HostInterface, HostGroup, SecurityProfile, DPIRule, ApplicationType,
ProtocolIcmp, ProtocolPortBased, SystemEvent, AntiMalwareEvent, AntiMalwareSpywareItem, plus the three filter
types.
Reachable through Manager, and one level down through DeepSecurity::SOAPInterface:
| SOAP operation | Manager method |
|---|---|
getApiVersion |
api_version |
getManagerTime |
manager_time |
authenticate / authenticateTenant |
connect(tenant, username, password) |
endSession |
disconnect |
hostRetrieveAll |
hosts |
hostRetrieve |
host(id) |
hostRetrieveByName |
host_by_name(name) |
hostGroupRetrieveAll |
host_groups |
hostGroupRetrieve |
host_group(id) |
hostGroupRetrieveByName |
host_group_by_name(name) |
hostDetailRetrieve |
host_details(host_filter, detail_level) |
antiMalwareEventRetrieve |
anti_malware_events_by_time_host_event(time_filter, host_filter, id_filter) |
dsc [global options] command [command options] [arguments...]
-m, --manager=hostname Deep Security Manager host
--port=port Web service port (default: 4119)
-t, --tenant=tenant Tenant name (default: empty, i.e. non-tenant authentication)
-u, --username=username Username (default: MasterAdmin)
-p, --password=password Password
-d, --debug=level Client debug output: debug, info, warn, error or fatal (default: off)
-o, --outfile=file Output filename (default: --, i.e. stdout)
-P, --progress_bar Show a progress bar
--help
--version
-o/--outfile is broken: any value other than the default -- raises a NameError. Redirect stdout instead.
dsc api_version Display the web service API version (no authentication needed)
dsc manager_time Display the manager's local time (no authentication needed)
dsc host_detail schema List available host_detail fields with types and descriptions
dsc host_detail list List host details as CSV
dsc anti_malware_event schema List available anti_malware_event fields
dsc anti_malware_event list List Anti-Malware events as CSV
list writes CSV with a header row of the selected field names. A field that raises during evaluation is emitted as
ERROR (message) rather than aborting the run.
--fields=list Comma separated field list, or a filename to read fields from
--detail_level=level low, medium or high (default: low)
--time_format=format strftime() format for date/time output
--fields=list Comma separated field list, or a filename to read fields from
--time_filter=filter last_hour, last_24_hours, last_7_days or last_day (default: last_day)
--time_format=format strftime() format for date/time output
dsc -m dsm.example.com api_version
dsc -m dsm.example.com -u MasterAdmin -p secret host_detail list > hosts.csv
dsc -m dsm.example.com -u MasterAdmin -p secret \
host_detail list --detail_level=high \
--fields=name,platform,overall_status,anti_malware_engine_version
dsc -m dsm.example.com -t TenantA -u admin -p secret \
anti_malware_event list --time_filter=last_7_days \
--time_format='%Y-%m-%d %H:%M:%S'
dsc -m dsm.example.com host_detail schema--fields takes a comma or whitespace separated list of accessor names. If the value names an existing file, the field
list is read from that file instead, with # starting a comment. Fields may be chains of calls separated by dots, so
host.name follows the host association of an event and name.size calls String#size on the result. Unknown
fields abort the command and print the list of valid ones.
Default host_detail list fields: name, display_name, anti_malware_classic_pattern_version,
anti_malware_engine_version, anti_malware_intelli_trap_exception_version, anti_malware_intelli_trap_version,
anti_malware_smart_scan_pattern_version, anti_malware_spyware_pattern_version,
overall_last_successful_communication, platform, host_type, host_group_name.
Default anti_malware_event list fields: host.name, host.display_name, log_date, start_time, end_time,
scan_action1, scan_action2, summary_scan_result, scan_result_action1, scan_result_action2, malware_name,
malware_type, infected_file_path, infection_source.
dsc.md holds additional notes on the command line client.
rake test # Test::Unit tests in test/
rake # same, the default task
rake windows_installer # build the Inno Setup installer (requires the Windows toolchain)
Test coverage is minimal: two files covering dsc time filter / time format parsing and a few savon_helper string
helpers.
MIT, see the LICENSE file (Copyright (c) 2012 Udo Schneider). The gemspec declares no license field, so the
packaged gem carries no license metadata.