07 — Hetzner + DNS/Cloudflare Audit
Scope: Hetzner-Hosting (heute: av-tools Project mit 1 Server), Hetzner-Object-Storage-Vorbereitung (noch nichts angelegt), DNS/Cloudflare-Surface fuer agenticventures.de und marvinkuehlmann.com. NDA-Relevanz markiert (Becker-NDA 10y).
Quelle: mcp__hetzner__* Tools (Servers, Firewalls, Volumes, SSH-Keys) live abgefragt 2026-05-15, plus passive DNS-Lookups (dig). Kein aktives Port-Probing.
Ampel-Uebersicht
| Check | Ampel | Kurz-Befund |
|---|---|---|
| 1. Hetzner Servers (Exposure, Backup) | gelb | Public-IP exposed (by design), Backup NULL, kein Cloud-DDoS-Schutz dokumentiert |
| 2. Firewalls (Regeln, Coverage) | gelb | SSH von 0.0.0.0/0 offen (key-only, aber kein Geofence/Tailscale), nur 1 Firewall an 1 Server |
| 3. SSH-Keys | gruen | 1 Key, ed25519, klar zugeordnet, Labels sauber |
| 4. Volumes | gruen | 0 dangling, 0 angelegt (LUKS-Frage NA bis erstes Volume) |
| 5. Hetzner Object Storage | gruen-info | Doku-Mode, noch nichts angelegt — Gating + Werte-Double-Check sauber gespect |
| 6. Cloudflare Tunnels / TLS-Mode / Zero-Trust | rot-blind | API nicht zugaenglich, mehrere kritische Settings unverifiziert |
| 7. DNS (DNSSEC, CAA) | rot | DNSSEC DEAKTIVIERT auf beiden Domains, keine CAA-Records |
| 8. NDA-Compliance / Subdomain-Leak | gruen | Kein Kunden-Name in oeffentlich resolvebaren Records (Becker-NDA OK) |
1. Hetzner Servers
Bestand (Live-MCP-Read 2026-05-15):
| Server | ID | Typ | Location | IPv4 | IPv6 | Backup | Created |
|---|---|---|---|---|---|---|---|
av-tools-stirling-01 | 131113789 | cx23 | nbg1-dc3 | 46.225.16.231 | 2a01:4f8:1c18:5e7f::/64 | null (deaktiviert) | 2026-05-15 |
Findings:
- F-07-01 (gelb):
backup_window: null— Hetzner-Snapshot-Backup nicht aktiviert. Beicx23kostet das 20 % Aufschlag (~1 €/Monat) und gibt 7 Slot-Snapshots automatisch. Begruendung warum gelb statt rot: Stirling-PDF hat keine Nutzdaten die nicht reproduzierbar sind — Bootstrap-Skripte liegen lokal/im Vault, Stack ist Compose + Docker-Volumes mit ephemeren Files. Aber: Compose-File +/opt/stirling/{data,config}sind heute NICHT im Vault gespiegelt → Reset = Userlist + interner Login + custom-files futsch. Empfehlung: Backup an, oder mindestens nightlytar | rclonevon/opt/stirling/{data,config,custom-files,extra-configs}in einen Hetzner-Bucket (sobaldav-tools-bucketexistiert). - F-07-02 (gruen):
rescue_enabled: false,protection.delete: false,protection.rebuild: false— alles erwartbar. Aber:protection.delete=truefuer alle Prod-Server (auch av-tools) waere ein billiger Anti-Fat-Finger-Schutz. Empfehlung: setzen, sobald Server-Inventar > 1. - F-07-03 (info): Server hat reverse-DNS auf
static.231.16.225.46.clients.your-server.de.(Hetzner-Default). Kein Reverse-DNS-Leak zu agenticventures.de, was OK ist — Verbindung Server ↔ Marken-Domain ist nur via Cloudflare-Tunnel-CNAME einseitig sichtbar. - F-07-04 (gelb): Outgoing-Traffic 7,86 MB seit Server-Start (heute), Ingoing 1,13 GB — Verhaeltnis plausibel fuer reines Tunnel-Setup. Aber: kein Egress-Monitoring/Cap dokumentiert, kein Alarm bei „Server schreit auf einmal ins Internet” (Indikator fuer Crypto-Mining-Compromise). Empfehlung: Better-Stack-Heartbeat oder Hetzner-internes Traffic-Alert konfigurieren bevor Server-Inventar waechst.
2. Firewalls
Bestand:
| Firewall | ID | Rules | Attached To |
|---|---|---|---|
av-tools-stirling | 10976973 | SSH/22 + ICMP (beide from 0.0.0.0/0, ::/0) | av-tools-stirling-01 |
Findings:
- F-07-05 (gelb): SSH von Welt offen (
0.0.0.0/0+::/0). Begruendung in av-tools: „key-only auth, kein password”. Stimmt — SSH key-only + fail2ban + unattended-upgrades sind in Bootstrap dokumentiert. Trotzdem ist die Surface unnoetig gross. Empfehlung Stufe 1 (5 min): SSH-Rule auf eigene aktuelle IP einschraenken (hcloud firewall add-rule ... --source-ips $(curl -s ifconfig.me)/32), zweite Rule fuer Hetzner-Recovery oder Tailscale-Adressraum, statt /0. Empfehlung Stufe 2 (richtiger Weg): Tailscale auf den Server, SSH-Rule entfernen, SSH nur ueber Tailscale-IP. Default fuer alle zukuenftigen Industriekunden-Server. - F-07-06 (gelb): Kein expliziter Deny-All-Egress — Hetzner-Firewall ist „default deny inbound, default allow outbound”. Bei einem PDF-Tool nicht kritisch, aber bei Industriekunden-Stack (PII-Daten, LLM-Calls) sollte Egress auf Allowlist (Mistral-API, S3-Endpoint, Cloudflare-Edge, Apt-Mirror) — sonst koennen Compromise-Payloads frei nach C2 telefonieren. Pattern fuer Hetzner-MVP-Industriekunde dokumentieren in _index.
- F-07-07 (gruen): Firewall ist tatsaechlich attached (
applied_to.[0].server.id == 131113789). Kein „Firewall existiert, aber wirkt auf nichts”-Antipattern. - F-07-08 (gruen): Labels sauber (
owner=marvin,purpose=av-tools,service=stirling-pdf) — Inventar-Disziplin gemaess naming-konvention eingehalten.
3. SSH-Keys
Bestand:
| Name | ID | Type | Fingerprint | Owner |
|---|---|---|---|---|
marvin-av-tools | 112321437 | ed25519 | ab:95:0c:fc:09:40:df:57:d5:3f:da:39:30:c6:f6:0b | marvin (label) |
Findings:
- F-07-09 (gruen): Nur 1 Key, ed25519 (modern), klar gelabeled. Comment
marvin@av-tools-stirling— purpose-bound (separat von ggf. anderem Personal-Key), gut. - F-07-10 (info): Lokaler Pfad laut Doku
~/.ssh/hetzner_av_tools. Ich kann den lokalen Pfad/Permissions hier nicht pruefen (kein Filesystem-Lookup im Scope). Empfehlung Marvin:ls -la ~/.ssh/hetzner_av_tools*→ muss600private,644public sein, beide owned by user. Plus: in 1Password als Backup hinterlegt? Wenn nein → tun, sonst Hetzner-Console-Reset noetig wenn lokaler Mac stirbt. - F-07-11 (info): Rotation-Plan: Doku in api-token-konvention beschreibt API-Token-Rotation alle 6 Monate, aber NICHT SSH-Key-Rotation. Bei „Mitarbeiter raus oder Mac kompromittiert” muss klar sein: neuen Key in Hetzner zufuegen, alten loeschen,
~/.ssh/authorized_keysauf Server kontrolliert ersetzen. Empfehlung: 1 Satz inav-tools.mdRunbook ergaenzen.
4. Volumes
- F-07-12 (gruen): 0 Volumes — keine dangling, kein Cost-Drift. Sobald erstes Volume angelegt wird (Industriekunde, Postgres-Data): Encryption-Frage stellt sich. Hetzner Cloud Volumes sind im Klartext (kein at-rest-Encryption ab Werk im Free-Tier). Standard: LUKS auf dem Server mit Key via systemd-creds oder Mistral-KMS-Aequivalent. In cloud-volume-block-storage heute NICHT dokumentiert — Action: Volume-Encryption-Pattern (LUKS-Setup) als „Pflicht-Schritt vor erstem Industriekunden-Volume” ergaenzen.
5. Hetzner Object Storage
Status: noch kein Bucket angelegt — Doku in storage beschreibt geplanten Aufbau (<kunde>-data, <kunde>-audit, <kunde>-test-objectlock).
Findings (Doku-Review):
- F-07-13 (gruen): Object-Lock-Werte-Double-Check (2555 Tage = 7y, NICHT 25550) ist explizit in
storage.mdmarkiert — Disziplin gut. - F-07-14 (gruen): Public-Access-blocked + Versioning-enabled als Default in der Bucket-Anlage-Checkliste. Pattern stimmt.
- F-07-15 (gelb): age-encrypted Backups (
<kunde>-audit/llm/...jsonl.gz.age) ist im Doku-Pattern erwaehnt — aber Key-Management fuer age-Keys nicht definiert. Wo liegt der Identity-Key? 1Password? Auf dem Server? Quorum-Restore moeglich? Bei Becker-NDA-Relevanz (Audit-Log enthaelt potentiell Becker-PII) ist Verlust-des-age-Keys = unlesbare 7-Jahre-Audit-Logs = HGB-Verletzung. Action: ADR fuer age-Key-Management vor erstem Bucket-Anlegen. - F-07-16 (info): MFA-only Read-Key fuer audit-Bucket (
<kunde>-audit-read-mfa) ist in Doku spec’d — Hetzner-S3-Credentials unterstuetzen aber keine MFA-Erzwingung auf API-Token-Ebene wie AWS-S3. Workaround: separater Hetzner-User mit MFA-required Console-Login, der die Keys generiert + verwaltet, plus orga-prozessual „Marvin tippt Key nur ein nach 1Password-MFA-Unlock”. Das ist eine schwaechere Garantie als AWS — sollte explizit in Compliance-Argumentation Richtung Industriekunden so kommuniziert sein. - F-07-17 (info): Cross-Region/Off-Site-Backup-Plan: rclone manuell (siehe Doku). Bei Becker (NDA-Daten 10y) sollte Off-Site-Strategie vor Go-Live stehen, nicht reaktiv. Action: rclone-Cron-Pattern + Ziel-Bucket (AWS S3 in
av-production?) als ADR vor Industriekunden-Onboarding.
6. Cloudflare Tunnels / TLS / Zero Trust
Was ich pruefen konnte: Live-DNS-Resolution. Alle MCP-Subdomains (mcp-whatsapp, mcp-vf, pdf) zeigen auf Cloudflare-Anycast-IPs (172.67.220.246, 104.21.78.120) — Cloudflare-Edge ist also live davorgeschaltet.
Was ich NICHT pruefen kann ohne Cloudflare-API/MCP:
- TLS-Mode (Full Strict vs Full vs Flexible) pro Zone
- Always-Use-HTTPS (Redirect 80→443)
- HSTS-Settings (max-age, includeSubdomains, preload)
- Min-TLS-Version (sollte 1.2+, idealerweise 1.3)
- Tunnel-Konfiguration pro Tunnel (Tunnel-IDs aus Doku:
6537ca14-...av-tools,ce6dd7c0-...mcp-vf,a3af8b46-...mcp-whatsapp) - Cloudflare-Access-Policies (existiert eine fuer
pdf.agenticventures.de? Doku sagt: noch nicht angelegt → F-07-19) - WAF-Rules / Bot-Fight-Mode / Rate-Limiting pro Hostname
- mTLS oder Service-Token zwischen Edge und Origin (Tunnel hat per-default kein mTLS Edge↔Tunnel-Cert)
Findings (was sicher gesagt werden kann):
- F-07-18 (rot-blind): Verifikations-Luecke. Action fuer Marvin: in Cloudflare Dashboard pro Zone (
agenticventures.de+marvinkuehlmann.com) folgende Settings screenshotten + inintern/capabilities/hetzner/cloudflare.md(neu, gibt es noch nicht) festhalten: SSL/TLS-Mode, Edge-Cert-Status, HSTS, Min-TLS-Version, Always-Use-HTTPS, Auto-HTTPS-Rewrites, Opportunistic-Encryption. Mindest-Soll: Full Strict + HSTS 1y + includeSubdomains + Min-TLS 1.2. - F-07-19 (gelb, dokumentiert):
pdf.agenticventures.dehat lautav-tools.mdnoch keine Access-Application angelegt — einzige Auth ist Stirling-interne Loginschicht mit Default-Useradmin/stirling-pdf. Wenn der Default-User nicht beim ersten Login geaendert wurde, ist Stirling effektiv offen sobald jemand die URL kennt. Action sofort: Cloudflare-Access-App anlegen mit Email-OTP-Allowlist, dann erst Default-Pwd-Reset im Stirling-Container verifizieren. Sequence wichtig — sonst Window wo Pwd-Wechsel-Flow ohne Access-Layer haengt. - F-07-20 (info): mcp-vf + mcp-whatsapp laufen ueber AWS-Fargate-Tunnel-Sidecar (laut
/Users/marvinkuehlmann/source/agentic-ventures/intern/capabilities/mcps/_index.md), nicht Hetzner — sind also nur DNS-seitig im Scope dieses Audit-Teils, Compute-Audit gehoert in AWS-Teil. - F-07-21 (gelb): Tunnel-Token-Rotation-Plan fehlt.
av-tools.mdbeschreibt wie rotiert wird (install-tunnel.sh <new-token>), aber kein Trigger / Interval / Owner. Empfehlung: gleicher 6-Monats-Rhythmus wie API-Tokens, plus sofort bei Compromise-Signal.
7. DNS — DNSSEC + CAA
Lookups (passive, dig 2026-05-15):
| Domain | NS | DNSKEY | DS | CAA |
|---|---|---|---|---|
agenticventures.de | lynn.ns.cloudflare.com, selah.ns.cloudflare.com | leer | leer | leer |
marvinkuehlmann.com | 4× *.awsdns-* (Route 53) | leer | leer | leer |
Findings:
- F-07-22 (rot): DNSSEC ist auf beiden Domains nicht aktiv. Kein DNSKEY-Record, kein DS-Record bei der Registry. Konsequenz: Spoofing-Angriffe gegen
mcp-*.agenticventures.de(z.B. cache-poisoning gegen Kunden-Resolver) nicht erkennbar. Bei Industriekunden-Sales-Story „DSGVO-streng, EU-only, Becker-grade” ist fehlendes DNSSEC eine Compliance-Inkonsistenz — Sales-Material verspricht „voller Edge-Schutz”, DNS-Layer ist aber nackt. Action:agenticventures.de(Cloudflare-Authority): Cloudflare Dashboard → DNS → Settings → DNSSEC → Enable. Plus: DS-Record bei Strato (Registrar) einreichen. ~5 min Aufwand, kostenlos.marvinkuehlmann.com(Route 53): Route 53 Hosted Zone → Sign Zone, KSK in KMS erzeugen lassen, DS bei Registrar einreichen.
- F-07-23 (rot): CAA-Records fehlen auf beiden Domains. Heisst: jede CA der Welt darf ein Zertifikat fuer
*.agenticventures.deausstellen. Mit Cloudflare-Edge laeuft TLS-Termination zwar bei CF (Let’s Encrypt / Google Trust Services / Cloudflare-Cert), aber ohne CAA kann ein boeswilliger Akteur via Domain-Hijack oder DNS-Hijack ein eigenes Cert anfordern. Action: CAA-Records setzen die nur die Cloudflare-CAs erlauben:
Analog fueragenticventures.de. CAA 0 issue "letsencrypt.org" agenticventures.de. CAA 0 issue "pki.goog" agenticventures.de. CAA 0 issuewild "letsencrypt.org" agenticventures.de. CAA 0 iodef "mailto:hello@marvinkuehlmann.com"marvinkuehlmann.com(ggf. mit Amazon-Trust-Services wenn AWS-ACM Certs irgendwo gezogen werden). ~10 min Aufwand, kostenlos. Vor Anlage Cloudflare-Doku checken welche CAs CF aktuell nutzt — andernfalls reisst man sich die eigene Cert-Renewal-Pipeline auf. - F-07-24 (info):
agenticventures.de(Cloudflare-NS) undmarvinkuehlmann.com(Route-53-NS) — zwei verschiedene Authority-Provider. OK, dokumentiert infirma/web-properties.md. Risiko-Aspekt: Lock-In-Diversifizierung gut, aber „wo liegt was DNS-technisch” muss klar bleiben — siehe Action F-07-22 (zwei separate DNSSEC-Aktivierungen).
8. NDA-Compliance / Subdomain-Leak
- F-07-25 (gruen): Live-Subdomains die ich resolved habe:
agenticventures.de,www.agenticventures.de,mcp-whatsapp.agenticventures.de,mcp-vf.agenticventures.de,pdf.agenticventures.de. Kein Kunden-Name leakt (keinbecker.agenticventures.de, kein*-bss.*o.ae.). Patternmcp-<kunde>.agenticventures.deaus web-properties ist eine Sales-Risikoquelle wenn ein Kunde tatsaechlich namentlich als Subdomain erscheint. Vor jedem neuenmcp-<kunde>.*-DNS-Eintrag pruefen: ist das ein NDA-Kunde? Wenn ja: pseudonymer Slug (z.B.mcp-c1.agenticventures.de, internc1 = becker) — gilt insbesondere fuer Becker (NDA-Frist 10y, CLAUDE.md Regel 22). - F-07-26 (gruen): Hetzner-Server-Hostnames im RDNS sind Hetzner-Default (
static.231.16.225.46.clients.your-server.de) — kein Selbst-Set-Hostname leakt Kunden-Daten. Bei Industriekunden-Servern dieselbe Disziplin halten: PTR-Records nur auf neutrale Slugs (av-c1-web.exampleo.ae.), nicht auf Kundennamen.
Top 3 — was als naechstes
- DNSSEC + CAA auf beiden Domains aktivieren (F-07-22 + F-07-23). Rot, ~15 min Aufwand, kostenlos, schliesst zwei harte Compliance-Luecken die bei jedem Industriekunden-Pre-Sales-Audit aufschlagen wuerden.
pdf.agenticventures.deCloudflare-Access-App live nehmen (F-07-19) — heute ist die Stirling-Instanz nur durch interne Login-Schicht mit Default-Pwd geschuetzt (laut Doku noch nicht geaendert beim ersten Login dokumentiert). Plus: SSH-Firewall-Rule von0.0.0.0/0auf Marvin-IP-only oder Tailscale (F-07-05). Beides am gleichen Server, eine Session.- Cloudflare-Settings dokumentieren + Hetzner-Volume-Encryption-Pattern spec’en (F-07-18 + F-07-12). Ohne diese beiden Doku-Stuecke ist die Hetzner-Spur fuer den naechsten Industriekunden NICHT go-live-fertig — Cloudflare-Mode + age-Key-Management + LUKS-Pattern muessen vor erstem Project-Anlage als ADRs stehen, sonst wird das erste Setup zur Vorlage fuer kompromittierte Defaults.
Was Marvin manuell nachreichen muss (Cloudflare-API nicht im Scope)
Cloudflare-MCP/API ist heute nicht in Marvins MCP-Inventar (intern/capabilities/mcps/_index.md). Folgende Werte bitte per Browser-Screenshot aus Cloudflare Dashboard ziehen und in eine neue Datei intern/capabilities/hetzner/cloudflare.md (oder besser: intern/capabilities/cloudflare/_index.md — Cloudflare ist nicht Hetzner-spezifisch) ablegen:
- Pro Zone (
agenticventures.de,marvinkuehlmann.com):- SSL/TLS encryption mode (soll: Full Strict)
- Edge-Cert: Universal SSL aktiv? Min TLS Version? TLS 1.3 enabled?
- HSTS: max-age + includeSubdomains + preload + no-sniff
- Always Use HTTPS: on
- Automatic HTTPS Rewrites: on
- DNSSEC: on/off + DS-Record bei Registrar eingereicht?
- Pro Tunnel (av-tools, mcp-vf, mcp-whatsapp):
- Tunnel-Status (healthy/degraded)
- Public-Hostname-Rules (welcher Hostname → welcher Origin-Port)
- Access-Application existiert? Mit welcher Policy (Email-OTP, IP-Allowlist, Service-Token)?
- Session-Duration der Access-App
- Zero Trust / Access Audit Log: pruefen ob Logs aktiviert + wohin gespeichert (SIEM-Forward?)
- WAF: Managed-Rules-Set aktiv? Bot-Fight-Mode? Rate-Limiting-Rules pro
mcp-*-Subdomain?
Sobald die Datei da ist: Folge-Audit mit Browser-MCP (Claude in Chrome) gegen Cloudflare-Dashboard moeglich.