prole/infrastructure/roles/audit/tasks/main.yml

205 lines
6.8 KiB
YAML

---
- name: Build audit allowlists
ansible.builtin.set_fact:
prole_audit_scan_paths_combined: >-
{{ (prole_audit_scan_paths | default([]))
+ (prole_audit_scan_paths_extra | default([]))
| unique }}
prole_audit_allow_prefixes_combined: >-
{{ (prole_audit_allow_prefixes | default([]))
+ (prole_audit_allow_prefixes_extra | default([]))
| unique }}
changed_when: false
- name: Verify dpkg database (Debian only)
ansible.builtin.command: >-
dpkg -V {{ prole_audit_dpkg_verify_packages | default([]) | join(' ') }}
register: prole_audit_dpkg_verify
changed_when: false
failed_when: false
check_mode: false
when: ansible_facts.os_family == "Debian"
- name: List files not owned by dpkg and not managed by prole
ansible.builtin.shell:
cmd: |
set -euo pipefail
paths=({{ prole_audit_scan_paths_combined | map('quote') | join(' ') }})
ALLOW_PREFIXES="$(printf '%s\n' {{ prole_audit_allow_prefixes_combined | map('quote') | join(' ') }})"
export ALLOW_PREFIXES
valid_paths=()
for p in "${paths[@]}"; do
if [ -e "$p" ]; then
valid_paths+=("$p")
fi
done
if [ "${#valid_paths[@]}" -eq 0 ]; then
exit 0
fi
{
find "${valid_paths[@]}" -xdev \( -type f -o -type l \) -print0 |
awk -v RS='\0' '
BEGIN { n = split(ENVIRON["ALLOW_PREFIXES"], a, "\n") }
{
allowed = 0
for (i = 1; i <= n; i++) {
p = a[i]
if (p != "" && index($0, p) == 1) {
if (length($0) == length(p) || substr($0, length(p) + 1, 1) == "/") {
allowed = 1
break
}
}
}
if (!allowed) { printf "%s\0", $0 }
}' |
xargs -0 -r -n 200 dpkg -S 2>&1 >/dev/null || true
} | sed -n 's/^dpkg-query: no path found matching pattern //p' | sort -u
args:
executable: /bin/bash
register: prole_audit_unowned
changed_when: false
check_mode: false
when:
- ansible_facts.os_family == "Debian"
- prole_audit_scan_paths_combined | length > 0
- name: Check k3s binary
ansible.builtin.stat:
path: /usr/local/bin/k3s
register: prole_audit_k3s_stat
changed_when: false
check_mode: false
- name: Read k3s version
ansible.builtin.command: /usr/local/bin/k3s --version
register: prole_audit_k3s_version
changed_when: false
failed_when: false
check_mode: false
when: prole_audit_k3s_stat.stat.exists
- name: Hash k3s binary
ansible.builtin.command: sha256sum /usr/local/bin/k3s
register: prole_audit_k3s_sha
changed_when: false
check_mode: false
when: prole_audit_k3s_stat.stat.exists
- name: Check k3s dpkg owner
ansible.builtin.command: dpkg -S /usr/local/bin/k3s
register: prole_audit_k3s_owner
changed_when: false
failed_when: false
check_mode: false
when: prole_audit_k3s_stat.stat.exists and ansible_facts.os_family == "Debian"
- name: Build k3s provenance
ansible.builtin.set_fact:
prole_audit_k3s_provenance:
path: /usr/local/bin/k3s
exists: "{{ prole_audit_k3s_stat.stat.exists | default(false) }}"
sha256: "{{ (prole_audit_k3s_sha.stdout | default('')) | regex_replace('\\s+.*$', '') }}"
version: "{{ prole_audit_k3s_version.stdout | default('') }}"
dpkg_owner: >-
{{ (prole_audit_k3s_owner.stdout | default('')) if (prole_audit_k3s_owner is defined and prole_audit_k3s_owner.rc == 0)
else 'unowned' }}
changed_when: false
- name: Locate helm binary
ansible.builtin.shell: command -v helm
register: prole_audit_helm_path
changed_when: false
failed_when: false
check_mode: false
- name: Read helm version
ansible.builtin.command:
argv:
- "{{ prole_audit_helm_path.stdout | trim }}"
- version
- --short
register: prole_audit_helm_version
changed_when: false
failed_when: false
check_mode: false
when: prole_audit_helm_path.rc == 0
- name: Hash helm binary
ansible.builtin.command: sha256sum "{{ prole_audit_helm_path.stdout | trim }}"
register: prole_audit_helm_sha
changed_when: false
check_mode: false
when: prole_audit_helm_path.rc == 0
- name: Check helm dpkg owner
ansible.builtin.command: dpkg -S "{{ prole_audit_helm_path.stdout | trim }}"
register: prole_audit_helm_owner
changed_when: false
failed_when: false
check_mode: false
when: prole_audit_helm_path.rc == 0 and ansible_facts.os_family == "Debian"
- name: Build helm provenance
ansible.builtin.set_fact:
prole_audit_helm_provenance:
path: "{{ prole_audit_helm_path.stdout | default('') | trim }}"
exists: "{{ prole_audit_helm_path.rc == 0 }}"
sha256: "{{ (prole_audit_helm_sha.stdout | default('')) | regex_replace('\\s+.*$', '') }}"
version: "{{ prole_audit_helm_version.stdout | default('') }}"
dpkg_owner: >-
{{ (prole_audit_helm_owner.stdout | default('')) if (prole_audit_helm_owner is defined and prole_audit_helm_owner.rc == 0)
else 'unowned' }}
changed_when: false
- name: Query tracked package versions
ansible.builtin.shell: >-
dpkg-query -W -f='${Package} ${Version} ${Architecture}\n'
{{ prole_audit_tracked_packages | default([]) | join(' ') }}
register: prole_audit_tracked_pkgs
changed_when: false
failed_when: false
check_mode: false
when:
- ansible_facts.os_family == "Debian"
- prole_audit_tracked_packages | default([]) | length > 0
- name: Report dpkg verification changes
ansible.builtin.debug:
msg: >-
{{ ((prole_audit_dpkg_verify.stdout_lines | default([]))
+ (prole_audit_dpkg_verify.stderr_lines | default([])))
if ((prole_audit_dpkg_verify.stdout_lines | default([]) | length) > 0
or (prole_audit_dpkg_verify.stderr_lines | default([]) | length) > 0)
else ['dpkg -V returned no differences'] }}
when: prole_audit_dpkg_verify is defined
- name: Report files not owned by dpkg and not managed by prole
ansible.builtin.debug:
msg: >-
{{ (prole_audit_unowned.stdout_lines | default([]))
if (prole_audit_unowned.stdout_lines | default([]) | length) > 0
else ['no unowned files found in scan paths'] }}
when: prole_audit_unowned is defined
- name: Report tracked package versions
ansible.builtin.debug:
msg: >-
{{ ((prole_audit_tracked_pkgs.stdout_lines | default([]))
+ (prole_audit_tracked_pkgs.stderr_lines | default([])))
if ((prole_audit_tracked_pkgs.stdout_lines | default([]) | length) > 0
or (prole_audit_tracked_pkgs.stderr_lines | default([]) | length) > 0)
else ['no tracked packages reported'] }}
when: prole_audit_tracked_pkgs is defined
- name: Report k3s provenance
ansible.builtin.debug:
var: prole_audit_k3s_provenance
- name: Report helm provenance
ansible.builtin.debug:
var: prole_audit_helm_provenance