diff --git a/.githooks/pre-commit b/.githooks/pre-commit new file mode 100755 index 0000000..cd7efb7 --- /dev/null +++ b/.githooks/pre-commit @@ -0,0 +1,85 @@ +#!/bin/bash +# Pre-commit secret scanner for itpp-infrastructure +# Scans staged changes for credential patterns before allowing commit. +# Blocks commits containing API keys, tokens, or passwords. + +set -euo pipefail + +RED='\033[0;31m' +NC='\033[0m' + +# Patterns that indicate secrets +PATTERNS=( + # API key formats + 'sk-[a-zA-Z0-9]{32,}' + 'sk-litellm-[a-zA-Z0-9]{32,}' + 'Bearer [a-zA-Z0-9_-]{20,}' + 'x-api-key: [a-zA-Z0-9]{20,}' + 'api_key.*=.*[a-zA-Z0-9_-]{20,}' + 'api-key: [a-zA-Z0-9_-]{20,}' + # SyncroMSP token patterns + 'T[0-9a-f]{8}[a-zA-Z0-9_-]{24,}' + # Generic secret patterns + 'passwor[d][[:space:]]*=[[:space:]]*[^[:space:]]{8,}' + 'secret[[:space:]]*=[[:space:]]*[^[:space:]]{16,}' + 'token[[:space:]]*=[[:space:]]*[^[:space:]]{16,}' + # AWS key patterns + 'AKIA[0-9A-Z]{16}' + 'aws_access_key_id[[:space:]]*=[[:space:]]*[A-Z0-9]{16,}' + # Private key patterns + '-----BEGIN (RSA|OPENSSH|EC) PRIVATE KEY-----' + # JWT/stripe patterns + 'eyJ[a-zA-Z0-9_-]{20,}\.[a-zA-Z0-9_-]{20,}' + 'sk_live_[0-9a-zA-Z]{24,}' + 'pk_live_[0-9a-zA-Z]{24,}' +) + +# Files to skip +SKIP_GLOB="*.lock|*.png|*.jpg|*.gif|*.svg|*.ico|*.woff*|*.ttf|*.eot|*.min.js|*.min.css|*.map|package-lock.json|yarn.lock|pnpm-lock.yaml|go.sum|Cargo.lock|*.pb.go|*.gen.go|*.generated.*|.gitignore" + +FOUND_SECRET=0 +CHANGED_FILES=$(git diff --cached --name-only --diff-filter=ACM) + +if [ -z "$CHANGED_FILES" ]; then + exit 0 +fi + +# Create temp file with staged content +STAGED_DIR=$(mktemp -d) +trap "rm -rf $STAGED_DIR" EXIT + +for file in $CHANGED_FILES; do + # Skip binary/lock files + if echo "$file" | grep -qE "$SKIP_GLOB"; then + continue + fi + + # Get staged content + mkdir -p "$(dirname "$STAGED_DIR/$file")" + git show ":$file" > "$STAGED_DIR/$file" 2>/dev/null || continue + + for pattern in "${PATTERNS[@]}"; do + if grep -qE "$pattern" "$STAGED_DIR/$file" 2>/dev/null; then + if [ $FOUND_SECRET -eq 0 ]; then + echo "" + echo -e "${RED}╔══════════════════════════════════════════════╗${NC}" + echo -e "${RED}║ SECRET DETECTED — COMMIT BLOCKED ║${NC}" + echo -e "${RED}╚══════════════════════════════════════════════╝${NC}" + echo "" + fi + FOUND_SECRET=1 + echo -e "${RED}[BLOCKED]${NC} $file — matches pattern: $pattern" + echo " → $(grep -nE "$pattern" "$STAGED_DIR/$file" | head -1 | cut -c1-120)" + fi + done +done + +if [ $FOUND_SECRET -eq 1 ]; then + echo "" + echo -e "${RED}Commit aborted. Remove the secrets above and try again.${NC}" + echo "If this is a false positive, add the file to SKIP_GLOB in .git/hooks/pre-commit" + echo "or use: git commit --no-verify" + exit 1 +fi + +exit 0 diff --git a/docs/architecture.md b/docs/architecture.md new file mode 100644 index 0000000..5b3817b --- /dev/null +++ b/docs/architecture.md @@ -0,0 +1,130 @@ +# IT Pro Partner — Live Architecture Reference + +**Last Updated:** 2026-08-09 +**Maintainer:** Sho'Nuff (Hermes Agent) +**Purpose:** Single source of truth for ITPP server infrastructure. Replaces the archived `master-apps-services.md` (Jul 16, 2026) which listed 10+ defunct servers and stale specs. + +--- + +## Servers + +| Server | IP | Specs | Provider | Role | +|---|---|---|---|---| +| **Core** | 152.53.192.33 | RS 2000 G9.5 (8 vCPU EPYC 9645, 15 GB RAM, 256 GB SSD) | netcup | Hermes agent host, monitoring, Caddy reverse proxy (26 sites) | +| **app1** | 152.53.36.131 | RS 4000 G9.5 (8 vCPU EPYC, 16 GB RAM, 512 GB SSD) | netcup | Service hub — AI gateway, CRM, signing, TTS, auth, automation | +| **app2** | 152.53.39.202 | RS 4000 G9.5 (8 vCPU EPYC, 16 GB RAM, 512 GB SSD) | netcup | Infrastructure — Gitea, Hudu, Ubiquiti controllers, Traccar, DNS, SIEM | +| **app3** | 152.53.241.111 | RS 4000 G9.5 (8 vCPU EPYC, 16 GB RAM, 512 GB SSD) | netcup | Web hosting — CloudPanel CE (WordPress/static/PHP), client sites | +| **app1-bu** | 5.161.225.131 | CPX21 (3 vCPU, 4 GB RAM, 80 GB) | Hetzner | Warm standby — provider diversity. Auto-restores from S3. | + +--- + +## Services by Server + +### Core (152.53.192.33) + +| Service | Port | Type | Docs | +|---|---|---|---| +| Hermes Agent | — | Systemd | See `hermes-agent` skill | +| Caddy | 80, 443 | Systemd | `/etc/caddy/Caddyfile` | +| Prometheus | 9090 (internal) | Docker | — | +| Grafana | :3002 | Docker | Credential in Vaultwarden | +| Uptime Kuma | :3001 | Docker | — | +| Telegraf | — | Docker | — | +| MikroTik Exporter | :9436 | Docker | — | +| Microbin | — | Docker | — | +| Browserless | — | Docker | — | +| Camofox Browser | :9377 | Docker | — | +| Mealie | 9925 (internal) | Docker | — | + +### App1 (152.53.36.131) + +| Service | Port | Type | Docs | +|---|---|---|---| +| **LiteLLM** | :4000 | Docker | In progress — `org-audit/docs/services/litellm-deployment.md` | +| **Twenty CRM** | 3000 | Docker (4 containers: server, worker, db, redis) | In progress — `org-audit/docs/services/twenty-crm-deployment.md` | +| DocuSeal | — | Docker | — | +| Kokoro TTS | :8880 | Docker | — | +| n8n | — | Docker | — | +| Open WebUI | — | Docker | — | +| **Vaultwarden** | :8081 | Docker | In progress — `org-audit/docs/services/vaultwarden-deployment.md` | +| **Wazuh** | :5601 | Docker (3 containers: dashboard, indexer, manager) | In progress — `org-audit/docs/services/wazuh-deployment.md` | +| Komodo | :9120 | Docker | — | + +### App2 (152.53.39.202) + +| Service | Port | Type | Docs | +|---|---|---|---| +| **Gitea** | :3001 | Docker | In progress — `org-audit/docs/services/gitea-deployment.md` | +| Hudu | :3000 | Docker | — | +| UNMS (UISP) | :6443 | Docker | — | +| UniFi | :8443 | Docker | — | +| Traccar | :8082 | Docker | Verified operational 2026-08-09 | +| **Technitium DNS** | :5380 | Docker | In progress — `org-audit/docs/services/technitium-dns-deployment.md` | +| RAGFlow | — | Docker | — | +| Dawarich | :3002 | Docker | — | +| searxng | 9925 (internal) | Docker | — | + +### App3 (152.53.241.111) + +| Service | Port | Type | Docs | +|---|---|---|---| +| CloudPanel CE | — | Systemd (nginx + PHP-FPM) | — | +| WordPress sites | 80, 443 | nginx | Per-site in CloudPanel | +| Static HTML sites | 80, 443 | nginx | Per-site in CloudPanel | + +--- + +## DNS & Domains + +| Domain | Registrar | DNS Provider | Notes | +|---|---|---|---| +| itpropartner.com | Cloudflare | SiteGround (external) | Cloudflare zone has no authority — records must be set at SiteGround | +| iamgmb.com | Cloudflare | Cloudflare | Grey-cloud only (no proxy). Zone: `f1fb2d357b8ff0fab54c5856130ec9ed` | +| germainebrown.com | Cloudflare | Cloudflare | Personal domain | +| fleettracker360.com | Cloudflare | Cloudflare | Zone: `d1830faef5a6d83365360fa925feeb13`. Orange-cloud proxy → app2 | +| debt... (DRE) | Cloudflare | Cloudflare | Access-protected | +| hotnow.io | Cloudflare | Cloudflare | Registered Aug 2026. No deployment yet. | + +--- + +## Backup Schedule + +| Source | Target | Frequency | Script | +|---|---|---|---| +| Core Hermes (live sync) | s3://hermes-vps-backups/live/ | Every 15 min | `hermes-live-sync` | +| Core Hermes (full) | s3://hermes-vps-backups/hermes-full-backup/ | Daily 1:00 AM | `hermes-backup.sh` | +| App1 | S3 | Daily 2:00 AM | Cron on app1 | +| App2 | S3 | Daily 2:30 AM | Cron on app2 | +| App3 | S3 | Daily 3:00 AM | Cron on app3 | + +**S3 target:** Wasabi `s3.us-east-1.wasabisys.com`, bucket `hermes-vps-backups`. + +--- + +## Key Repositories + +| Repo | Gitea URL | Purpose | +|---|---|---| +| itpp-infrastructure | ippadmin/itpp-infrastructure | Infrastructure docs and scripts | +| disaster-recovery | ippadmin/disaster-recovery | DR plans, runbooks, issue log | +| hermes-skills | ippadmin/hermes-skills | Hermes Agent skills (⚠️ plaintext secrets — see security note) | +| hermes-recovery | ippadmin/hermes-recovery | Hermes recovery bundles (⚠️ plaintext secrets — see security note) | +| org-audit | ippadmin/org-audit | External audit exports and deployment docs | +| homelab | ippadmin/homelab | Home lab documentation | + +--- + +## Security Notes + +1. **`hermes-recovery` and `hermes-skills` contain plaintext API keys in Git history** — CRITICAL. Requires key rotation + history purge. The actual API keys must be rotated before purging since clones may exist. +2. **Vaultwarden** is the sole credential store — deployment docs are in progress. +3. **LiteLLM** routes all AI model traffic — deployment docs are in progress. +4. **Wazuh** is the security monitoring infrastructure — deployment docs are in progress. +5. **Technitium DNS** is authoritative for internal zones — no zone file backup procedure documented yet. + +--- + +## Changelog + +- **2026-08-09:** Created as replacement for archived `master-apps-services.md`. Corrected server specs, removed defunct servers, added documentation cross-references. +- **2026-07-28:** Original `master-apps-services.md` archived (stale — listed Mattermost, wphost01, standalone hudu, incorrect specs).