Skip to content

Commit

Permalink
add support for CWS on Windows (#907)
Browse files Browse the repository at this point in the history
* run security agent specs on windows

* add security agent test

* add support for security agent service on windows

* small code cleanup

* add rspec test for windows on CWS
  • Loading branch information
paulcacheux authored Feb 12, 2024
1 parent 0461c8c commit 9c2c583
Show file tree
Hide file tree
Showing 6 changed files with 208 additions and 19 deletions.
13 changes: 13 additions & 0 deletions kitchen.yml
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,19 @@ suites:
bpf_debug: true
enable_conntrack: true

- name: security-agent
run_list:
- recipe[datadog::dd-agent]
attributes:
datadog: &DATADOG
aptrepo: 'http://apt.datad0g.com'
aptrepo_dist: 'beta'
api_key: somenonnullapikeythats32charlong
application_key: alsonotnil
security_agent:
cws:
enabled: true

- name: dd-handler
run_list:
- recipe[datadog::dd-handler]
Expand Down
2 changes: 1 addition & 1 deletion recipes/dd-agent.rb
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ def template_vars
include_recipe '::system-probe' if system_probe_managed && system_probe_supported

# security-agent is a dependency of the agent on Linux or Windows
include_recipe '::security-agent' unless is_windows
include_recipe '::security-agent'

# Installation metadata to let know the agent about installation method and its version
include_recipe '::install_info'
Expand Down
36 changes: 24 additions & 12 deletions recipes/security-agent.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,17 @@
is_windows = platform_family?('windows')

# Set the correct agent startup action
security_agent_enabled = !is_windows && node['datadog']['security_agent']['cws']['enabled'] || node['datadog']['security_agent']['cspm']['enabled']
security_agent_enabled = node['datadog']['security_agent']['cws']['enabled'] || (!is_windows && node['datadog']['security_agent']['cspm']['enabled'])
security_agent_start = security_agent_enabled && node['datadog']['agent_start'] && node['datadog']['agent_enable'] ? :start : :stop

#
# Configures security-agent agent
security_agent_config_file = '/etc/datadog-agent/security-agent.yaml'
security_agent_config_file =
if is_windows
'C:/ProgramData/Datadog/security-agent.yaml'
else
'/etc/datadog-agent/security-agent.yaml'
end
security_agent_config_file_exists = ::File.exist?(security_agent_config_file)

template security_agent_config_file do
Expand Down Expand Up @@ -52,9 +58,11 @@
compliance_extra_config: compliance_extra_config
)

owner 'root'
group 'dd-agent'
mode '640'
unless is_windows
owner 'root'
group 'dd-agent'
mode '640'
end

notifies :restart, 'service[datadog-agent-security]', :delayed if security_agent_enabled

Expand All @@ -65,14 +73,18 @@
# Common configuration
service_provider = Chef::Datadog.service_provider(node)

service_name = 'datadog-agent-security'
service_name = is_windows ? 'datadog-security-agent' : 'datadog-agent-security'

if security_agent_enabled
service 'datadog-agent-security' do
service_name service_name
action :start
provider service_provider unless service_provider.nil?
service 'datadog-agent-security' do
service_name service_name
action [security_agent_start]
provider service_provider unless service_provider.nil?
if is_windows
supports :restart => true, :start => true, :stop => true
restart_command "powershell restart-service #{service_name} -Force"
stop_command "powershell stop-service #{service_name} -Force"
else
supports :restart => true, :status => true, :start => true, :stop => true
subscribes :restart, "template[#{security_agent_config_file}]", :delayed
end
subscribes :restart, "template[#{security_agent_config_file}]", :delayed if security_agent_enabled
end
10 changes: 4 additions & 6 deletions recipes/system-probe.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,11 @@
is_windows = platform_family?('windows')

# Set the correct agent startup action
npm_enabled = node['datadog']['system_probe']['network_enabled']
usm_enabled = node['datadog']['system_probe']['service_monitoring_enabled']
cws_enabled = node['datadog']['security_agent']['cws']['enabled']
sysprobe_enabled = if is_windows
node['datadog']['system_probe']['network_enabled']
else
node['datadog']['system_probe']['enabled'] || node['datadog']['system_probe']['network_enabled'] || node['datadog']['system_probe']['service_monitoring_enabled'] || cws_enabled
end
sysprobe_enabled = node['datadog']['system_probe']['enabled'] || npm_enabled || usm_enabled || cws_enabled

sysprobe_agent_start = sysprobe_enabled && node['datadog']['agent_start'] && node['datadog']['agent_enable'] ? :start : :stop

#
Expand Down Expand Up @@ -99,6 +98,5 @@
else
supports :restart => true, :status => true, :start => true, :stop => true
end
supports :restart => true, :status => true, :start => true, :stop => true
subscribes :restart, "template[#{system_probe_config_file}]", :delayed if sysprobe_enabled
end
55 changes: 55 additions & 0 deletions spec/security-agent_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,59 @@
})
end
end

context 'with CWS enabled on Windows' do
cached(:solo) do
ChefSpec::SoloRunner.new(
platform: 'windows',
version: '2012R2'
) do |node|
node.name 'chef-nodename' # expected to be used as the hostname in `datadog.yaml`
node.normal['datadog'] = {
'api_key' => 'somethingnotnil',
'agent_major_version' => 6,
'security_agent' => {
'cws' => {
'enabled' => true,
}
},
'extra_config' => {
'security_agent' => {
'runtime_security_config' => {
'activity_dump' => {
'enabled' => true,
}
}
}
}
}
end
end

cached(:chef_run) do
solo.converge(described_recipe) do
solo.resource_collection.insert(
Chef::Resource::Service.new('datadog-agent', solo.run_context))
end
end

it 'security-agent.yaml is created' do
expect(chef_run).to create_template('C:/ProgramData/Datadog/security-agent.yaml')
end

it 'security-agent.yaml contains expected YAML configuration' do
expected_yaml = <<-EOF
compliance_config:
enabled: false
runtime_security_config:
enabled: true
activity_dump:
enabled: true
EOF

expect(chef_run).to(render_file('C:/ProgramData/Datadog/security-agent.yaml').with_content { |content|
expect(YAML.safe_load(content).to_json).to be_json_eql(YAML.safe_load(expected_yaml).to_json)
})
end
end
end
111 changes: 111 additions & 0 deletions spec/system-probe_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -240,4 +240,115 @@
})
end
end

context 'with CWS enabled' do
cached(:solo) do
ChefSpec::SoloRunner.new(
platform: 'ubuntu',
version: '16.04'
) do |node|
node.name 'chef-nodename' # expected to be used as the hostname in `datadog.yaml`
node.normal['datadog'] = {
'api_key' => 'somethingnotnil',
'agent_major_version' => 6,
'security_agent' => {
'cws' => {
'enabled' => true,
}
},
'extra_config' => {
'security_agent' => {
'runtime_security_config' => {
'activity_dump' => {
'enabled' => true,
}
}
}
}
}
end
end

cached(:chef_run) do
solo.converge(described_recipe) do
solo.resource_collection.insert(
Chef::Resource::Service.new('datadog-agent', solo.run_context))
solo.resource_collection.insert(
Chef::Resource::Service.new('datadog-agent-security', solo.run_context))
end
end

it 'system-probe.yaml is created' do
expect(chef_run).to create_template('/etc/datadog-agent/system-probe.yaml')
end

it 'system-probe.yaml contains expected YAML configuration' do
expected_yaml = <<-EOF
runtime_security_config:
enabled: true
activity_dump:
enabled: true
system_probe_config:
enabled: false
bpf_debug: false
debug_port: 0
enable_conntrack: false
sysprobe_socket: '/opt/datadog-agent/run/sysprobe.sock'
EOF

expect(chef_run).to(render_file('/etc/datadog-agent/system-probe.yaml').with_content { |content|
expect(YAML.safe_load(content).to_json).to be_json_eql(YAML.safe_load(expected_yaml).to_json)
})
end
end

context 'with CWS enabled on Windows' do
cached(:solo) do
ChefSpec::SoloRunner.new(
platform: 'windows',
version: '2012R2'
) do |node|
node.name 'chef-nodename' # expected to be used as the hostname in `datadog.yaml`
node.normal['datadog'] = {
'api_key' => 'somethingnotnil',
'agent_major_version' => 6,
'security_agent' => {
'cws' => {
'enabled' => true,
}
}
}
end
end

cached(:chef_run) do
solo.converge(described_recipe) do
solo.resource_collection.insert(
Chef::Resource::Service.new('datadog-agent', solo.run_context))
solo.resource_collection.insert(
Chef::Resource::Service.new('datadog-agent-security', solo.run_context))
end
end

it 'system-probe.yaml is created' do
expect(chef_run).to create_template('C:/ProgramData/Datadog/system-probe.yaml')
end

it 'system-probe.yaml contains expected YAML configuration' do
expected_yaml = <<-EOF
runtime_security_config:
enabled: true
system_probe_config:
enabled: false
bpf_debug: false
debug_port: 0
enable_conntrack: false
sysprobe_socket: 'localhost:3333'
EOF

expect(chef_run).to(render_file('C:/ProgramData/Datadog/system-probe.yaml').with_content { |content|
expect(YAML.safe_load(content).to_json).to be_json_eql(YAML.safe_load(expected_yaml).to_json)
})
end
end
end

0 comments on commit 9c2c583

Please sign in to comment.