Private
Public Access
1
0

feat(M11+M12): Email notifications, audit hardening, deployment packaging, backup/DR, integration testing

M11 - Email Notifications + Audit Logging Hardening:
- Email notifier (lettre crate) with templates for patch failure, job completion, maintenance reminders
- Audit log hash chaining (prev_hash + row_hash) for tamper-evident logging
- Periodic + on-demand audit integrity verification
- Audit logging for all config changes and certificate operations
- Frontend: email settings integration, audit integrity verification action

M12 - Deployment Packaging, Backup/DR, Integration Testing:
- scripts/backup.sh: Nightly pg_dump, CA backup (GPG), config backup (secrets excluded unless encrypted)
- scripts/setup.sh: Enhanced with backup dir, seed migration, backup cron, systemd target install
- systemd units: Restart=always, WatchdogSec, ReadWritePaths, security hardening
- systemd/patch-manager.target: Service target for coordinated lifecycle
- docs/runbooks/restore.md: Full DR runbook with RPO 24h / RTO 4h targets
- scripts/integration-test.sh: 9 test suites covering full API lifecycle
- scripts/performance-test.sh: NFR validation (dashboard <5s, CIDR /22 <10s, API <2s)
- docs/security-review.md: Comprehensive security control verification
- docs/compliance-mapping.md: HIPAA (6 sections) + PCI-DSS v4.0 (9 requirements) mapped
This commit is contained in:
2026-04-24 00:45:51 +00:00
parent 84ab92f4f0
commit 297bf1bd83
26 changed files with 2651 additions and 65 deletions

View File

@ -1,8 +1,10 @@
[Unit]
Description=Linux Patch Manager — Web Server
Documentation=https://gitea.moon-dragon.us/echo/linux_patch_manager
After=network.target postgresql.service
After=network-online.target postgresql.service
Wants=network-online.target
Requires=postgresql.service
PartOf=patch-manager.target
[Service]
Type=simple
@ -16,22 +18,40 @@ Environment="PATCH_MANAGER_CONFIG=/etc/patch-manager/config.toml"
# Environment="PATCH_MANAGER__DATABASE__URL=postgres://..."
ExecStart=/usr/local/bin/pm-web
Restart=on-failure
# Restart policy — aggressive restart for production availability
Restart=always
RestartSec=5s
StartLimitIntervalSec=60
StartLimitBurst=5
# Timeouts
TimeoutStartSec=90s
TimeoutStopSec=30s
# Watchdog — pm-web must report health within this interval
WatchdogSec=120s
# Security hardening
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/var/log/patch-manager
ReadWritePaths=/var/log/patch-manager /etc/patch-manager/ca /etc/patch-manager/certs /etc/patch-manager/tls /etc/patch-manager/jwt /usr/share/patch-manager/frontend
PrivateTmp=true
PrivateDevices=true
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectControlGroups=true
RestrictNamespaces=true
RestrictSUIDSGID=true
# Allow binding to port 443 without root
AmbientCapabilities=CAP_NET_BIND_SERVICE
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
# File descriptor limits
LimitNOFILE=65536
# Logging
StandardOutput=journal
StandardError=journal

View File

@ -1,10 +1,12 @@
[Unit]
Description=Linux Patch Manager — Background Worker
Documentation=https://gitea.moon-dragon.us/echo/linux_patch_manager
After=network.target postgresql.service patch-manager-web.service
After=network-online.target postgresql.service patch-manager-web.service
Wants=network-online.target
Requires=postgresql.service
# Worker waits for the web process to apply migrations before starting tasks
Wants=patch-manager-web.service
PartOf=patch-manager.target
[Service]
Type=simple
@ -16,17 +18,35 @@ WorkingDirectory=/opt/patch-manager
Environment="PATCH_MANAGER_CONFIG=/etc/patch-manager/config.toml"
ExecStart=/usr/local/bin/pm-worker
Restart=on-failure
# Restart policy — aggressive restart for production availability
Restart=always
RestartSec=10s
TimeoutStopSec=60s
StartLimitIntervalSec=120
StartLimitBurst=5
# Timeouts — worker may take longer to drain active jobs
TimeoutStartSec=120s
TimeoutStopSec=120s
# Watchdog — worker must report heartbeat within this interval
WatchdogSec=180s
# Security hardening
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/var/log/patch-manager
ReadWritePaths=/var/log/patch-manager /etc/patch-manager/ca /etc/patch-manager/certs /etc/patch-manager/tls /etc/patch-manager/jwt
PrivateTmp=true
PrivateDevices=true
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectControlGroups=true
RestrictNamespaces=true
RestrictSUIDSGID=true
# File descriptor limits
LimitNOFILE=65536
# Logging
StandardOutput=journal

View File

@ -0,0 +1,7 @@
[Unit]
Description=Linux Patch Manager — Service Target
Documentation=https://gitea.moon-dragon.us/echo/linux_patch_manager
Wants=patch-manager-web.service patch-manager-worker.service
[Install]
WantedBy=multi-user.target