170 lines
7.1 KiB
YAML
170 lines
7.1 KiB
YAML
---
|
|
- name: Deploy AWatch-rus Windows phase2 collectors
|
|
hosts: aw_windows
|
|
gather_facts: false
|
|
|
|
vars:
|
|
aw_windows_repo_root: "/home/igor/tmp/AWatch-rus"
|
|
aw_windows_deploy_root: "C:\\Deploy\\AWatch-rus"
|
|
aw_windows_server_host: "10.10.10.13"
|
|
aw_windows_server_port: 5600
|
|
aw_windows_domain: "SHARKON2025"
|
|
aw_windows_users:
|
|
- user1
|
|
- user2
|
|
- user3
|
|
- user4
|
|
- user5
|
|
aw_windows_extra_users: []
|
|
aw_windows_users_effective: "{{ (aw_windows_users + aw_windows_extra_users) | unique }}"
|
|
aw_windows_install_root: "C:\\Program Files\\ActivityWatch-Phase2"
|
|
aw_windows_state_root: "C:\\ProgramData\\ActivityWatch"
|
|
aw_windows_afk_enabled: true
|
|
aw_windows_window_enabled: true
|
|
aw_windows_local_agent_logs_enabled: false
|
|
aw_windows_incident_capture_enabled: true
|
|
aw_windows_incident_screenshot_enabled: true
|
|
aw_windows_incident_artifacts_root: "{{ aw_windows_state_root }}\\incident-artifacts"
|
|
aw_windows_logon_marker_enabled: true
|
|
aw_windows_skip_hardening: false
|
|
aw_windows_rules_path: "{{ aw_windows_deploy_root }}\\windows\\web-category-rules.example.json"
|
|
aw_windows_policy_path: "{{ aw_windows_deploy_root }}\\windows\\dlp-policy.example.json"
|
|
aw_windows_validation_remote_path: "C:\\Windows\\Temp\\aw_validate_phase2_ansible.json"
|
|
aw_windows_validation_local_dir: "/tmp/aw-rus-validation"
|
|
aw_windows_launch_task_pattern: "ActivityWatch Launch *"
|
|
aw_windows_recovery_task_name: "ActivityWatch Recovery"
|
|
aw_windows_force_task_restart: true
|
|
aw_windows_api_smoke_check_enabled: true
|
|
aw_windows_api_smoke_check_bucket: "aw-watcher-afk_SHARKON2025"
|
|
aw_windows_api_smoke_check_limit: 10
|
|
|
|
tasks:
|
|
- name: Validate required variables
|
|
ansible.builtin.assert:
|
|
that:
|
|
- aw_windows_server_host is defined
|
|
- aw_windows_server_port is defined
|
|
- aw_windows_domain is defined
|
|
- aw_windows_users_effective | length > 0
|
|
- aw_windows_install_root is defined
|
|
- aw_windows_state_root is defined
|
|
fail_msg: "Missing required Windows deployment variables."
|
|
|
|
- name: Ensure deploy directories exist
|
|
ansible.windows.win_file:
|
|
path: "{{ item }}"
|
|
state: directory
|
|
loop:
|
|
- "{{ aw_windows_deploy_root }}"
|
|
- "{{ aw_windows_deploy_root }}\\windows"
|
|
|
|
- name: Upload Windows deployment toolkit
|
|
ansible.windows.win_copy:
|
|
src: "{{ aw_windows_repo_root }}/windows/{{ item }}"
|
|
dest: "{{ aw_windows_deploy_root }}\\windows\\{{ item }}"
|
|
loop:
|
|
- ActivityWatch.Windows.Common.psd1
|
|
- ActivityWatch.Windows.Common.psm1
|
|
- browser-domains-native-collector.ps1
|
|
- dlp-endpoint-signals-collector.ps1
|
|
- deploy-domain-users.ps1
|
|
- deploy-ensemble.ps1
|
|
- hardening-recovery.ps1
|
|
- validate-deployment.ps1
|
|
- web-category-rules.example.json
|
|
- dlp-policy.example.json
|
|
|
|
- name: Upload user list for domain deploy
|
|
ansible.windows.win_copy:
|
|
dest: "{{ aw_windows_deploy_root }}\\windows\\users.txt"
|
|
content: |
|
|
{% for user in aw_windows_users -%}
|
|
{{ user }}
|
|
{% endfor -%}
|
|
{% for user in aw_windows_extra_users -%}
|
|
{{ user }}
|
|
{% endfor -%}
|
|
|
|
- name: Run phase2 ensemble deployment
|
|
ansible.windows.win_powershell:
|
|
script: |
|
|
$ErrorActionPreference = 'Stop'
|
|
$params = @{
|
|
ServerHost = "{{ aw_windows_server_host }}"
|
|
ServerPort = {{ aw_windows_server_port }}
|
|
Domain = "{{ aw_windows_domain }}"
|
|
UserListPath = "{{ aw_windows_deploy_root }}\windows\users.txt"
|
|
InstallRoot = "{{ aw_windows_install_root }}"
|
|
StateRoot = "{{ aw_windows_state_root }}"
|
|
AfkEnabled = {{ '$true' if (aw_windows_afk_enabled | bool) else '$false' }}
|
|
WindowEnabled = {{ '$true' if (aw_windows_window_enabled | bool) else '$false' }}
|
|
LocalAgentLogsEnabled = {{ '$true' if (aw_windows_local_agent_logs_enabled | bool) else '$false' }}
|
|
IncidentCaptureEnabled = {{ '$true' if (aw_windows_incident_capture_enabled | bool) else '$false' }}
|
|
IncidentScreenshotEnabled = {{ '$true' if (aw_windows_incident_screenshot_enabled | bool) else '$false' }}
|
|
IncidentArtifactsRoot = "{{ aw_windows_incident_artifacts_root }}"
|
|
LogonMarkerEnabled = {{ '$true' if (aw_windows_logon_marker_enabled | bool) else '$false' }}
|
|
CustomRulesPath = "{{ aw_windows_rules_path }}"
|
|
CustomPolicyPath = "{{ aw_windows_policy_path }}"
|
|
}
|
|
{% if aw_windows_skip_hardening | bool %}
|
|
$params.SkipHardening = $true
|
|
{% endif %}
|
|
& "{{ aw_windows_deploy_root }}\windows\deploy-ensemble.ps1" @params
|
|
|
|
- name: Force start ActivityWatch recovery and launch tasks
|
|
when: aw_windows_force_task_restart | bool
|
|
ansible.windows.win_powershell:
|
|
script: |
|
|
$ErrorActionPreference = 'Stop'
|
|
Start-ScheduledTask -TaskName "{{ aw_windows_recovery_task_name }}"
|
|
Get-ScheduledTask |
|
|
Where-Object TaskName -like "{{ aw_windows_launch_task_pattern }}" |
|
|
ForEach-Object { Start-ScheduledTask -TaskName $_.TaskName }
|
|
|
|
- name: Wait for fresh AFK events to appear on AW server
|
|
when: aw_windows_api_smoke_check_enabled | bool
|
|
delegate_to: localhost
|
|
ansible.builtin.uri:
|
|
url: "http://{{ aw_windows_server_host }}:{{ aw_windows_server_port }}/api/0/buckets/{{ aw_windows_api_smoke_check_bucket }}/events?limit={{ aw_windows_api_smoke_check_limit }}"
|
|
method: GET
|
|
return_content: true
|
|
register: aw_windows_api_smoke
|
|
until: >
|
|
aw_windows_api_smoke.status == 200 and
|
|
(aw_windows_api_smoke.json | length) > 0 and
|
|
(
|
|
aw_windows_api_smoke.json
|
|
| selectattr('data.status', 'equalto', 'not-afk')
|
|
| list
|
|
| length
|
|
) > 0
|
|
retries: 10
|
|
delay: 6
|
|
|
|
- name: Run validation and store report on target
|
|
ansible.windows.win_powershell:
|
|
script: |
|
|
$ErrorActionPreference = 'Stop'
|
|
$report = & "{{ aw_windows_deploy_root }}\windows\validate-deployment.ps1" `
|
|
-ConfigPath "{{ aw_windows_state_root }}\deployment-config.json"
|
|
$report | ConvertTo-Json -Depth 12 | Out-File -FilePath "{{ aw_windows_validation_remote_path }}" -Encoding utf8
|
|
|
|
- name: Ensure local validation directory exists
|
|
ansible.builtin.file:
|
|
path: "{{ aw_windows_validation_local_dir }}"
|
|
state: directory
|
|
mode: "0755"
|
|
delegate_to: localhost
|
|
|
|
- name: Fetch validation report
|
|
ansible.builtin.fetch:
|
|
src: "{{ aw_windows_validation_remote_path }}"
|
|
dest: "{{ aw_windows_validation_local_dir }}/"
|
|
flat: false
|
|
|
|
- name: Show report location
|
|
ansible.builtin.debug:
|
|
msg:
|
|
- "Windows phase2 deploy completed on {{ inventory_hostname }}."
|
|
- "Validation report: {{ aw_windows_validation_local_dir }}/{{ inventory_hostname }}/C$/Windows/Temp/aw_validate_phase2_ansible.json"
|