Merge pull request #4 from beatz174-bit/codex/create-inventory-of-internet-facing-apps
Add lifecycle and vulnerability management plan for internet-facing services
This commit is contained in:
@@ -0,0 +1,144 @@
|
||||
# Internet-Facing Stack Lifecycle & Vulnerability Management
|
||||
|
||||
_Last updated: 2026-04-07 (UTC)_
|
||||
|
||||
## 1) Internet-facing application inventory (app, version, image digest)
|
||||
|
||||
> Source of truth for internet-facing targets: `results/*` host folders and their WhatWeb outputs.
|
||||
> Operational owner must replace all `TBD` digest values with runtime evidence from `docker image inspect`/`docker ps --no-trunc`.
|
||||
|
||||
| Host/FQDN | Product/App | Deployed version evidence | Container image (repo:tag) | Image digest (sha256) | Evidence source |
|
||||
|---|---|---|---|---|---|
|
||||
| auth.lan.ddnsgeek.com | Authelia (auth portal) | Version not fingerprinted from external scan | TBD | TBD | `results/auth.../tcp_443_https_whatweb.txt` |
|
||||
| edge.lan.ddnsgeek.com | Edge reverse-proxy/app entrypoint | Version not fingerprinted from external scan | TBD | TBD | `results/edge.../tcp_443_https_whatweb.txt` |
|
||||
| familytree.lan.ddnsgeek.com | FamilyTree app (gunicorn-backed) | gunicorn detected, app version not fingerprinted | TBD | TBD | `results/familytree.../tcp_443_https_whatweb.txt` |
|
||||
| gitea.lan.ddnsgeek.com | Gitea | Gitea detected; exact version not fingerprinted | TBD | TBD | `results/gitea.../tcp_443_https_whatweb.txt` |
|
||||
| gotify.lan.ddnsgeek.com | Gotify | Version not fingerprinted from external scan | TBD | TBD | `results/gotify.../tcp_443_https_whatweb.txt` |
|
||||
| grafana.lan.ddnsgeek.com | Grafana | Grafana login redirect observed; exact version not fingerprinted | TBD | TBD | `results/grafana.../tcp_443_https_whatweb.txt` |
|
||||
| influxdb.lan.ddnsgeek.com | InfluxDB (behind auth) | Version not fingerprinted from external scan | TBD | TBD | `results/influxdb.../tcp_443_https_whatweb.txt` |
|
||||
| kuma.lan.ddnsgeek.com | Uptime Kuma | Dashboard redirect observed; exact version not fingerprinted | TBD | TBD | `results/kuma.../tcp_443_https_whatweb.txt` |
|
||||
| monitor-kuma.lan.ddnsgeek.com | Uptime Kuma (monitoring endpoint) | Dashboard redirect observed; exact version not fingerprinted | TBD | TBD | `results/monitor-kuma.../tcp_443_https_whatweb.txt` |
|
||||
| nextcloud.lan.ddnsgeek.com | Nextcloud (Apache/PHP stack) | Apache 2.4.66, PHP 8.3.30 | TBD | TBD | `results/nextcloud.../tcp_443_https_whatweb.txt` |
|
||||
| node-red.lan.ddnsgeek.com | Node-RED (behind auth) | Version not fingerprinted from external scan | TBD | TBD | `results/node-red.../tcp_443_https_whatweb.txt` |
|
||||
| passbolt.lan.ddnsgeek.com | Passbolt | NGINX detected; exact Passbolt version not fingerprinted | TBD | TBD | `results/passbolt.../tcp_443_https_whatweb.txt` |
|
||||
| portainer.lan.ddnsgeek.com | Portainer | Portainer detected; exact version not fingerprinted | TBD | TBD | `results/portainer.../tcp_443_https_whatweb.txt` |
|
||||
| prometheus.lan.ddnsgeek.com | Prometheus (behind auth) | Version not fingerprinted from external scan | TBD | TBD | `results/prometheus.../tcp_443_https_whatweb.txt` |
|
||||
| searxng.lan.ddnsgeek.com | SearXNG | `searxng/2026.4.5+474b0a55b` detected | TBD | TBD | `results/searxng.../tcp_443_https_whatweb.txt` |
|
||||
| shifts.lan.ddnsgeek.com | Shifts app (nginx front-end) | nginx 1.29.7 | TBD | TBD | `results/shifts.../tcp_443_https_whatweb.txt` |
|
||||
| stockfill.lan.ddnsgeek.com | Stockfill app (nginx front-end) | nginx 1.27.5 | TBD | TBD | `results/stockfill.../tcp_443_https_whatweb.txt` |
|
||||
| traefik.lan.ddnsgeek.com | Traefik (behind auth) | Version not fingerprinted from external scan | TBD | TBD | `results/traefik.../tcp_443_https_whatweb.txt` |
|
||||
|
||||
### Required evidence commands (run on Docker host)
|
||||
|
||||
```bash
|
||||
# Capture deployed containers with immutable image digest references
|
||||
sudo docker ps --format '{{.Names}}\t{{.Image}}' --no-trunc
|
||||
|
||||
# Resolve image digests for inventory table
|
||||
sudo docker image inspect <image:tag> --format '{{index .RepoDigests 0}}'
|
||||
|
||||
# Optional: export inventory as CSV for compliance tracking
|
||||
sudo docker ps --format '{{.Names}},{{.Image}}' --no-trunc > internet-facing-runtime-images.csv
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2) Monthly update window definition
|
||||
|
||||
## Standard cadence
|
||||
- **Window:** Second Tuesday of every month, **02:00–06:00 UTC**.
|
||||
- **Fallback window:** Second Wednesday of every month, **02:00–06:00 UTC**.
|
||||
- **Emergency patch window (critical CVE only):** within **48 hours** of advisory triage.
|
||||
|
||||
## Scope per window
|
||||
1. **OS packages** (host + VM base images): apply security and bugfix updates.
|
||||
2. **Container base images**: rebuild/pull fresh immutable digests.
|
||||
3. **Application releases**: patch/minor upgrades for internet-facing apps.
|
||||
|
||||
## Freeze and exception policy
|
||||
- No deferral beyond one cycle without documented risk acceptance.
|
||||
- Critical internet-facing CVEs (remote exploitable) cannot wait for the next regular window.
|
||||
|
||||
---
|
||||
|
||||
## 3) Pre-production smoke checks for critical apps
|
||||
|
||||
All updates must be promoted through pre-prod first. Minimum smoke checks:
|
||||
|
||||
### Nextcloud
|
||||
- Login page loads.
|
||||
- Test user login succeeds.
|
||||
- File upload + download round trip succeeds.
|
||||
- Background jobs/cron status healthy.
|
||||
|
||||
### Passbolt
|
||||
- Login page loads.
|
||||
- Browser extension/API auth succeeds.
|
||||
- Secret create/read/update works for test vault.
|
||||
- Email/notification queue healthy.
|
||||
|
||||
### Gitea
|
||||
- Login succeeds.
|
||||
- Repository clone + push with test repo succeeds.
|
||||
- Webhook test delivery succeeds.
|
||||
- Actions/runner (if enabled) executes sample workflow.
|
||||
|
||||
### Grafana
|
||||
- Login succeeds.
|
||||
- Datasource health checks pass.
|
||||
- Key dashboards render without panel errors.
|
||||
- Alert rule evaluation pipeline healthy.
|
||||
|
||||
### Shared gate for all critical apps
|
||||
- HTTPS endpoint returns expected status.
|
||||
- No new high/critical findings in pre-prod vulnerability scan.
|
||||
- Error budget/SLO smoke threshold respected for 30 minutes post-deploy.
|
||||
|
||||
---
|
||||
|
||||
## 4) CVE advisory tracking mapped to deployed versions
|
||||
|
||||
Create/maintain a single register (`cve-register.csv` or ticket board) with these required fields:
|
||||
|
||||
- Product
|
||||
- Deployed version
|
||||
- Deployed image digest
|
||||
- CVE ID
|
||||
- CVSS score/severity
|
||||
- Advisory source URL
|
||||
- Affected version range
|
||||
- Exploit status (known exploited: yes/no)
|
||||
- Mitigation owner
|
||||
- Target fix version
|
||||
- Due date
|
||||
- Status (Open / In-progress / Pending validation / Resolved)
|
||||
|
||||
### Advisory sources (minimum)
|
||||
- Vendor advisories/release notes for each product (Nextcloud, Passbolt, Gitea, Grafana, etc.)
|
||||
- NVD
|
||||
- CISA KEV catalog (for known exploited CVEs)
|
||||
|
||||
### Mapping rule
|
||||
A CVE can only be marked “Not Affected” when the deployed version + digest is proven outside vulnerable ranges with evidence attached.
|
||||
|
||||
---
|
||||
|
||||
## 5) Closure evidence requirement (hard gate)
|
||||
|
||||
A vulnerability ticket is only closed when **both** conditions are met:
|
||||
|
||||
1. **Version or digest changed in production**
|
||||
- Before/after evidence attached (`docker image inspect`, deployment manifest diff, or SBOM diff).
|
||||
2. **Post-update scan is clean for that CVE**
|
||||
- Re-scan target service and attach artifact proving CVE no longer detected.
|
||||
|
||||
### Mandatory closure artifacts
|
||||
- Screenshot/export of runtime version and image digest after deployment.
|
||||
- Linked change request/deployment ID.
|
||||
- Post-update vulnerability scan report.
|
||||
- Smoke-test checklist execution evidence.
|
||||
|
||||
### Status workflow
|
||||
`Open -> Planned -> In Progress -> Pending Validation -> Resolved`
|
||||
|
||||
`Resolved` is prohibited unless both hard-gate conditions above are satisfied.
|
||||
Reference in New Issue
Block a user