mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2025-08-29 15:06:26 +02:00
Another big round of refactoring and cleaning...
This commit is contained in:
27
roles/sys-hlth-csp/README.md
Normal file
27
roles/sys-hlth-csp/README.md
Normal file
@@ -0,0 +1,27 @@
|
||||
# Health CSP Crawler
|
||||
|
||||
## Description
|
||||
|
||||
This Ansible role automates the validation of [Content Security Policy (CSP)](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/CSP) enforcement for all configured domains by crawling them using a [CSP Checker](https://github.com/kevinveenbirkenbach/csp-checker).
|
||||
|
||||
## Overview
|
||||
|
||||
Designed for Archlinux systems, this role periodically checks whether web resources (JavaScript, fonts, images, etc.) are blocked by CSP headers. It integrates Python and Node.js tooling and installs a systemd service with timer support.
|
||||
|
||||
## Features
|
||||
|
||||
- **CSP Resource Validation:** Uses Puppeteer to simulate browser requests and detect blocked resources.
|
||||
- **Domain Extraction:** Parses all `.conf` files in the NGINX config folder to determine the list of domains to check.
|
||||
- **Automated Execution:** Registers a systemd service and timer for recurring health checks.
|
||||
- **Error Notification:** Integrates with `sys-alm-compose` for alerting on failure.
|
||||
|
||||
## License
|
||||
|
||||
CyMaIS NonCommercial License (CNCL)
|
||||
[https://s.veen.world/cncl](https://s.veen.world/cncl)
|
||||
|
||||
## Author
|
||||
|
||||
Kevin Veen-Birkenbach
|
||||
Consulting & Coaching Solutions
|
||||
[https://www.veen.world](https://www.veen.world)
|
62
roles/sys-hlth-csp/files/sys-hlth-csp.py
Normal file
62
roles/sys-hlth-csp/files/sys-hlth-csp.py
Normal file
@@ -0,0 +1,62 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
import argparse
|
||||
|
||||
def extract_domains(config_path):
|
||||
"""
|
||||
Extracts domain names from .conf filenames in the given directory.
|
||||
"""
|
||||
domain_pattern = re.compile(r'^([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}\.conf$')
|
||||
try:
|
||||
return [
|
||||
fn[:-5]
|
||||
for fn in os.listdir(config_path)
|
||||
if fn.endswith(".conf") and domain_pattern.match(fn)
|
||||
]
|
||||
except FileNotFoundError:
|
||||
print(f"Directory {config_path} not found.", file=sys.stderr)
|
||||
return None
|
||||
|
||||
def run_checkcsp(domains):
|
||||
"""
|
||||
Executes the 'checkcsp' command with the given domains.
|
||||
"""
|
||||
cmd = ["checkcsp", "start", "--short"] + domains
|
||||
try:
|
||||
result = subprocess.run(cmd, check=True)
|
||||
return result.returncode
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"'checkcsp' reported issues (exit code {e.returncode})", file=sys.stderr)
|
||||
return e.returncode
|
||||
except Exception as e:
|
||||
print(f"Unexpected error: {e}", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Extract domains from NGINX and run checkcsp against them"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--nginx-config-dir",
|
||||
required=True,
|
||||
help="Directory containing NGINX .conf files"
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
domains = extract_domains(args.nginx_config_dir)
|
||||
if domains is None:
|
||||
sys.exit(1)
|
||||
|
||||
if not domains:
|
||||
print("No domains found to check.")
|
||||
sys.exit(0)
|
||||
|
||||
rc = run_checkcsp(domains)
|
||||
sys.exit(rc)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
5
roles/sys-hlth-csp/handlers/main.yml
Normal file
5
roles/sys-hlth-csp/handlers/main.yml
Normal file
@@ -0,0 +1,5 @@
|
||||
- name: "reload sys-hlth-csp.cymais.service"
|
||||
systemd:
|
||||
name: sys-hlth-csp.cymais.service
|
||||
enabled: yes
|
||||
daemon_reload: yes
|
27
roles/sys-hlth-csp/meta/main.yml
Normal file
27
roles/sys-hlth-csp/meta/main.yml
Normal file
@@ -0,0 +1,27 @@
|
||||
galaxy_info:
|
||||
author: "Kevin Veen-Birkenbach"
|
||||
description: "Checks for CSP-blocked resources via Puppeteer-based Node.js crawler"
|
||||
license: "CyMaIS NonCommercial License (CNCL)"
|
||||
license_url: "https://s.veen.world/cncl"
|
||||
company: |
|
||||
Kevin Veen-Birkenbach
|
||||
Consulting & Coaching Solutions
|
||||
https://www.veen.world
|
||||
min_ansible_version: "2.9"
|
||||
platforms:
|
||||
- name: Archlinux
|
||||
versions:
|
||||
- rolling
|
||||
galaxy_tags:
|
||||
- csp
|
||||
- puppeteer
|
||||
- health
|
||||
- browser
|
||||
- nodejs
|
||||
- monitoring
|
||||
- systemd
|
||||
repository: "https://s.veen.world/cymais"
|
||||
issue_tracker_url: "https://s.veen.world/cymaisissues"
|
||||
documentation: "https://s.veen.world/cymais"
|
||||
dependencies:
|
||||
- sys-alm-compose
|
48
roles/sys-hlth-csp/tasks/main.yml
Normal file
48
roles/sys-hlth-csp/tasks/main.yml
Normal file
@@ -0,0 +1,48 @@
|
||||
- name: "pkgmgr install"
|
||||
include_role:
|
||||
name: pkgmgr-install
|
||||
vars:
|
||||
package_name: checkcsp
|
||||
when: run_once_health_csp is not defined
|
||||
|
||||
- name: rebuild checkcsp docker image
|
||||
shell: checkcsp build
|
||||
# Todo this could be optimized in the future
|
||||
|
||||
- name: "create {{ health_csp_crawler_folder }}"
|
||||
file:
|
||||
path: "{{ health_csp_crawler_folder }}"
|
||||
state: directory
|
||||
mode: 0755
|
||||
when: run_once_health_csp is not defined
|
||||
|
||||
- name: copy sys-hlth-csp.py
|
||||
copy:
|
||||
src: sys-hlth-csp.py
|
||||
dest: "{{ health_csp_crawler_script }}"
|
||||
mode: 0755
|
||||
when: run_once_health_csp is not defined
|
||||
|
||||
- name: create sys-hlth-csp.cymais.service
|
||||
template:
|
||||
src: sys-hlth-csp.service.j2
|
||||
dest: /etc/systemd/system/sys-hlth-csp.cymais.service
|
||||
notify: reload sys-hlth-csp.cymais.service
|
||||
when: run_once_health_csp is not defined
|
||||
|
||||
- name: set service_name to role_name
|
||||
set_fact:
|
||||
service_name: "{{ role_name }}"
|
||||
when: run_once_health_csp is not defined
|
||||
|
||||
- name: include systemd timer role
|
||||
include_role:
|
||||
name: sys-timer
|
||||
vars:
|
||||
on_calendar: "{{ on_calendar_health_csp_crawler }}"
|
||||
when: run_once_health_csp is not defined
|
||||
|
||||
- name: run the health_csp tasks once
|
||||
set_fact:
|
||||
run_once_health_csp: true
|
||||
when: run_once_health_csp is not defined
|
8
roles/sys-hlth-csp/templates/sys-hlth-csp.service.j2
Normal file
8
roles/sys-hlth-csp/templates/sys-hlth-csp.service.j2
Normal file
@@ -0,0 +1,8 @@
|
||||
[Unit]
|
||||
Description=Check for CSP-blocked resources via Puppeteer
|
||||
OnFailure=sys-alm-compose.cymais@%n.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart=/usr/bin/python3 {{ health_csp_crawler_script }} \
|
||||
--nginx-config-dir={{ nginx.directories.http.servers }}
|
3
roles/sys-hlth-csp/vars/main.yml
Normal file
3
roles/sys-hlth-csp/vars/main.yml
Normal file
@@ -0,0 +1,3 @@
|
||||
health_csp_crawler_folder: '{{ path_administrator_scripts }}sys-hlth-csp/'
|
||||
health_csp_crawler_script: '{{ health_csp_crawler_folder }}sys-hlth-csp.py'
|
||||
|
Reference in New Issue
Block a user