Sync docs, audit artifacts, project notes, and VerdictTank proposal docs
- audit/phase-one + phase-two: security audit briefs, findings, credential-rotation plan, Docker-USER hardening scripts, rollback refs - disaster-recovery/restore-test-log.md + backup-dr-audit-2026-08-10.md - clients/ (modelortho SEO audit, ai-biz-dev competitive landscape), notes/ (tiktok strategy) - projects/: front-desk-voice-agent, seo-visibility-checker product plan, hotnow-savannah HTML, resend-transactional-email, backup-dashboard-enhancements, code-review-graph, seo-ci-architecture - proposals/verdicttank/: architecture v4.0, methodology, judge-pool review, consolidation reasoning, cross-check review - docs/super-search/firecrawl-provider-strategy.md - updates: CHANGELOG, model-chain, projects-master-readme, intelsight.io - .gitignore: exclude nested standalone repos (seo-tool, venturebuilt)
This commit is contained in:
@@ -0,0 +1,147 @@
|
||||
import smtplib
|
||||
import ssl
|
||||
import imaplib
|
||||
import importlib.util
|
||||
from email.mime.multipart import MIMEMultipart
|
||||
from email.mime.text import MIMEText
|
||||
from email.mime.application import MIMEApplication
|
||||
from pathlib import Path
|
||||
|
||||
# Signature module (hyphenated filename, load via importlib)
|
||||
spec = importlib.util.spec_from_file_location(
|
||||
"sig", "/root/.hermes/references/shonuff-signature.py"
|
||||
)
|
||||
sig = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(sig)
|
||||
signature_html = sig.build_signature_block()
|
||||
|
||||
# Credentials
|
||||
pw = Path("/root/.config/himalaya/shonuff.pass").read_text().strip()
|
||||
FROM = "Sho'Nuff Brown <shonuff@germainebrown.com>"
|
||||
FROM_ADDR = "shonuff@germainebrown.com"
|
||||
TO = ["g@germainebrown.com"]
|
||||
SUBJECT = "ITPP Phase One Infrastructure Audit - Final Package"
|
||||
|
||||
# ---- Plain text part ----
|
||||
plain = """ITPP Phase One Infrastructure Audit - Final Package
|
||||
|
||||
Phase One read-only audit is complete across all six servers plus the Gitea
|
||||
estate, DNS, and backups. Zero live changes were made.
|
||||
|
||||
What we found (five systemic themes):
|
||||
1. No segmentation - Docker published-port rules bypass UFW, roughly 20
|
||||
management consoles public, no VLAN or Tailscale ACLs.
|
||||
2. Plaintext credentials in world-readable locations across the estate.
|
||||
3. Backups are write-only - 30 of 34 targets backed up, only 2 ever
|
||||
restore-tested; LiteLLM Postgres never backed up.
|
||||
4. SIEM monitors only itself - Wazuh has zero enrolled agents; Grafana
|
||||
default admin/admin public, no MFA.
|
||||
5. Warm standby not data-ready - app1-bu state.db roughly 28 days stale.
|
||||
|
||||
Severity: 23 Critical, 34 High, 36 Medium, 17 Low (consolidated).
|
||||
|
||||
Independent review (Indep, claude-sonnet-5): re-scored every Critical/High.
|
||||
Confirmed D1 (watchdog IP) false positive. Refined D2 (Gitea dropped from the
|
||||
finding, has a passing restore test). Caught two silent downgrades now
|
||||
restored (single SSH key restored to Critical as C10) and one missed finding
|
||||
(WISP tower router zero backup).
|
||||
|
||||
Attached: report.md, policy-and-procedure.md, skill-spec.md, indep-review.md.
|
||||
|
||||
Next step: Phase Two remediation is ordered in Section 4 of the report. The
|
||||
highest-leverage first moves are bind Docker publishes to loopback, rotate
|
||||
plaintext credentials, and enroll Wazuh agents. No action taken in Phase One.
|
||||
|
||||
"""
|
||||
|
||||
# ---- HTML part ----
|
||||
html = """
|
||||
<h2 style="color:#1a1a2e;">ITPP Phase One Infrastructure Audit - Final Package</h2>
|
||||
<hr style="border:none;border-top:2px solid #cc0000;margin:12px 0 20px 0;">
|
||||
|
||||
<p>Phase One read-only audit is complete across all six servers plus the Gitea
|
||||
estate, DNS, and backups. <strong>Zero live changes were made.</strong> The full
|
||||
report, policy and procedure document, and the skill specification are attached.</p>
|
||||
|
||||
<h3 style="color:#1a1a2e;">What we found (five systemic themes)</h3>
|
||||
<ol>
|
||||
<li><strong>No segmentation</strong> - Docker published-port rules bypass UFW,
|
||||
leaving roughly 20 management consoles public, with no VLAN or Tailscale ACLs.</li>
|
||||
<li><strong>Plaintext credentials</strong> in world-readable locations across the estate.</li>
|
||||
<li><strong>Backups are write-only</strong> - 30 of 34 targets backed up, only 2 ever
|
||||
restore-tested; LiteLLM Postgres is never backed up.</li>
|
||||
<li><strong>SIEM monitors only itself</strong> - Wazuh has zero enrolled agents;
|
||||
Grafana runs default admin/admin public with no MFA.</li>
|
||||
<li><strong>Warm standby not data-ready</strong> - app1-bu state.db roughly 28 days stale.</li>
|
||||
</ol>
|
||||
|
||||
<h3 style="color:#1a1a2e;">Severity</h3>
|
||||
<table cellpadding="6" cellspacing="0" style="border-collapse:collapse;font-size:14px;">
|
||||
<tr>
|
||||
<td style="border:1px solid #ddd;background:#fdecea;color:#a30;"><strong>23 Critical</strong></td>
|
||||
<td style="border:1px solid #ddd;background:#fff4e5;color:#a30;"><strong>34 High</strong></td>
|
||||
<td style="border:1px solid #ddd;background:#fffbe6;"><strong>36 Medium</strong></td>
|
||||
<td style="border:1px solid #ddd;"><strong>17 Low</strong></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h3 style="color:#1a1a2e;">Independent review (Indep, claude-sonnet-5)</h3>
|
||||
<p>A second pass re-scored every Critical and High finding against the raw
|
||||
evidence. It confirmed D1 (watchdog IP) as a false positive, refined D2 (Gitea
|
||||
dropped from the finding, it has a passing restore test), and caught two silent
|
||||
severity downgrades now corrected, plus one missed finding (WISP tower router
|
||||
with zero backup). Full detail is in the report, Section 8.</p>
|
||||
|
||||
<h3 style="color:#1a1a2e;">Attached</h3>
|
||||
<ul>
|
||||
<li><strong>report.md</strong> - Final Report (severity matrix, recommendations, disagreements log)</li>
|
||||
<li><strong>policy-and-procedure.md</strong> - v1.0 policy and procedure document</li>
|
||||
<li><strong>skill-spec.md</strong> - itpp-policy-adherence skill specification</li>
|
||||
<li><strong>indep-review.md</strong> - independent severity review</li>
|
||||
</ul>
|
||||
|
||||
<h3 style="color:#1a1a2e;">Next step</h3>
|
||||
<p>Phase Two remediation is ordered in Section 4 of the report. The
|
||||
highest-leverage first moves are to bind Docker publishes to loopback, rotate
|
||||
plaintext credentials, and enroll Wazuh agents. No action was taken in Phase One
|
||||
per the read-only mandate.</p>
|
||||
|
||||
"""
|
||||
|
||||
# ---- Assemble MIME ----
|
||||
msg = MIMEMultipart("mixed")
|
||||
msg["From"] = FROM
|
||||
msg["To"] = ", ".join(TO)
|
||||
msg["Subject"] = SUBJECT
|
||||
|
||||
alt = MIMEMultipart("alternative")
|
||||
alt.attach(MIMEText(plain, "plain", "utf-8"))
|
||||
alt.attach(MIMEText(html + signature_html, "html", "utf-8"))
|
||||
msg.attach(alt)
|
||||
|
||||
base = Path("/root/projects/itpp-infrastructure/audit/phase-one")
|
||||
attachments = [
|
||||
(base / "report.md", "report.md"),
|
||||
(base / "policy-and-procedure.md", "policy-and-procedure.md"),
|
||||
(base / "skill-spec.md", "skill-spec.md"),
|
||||
(base / "findings" / "indep-review.md", "indep-review.md"),
|
||||
]
|
||||
for path, filename in attachments:
|
||||
part = MIMEApplication(path.read_bytes(), _subtype="markdown")
|
||||
part.add_header("Content-Disposition", "attachment", filename=filename)
|
||||
msg.attach(part)
|
||||
|
||||
# ---- Send ----
|
||||
ctx = ssl.create_default_context()
|
||||
with smtplib.SMTP("mail.germainebrown.com", 2525, timeout=30) as s:
|
||||
s.starttls(context=ctx)
|
||||
s.login(FROM_ADDR, pw)
|
||||
s.send_message(msg, from_addr=FROM_ADDR, to_addrs=TO)
|
||||
print("SMTP send OK")
|
||||
|
||||
# ---- IMAP APPEND to Sent ----
|
||||
imap = imaplib.IMAP4_SSL("mail.germainebrown.com", 993, ssl_context=ctx)
|
||||
imap.login(FROM_ADDR, pw)
|
||||
typ, data = imap.append("Sent", None, None, msg.as_bytes())
|
||||
imap.logout()
|
||||
print(f"IMAP append: {typ} {data}")
|
||||
Reference in New Issue
Block a user