Add Ansible-based maintenance scripts for infrastructure operations: - CVE scanner using NIST NVD database - Package update checker with OpenAI risk assessment - Docker cleanup playbook - Log archiver for rotated logs - Disk space analyzer Supports Ubuntu 20.04/22.04/24.04, Debian 11/12/13, and Alpine Linux
111 lines
4.0 KiB
YAML
111 lines
4.0 KiB
YAML
---
|
|
- name: Identify Packages with CVE Vulnerabilities
|
|
hosts: all
|
|
gather_facts: true
|
|
vars:
|
|
cve_nvd_api_url: "https://services.nvd.nist.gov/rest/json/cves/2.0"
|
|
output_file: "/tmp/cve_report_{{ ansible_date_time.iso8601_basic_short }}.json"
|
|
results_per_page: 2000
|
|
|
|
tasks:
|
|
- name: Detect OS family and set package manager
|
|
set_fact:
|
|
pkg_mgr: "{{ 'apt' if ansible_os_family == 'Debian' else 'apk' if ansible_os_family == 'Alpine' else 'unknown' }}"
|
|
|
|
- name: Ensure required packages are installed
|
|
package:
|
|
name:
|
|
- curl
|
|
- jq
|
|
state: present
|
|
|
|
- name: Get installed packages with versions (Debian/Ubuntu)
|
|
command: dpkg-query -W -f='${Package}\t${Version}\n'
|
|
register: installed_packages_debian
|
|
changed_when: false
|
|
when: ansible_os_family == 'Debian'
|
|
|
|
- name: Get installed packages with versions (Alpine)
|
|
command: apk info -vv
|
|
register: installed_packages_alpine
|
|
changed_when: false
|
|
when: ansible_os_family == 'Alpine'
|
|
|
|
- name: Parse package list into dictionary
|
|
set_fact:
|
|
package_dict: "{{ installed_packages_debian.stdout | default('') | split('\n') | select('match', '^.+\t.+$') | map('regex_replace', '^(.+?)\\t(.+)$', '{\"name\": \"\\1\", \"version\": \"\\2\"}') | map('from_json') | list }}"
|
|
when: ansible_os_family == 'Debian'
|
|
|
|
- name: Parse Alpine package list into dictionary
|
|
set_fact:
|
|
package_dict: "{{ installed_packages_alpine.stdout | default('') | split('\n') | select('match', '^.+-.+$') | map('regex_replace', '^(.+?)-([0-9].+)$', '{\"name\": \"\\1\", \"version\": \"\\2\"}') | map('from_json') | list }}"
|
|
when: ansible_os_family == 'Alpine'
|
|
|
|
- name: Query NVD CVE database for each package
|
|
uri:
|
|
url: "{{ cve_nvd_api_url }}"
|
|
method: GET
|
|
return_content: true
|
|
validate_certs: false
|
|
headers:
|
|
User-Agent: "Ansible-CVE-Scanner/1.0"
|
|
register: nvd_response
|
|
failed_when: false
|
|
until: nvd_response.status == 200
|
|
retries: 3
|
|
delay: 2
|
|
|
|
- name: Extract CVE data from NVD response
|
|
set_fact:
|
|
cve_data: "{{ nvd_response.content | from_json | json_query('vulnerabilities[*]') }}"
|
|
when: nvd_response.status == 200
|
|
|
|
- name: Match CVEs with installed packages
|
|
set_fact:
|
|
cve_findings: >-
|
|
{{ cve_findings | default([]) +
|
|
[{
|
|
'package': item.package_name,
|
|
'version': item.version,
|
|
'cves': cve_data | selectattr('cve.id', 'defined') |
|
|
selectattr('cve.descriptions[*].value', 'contains', item.package_name) |
|
|
map(attribute='cve') | list,
|
|
'hostname': ansible_hostname,
|
|
'ip_address': ansible_default_ipv4.address,
|
|
'os': ansible_distribution + ' ' + ansible_distribution_version,
|
|
'scan_date': ansible_date_time.iso8601
|
|
}]
|
|
}}
|
|
loop: "{{ package_dict }}"
|
|
loop_control:
|
|
loop_var: item
|
|
vars:
|
|
package_name: "{{ item.name }}"
|
|
version: "{{ item.version }}"
|
|
|
|
- name: Filter packages with CVEs
|
|
set_fact:
|
|
affected_packages: "{{ cve_findings | selectattr('cves', 'defined') | selectattr('cves', 'length', 'gt', 0) | list }}"
|
|
|
|
- name: Generate CVE report JSON
|
|
copy:
|
|
dest: "{{ output_file }}"
|
|
content: "{{ affected_packages | to_json(indent=2) }}"
|
|
mode: '0600'
|
|
|
|
- name: Display CVE summary
|
|
debug:
|
|
msg: "Found {{ affected_packages | length }} packages with CVEs. Report saved to {{ output_file }}"
|
|
|
|
- name: Return CVE findings
|
|
set_fact:
|
|
cve_report:
|
|
hostname: ansible_hostname
|
|
ip_address: ansible_default_ipv4.address
|
|
os: ansible_distribution + ' ' + ansible_distribution_version
|
|
total_packages: package_dict | length
|
|
packages_with_cves: affected_packages | length
|
|
findings: affected_packages
|
|
scan_date: ansible_date_time.iso8601
|
|
report_file: output_file
|