Files
root f5175f1ce0 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)
2026-08-26 02:27:28 -04:00

23 KiB

NetEng-A - Network Exposure Inventory (Phase One, Read-Only)

Auditor: NetEng-A (network enumeration) Date: 2026-08-13 Scope: Firewalls, open/listening ports, public DNS, VPN/private paths, and reverse-proxy/ingress surface across the ITPP estate. Method: Read-only discovery only (ss -tulpn, ip, ufw status, iptables -L/-t nat, dig, docker ps, docker inspect, cat of config files). No configuration was modified on any host.

Severity legend: Critical = publicly reachable management/security console or control-plane with broad impact. High = significant unintended public exposure or broken DNS control. Medium = defense-in-depth gap or weak configuration. Low = hygiene/minor.


1. Executive summary

  • Hosts reachable: 6 of 6 servers in scope (Core, app1, app2, app3, app1-bu, wphost02) - all accepted the itpp-infra SSH key.
  • Total open listening sockets (bound to non-loopback/public addresses): ~390 across the estate. app2 alone accounts for ~330 of them (Traccar's 5000-5150 device range published on both TCP and UDP = 302 sockets).
  • Single most important finding: Docker published-port rules bypass UFW on Core, app1, app2, and app3. Security and management consoles (Wazuh, UniFi, UNMS, Grafana, CloudPanel) are reachable from the public internet even though UFW's allow-lists do not include their ports.
  • DNS hygiene is poor: the itpropartner.com apex A record and ~10 legacy subdomains still resolve to a decommissioned GCP host (35.212.86.161), and the SPF record is malformed (two concatenated v=spf1 strings with a truncated IP).

2. Cross-cutting finding: Docker port publishing bypasses UFW (Critical)

Evidence (app1, identical mechanism on Core/app2/app3):

# iptables -t nat -L DOCKER -n
DNAT tcp 0.0.0.0/0 0.0.0.0/0 tcp dpt:5601 to:172.26.0.4:5601
DNAT tcp 0.0.0.0/0 0.0.0.0/0 tcp dpt:9200 to:172.26.0.2:9200
# iptables -L DOCKER -n
ACCEPT tcp 0.0.0.0/0 172.26.0.4 tcp dpt:5601
ACCEPT tcp 0.0.0.0/0 172.26.0.2 tcp dpt:9200

UFW's ALLOW list on app1 contains only 22, 80, 443, 1514, 1515 (and 3006 from Core). Yet 5601, 9200, 55000, 514/udp, 3003, 9120 are all published by Docker as 0.0.0.0:<port>. Docker inserts DNAT rules into nat/PREROUTING and ACCEPT rules into the filter/FORWARD DOCKER chain, which are processed before UFW's filter/INPUT chain. UFW's default-deny therefore never sees these packets.

Why it matters: every operator on these boxes believes UFW is the security boundary, but any docker run -p <port> silently punches a public hole. On app2, ~20 services (UniFi controller, UNMS/UISP, Gitea SSH, BookStack, MinIO console, RAGFlow, Technitium DNS, support API, Infinity DB) are publicly reachable despite none of their ports appearing in UFW. This is a systemic, high-impact control failure.

Remediation (Phase Two): bind Docker publishes to 127.0.0.1 (e.g. -p 127.0.0.1:5601:5601) and route through the reverse proxy, or enable ufw-docker/DOCKER-USER chain rules.


3. Core (localhost / 152.53.192.33)

3.1 Open ports (non-loopback)

Port Proto Process Bound UFW Publicly reachable?
22 tcp sshd 0.0.0.0 ALLOW Anywhere Yes (intended)
80/443 tcp/udp caddy 152.53.192.33 ALLOW Anywhere Yes (intended ingress)
3000 tcp browserless (docker) 0.0.0.0 not listed Yes - bypass
3001 tcp uptime-kuma (docker) 0.0.0.0 not listed Yes - bypass
3002 tcp grafana * ALLOW Anywhere Yes (intentional)
9377 tcp camofox-browser (docker) 0.0.0.0 not listed Yes - bypass
8080 tcp python3 -m http.server 0.0.0.0 tailscale0 only No (UFW), bound 0.0.0.0
8083 tcp shark-game backend 0.0.0.0 not listed No (UFW)
8105 tcp rally backend 0.0.0.0 not listed No (UFW)
8787 tcp socat → 127.0.0.1:8642 (Hermes) 0.0.0.0 not listed No (UFW)
8899 tcp super-search MCP 0.0.0.0 172.17.0.0/16 only No
8934, 9876 tcp python3 -m http.server 0.0.0.0 not listed No (UFW)
9090 tcp prometheus * not listed No (UFW)
9100 tcp node_exporter * not listed No (UFW)
9119 tcp hermes gateway 0.0.0.0 not listed No (UFW)
9273 tcp telegraf * not listed No (UFW)
34239 tcp act_runner * not listed No (UFW)
1701 udp xl2tpd (L2TP) 0.0.0.0 not listed No (UFW)
51821 udp wireguard 0.0.0.0 ALLOW Anywhere Yes (intended)
5353 udp avahi-daemon 0.0.0.0 + mcast not listed No (multicast)

3.2 Firewall

UFW active, default deny incoming/allow outgoing/deny routed. Allows 22, 80, 443, 51821/udp, 8890, 3002, 8080 on tailscale0, 8899 from 172.17.0.0/16. Baseline is sound, but the Docker bypass (section 2) undermines it for 3000/3001/9377.

3.3 Findings

ID Severity Finding Evidence Why it matters
CORE-1 High Grafana (3002) publicly exposed by explicit UFW rule ufw: 3002/tcp ALLOW Anywhere; ss: *:3002 grafana Grafana holds dashboards of the entire monitoring estate; a public, unauthenticated-able Grafana (or one with weak creds) leaks ops data and is a frequent CVE target.
CORE-2 High Headless-browser proxies publicly reachable via Docker bypass docker: browserless 0.0.0.0:3000, camofox-browser 0.0.0.0:9377; nat DOCKER DNAT 0.0.0.0/0 dpt:3000, dpt:9377 browserless/camofox render arbitrary URLs; a public instance is an SSRF / internal-network pivot primitive.
CORE-3 Medium Monitoring exporters bound to 0.0.0.0 ss: *:9090 prometheus, *:9100 node_exporter, *:9273 telegraf These expose metrics (hostnames, labels, sometimes secrets in scrape configs) if UFW is ever disabled. Should be loopback/private-only.
CORE-4 Medium Three ad-hoc python3 -m http.server on 0.0.0.0 PIDs 2191495 (:8080), 1601850 (:8934), 1607064 (:9876) Unauthenticated static file servers serving unknown directories on all interfaces.
CORE-5 Medium Hermes control API exposed via socat on 0.0.0.0:8787 socat TCP-LISTEN:8787,fork,reuseaddr TCP:127.0.0.1:8642 A control/agent API reachable on all interfaces; UFW currently blocks it, but the binding is needlessly broad.
CORE-6 Low avahi/mDNS (5353) running on public interface ss: 0.0.0.0:5353 avahi-daemon Multicast name resolution leaks hostnames/services to the local segment.

4. app1 (152.53.36.131, Netcup RS 4000) - Wazuh / AI / CRM host

4.1 Open ports (non-loopback)

Port Proto Process Bound UFW Publicly reachable?
22 tcp sshd 0.0.0.0 ALLOW Yes
80/443 tcp caddy * ALLOW Yes (intended)
3006 tcp caddy (browserless proxy) * ALLOW from Core only No (source-restricted)
1514/1515 tcp Wazuh manager 0.0.0.0 ALLOW Anywhere Yes (intentional but risky)
514 udp Wazuh syslog 0.0.0.0 not listed Yes - bypass
55000 tcp Wazuh manager API 0.0.0.0 not listed Yes - bypass
9200 tcp Wazuh indexer (Elasticsearch) 0.0.0.0 not listed Yes - bypass
5601 tcp Wazuh dashboard 0.0.0.0 not listed Yes - bypass
3003 tcp Twenty CRM 0.0.0.0 not listed Yes - bypass
9120 tcp Komodo core 0.0.0.0 not listed Yes - bypass

4.2 Findings

ID Severity Finding Evidence Why it matters
APP1-1 Critical Wazuh security stack publicly exposed via Docker bypass docker: single-node-wazuh.indexer-1 0.0.0.0:9200, dashboard-1 0.0.0.0:5601, manager-1 0.0.0.0:55000, 0.0.0.0:514/udp; UFW lists none of these The Wazuh indexer holds all security-event telemetry for the estate and the dashboard is the admin console. Both are on the public internet with no UFW gate.
APP1-2 High Wazuh agent enrollment ports (1514/1515) open to the world by explicit UFW rule ufw: 1514/tcp, 1515/tcp ALLOW Anywhere Enrollment should be restricted to agent source ranges; a public enrollment port invites rogue agent registration into the SIEM.
APP1-3 High Twenty CRM (3003) and Komodo core (9120) publicly reachable via Docker bypass docker: twenty-server-1 0.0.0.0:3003, komodo-core-1 0.0.0.0:9120 Client CRM data (PII) and the Komodo deployment/automation control plane are public, bypassing UFW.
APP1-4 Info Intended public surface is correctly proxied /etc/caddy/Caddyfile maps vault, n8n, ai, admin-ai, noc, wz, sign.iamgmb.com, giftaroast.com, crm.debtrecoveryexperts.com, komodo.iamgmb.com, transitpin.iamgmb.com → 127.0.0.1 backends Reverse proxy is doing its job; the leaks are at the Docker layer, not Caddy.

5. app2 (152.53.39.202, Netcup RS 4000) - management/self-hosted stack

5.1 Open ports (non-loopback)

Port(s) Proto Service UFW Publicly reachable?
22 tcp sshd ALLOW Yes
80/443 tcp caddy ALLOW Yes (intended)
53 tcp/udp Technitium DNS (dns1.itpropartner.com) ALLOW only from 76.195.7.60 Yes - bypass (open resolver)
81, 8089, 8444 tcp UNMS/UISP nginx not listed Yes - bypass
8080, 8443, 8843, 8880 tcp UniFi controller not listed Yes - bypass
3478, 10001 udp UniFi STUN/discovery not listed Yes - bypass
2055 udp UNMS NetFlow not listed Yes - bypass
3022 tcp Gitea SSH not listed Yes - bypass
6875 tcp BookStack not listed Yes - bypass
6880 tcp support-api not listed Yes - bypass
8082 tcp Traccar web UI not listed Yes - bypass
5000-5150 tcp+udp Traccar device listeners (302 sockets) ALLOW Anywhere (explicit) Yes (intentional)
9001 tcp MinIO console not listed Yes - bypass
9380-9384, 9392 tcp RAGFlow not listed Yes - bypass
23817, 23820 tcp Infinity database not listed Yes - bypass

5.2 Findings

ID Severity Finding Evidence Why it matters
APP2-1 Critical UniFi Network Controller publicly exposed via Docker bypass docker: unifi-controller 0.0.0.0:8080,8443,8843,8880; nat DOCKER DNAT 0.0.0.0/0 dpt:8443 to:172.17.0.2:8443; UFW lists none The UniFi controller manages the tower/Wi-Fi network. Its 8443 web UI and 8080 device-inform endpoint are public. Compromise = control of the wireless/tower estate.
APP2-2 Critical UNMS/UISP (ISP management) publicly exposed via Docker bypass docker: unms-nginx 0.0.0.0:81,8089,8444; nat DNAT 0.0.0.0/0 dpt:8444 to:172.18.251.5:443 UISP is the entire WISP network-management plane (device inventory, configs, customers). Publicly reachable despite UFW.
APP2-3 High Technitium DNS published 0.0.0.0:53 bypasses source restriction UFW allows 53 only from 76.195.7.60, but docker: technitium 0.0.0.0:53->53 tcp+udp and DOCKER chain ACCEPT 0.0.0.0/0 dpt:53 Operator clearly intended DNS to be reachable only from the home router, yet the Docker publish makes it a public open resolver (DNS amplification/abuse risk).
APP2-4 High Traccar device range (5000-5150, ~302 sockets) fully public by explicit UFW rule ufw: 5000:5150/tcp+udp ALLOW Anywhere Fleet-tracking device protocol listeners are open to the world; large attack surface for protocol-specific exploits and data injection.
APP2-5 High Gitea SSH (3022), BookStack (6875), support-api (6880), MinIO console (9001), RAGFlow (9380-9392), Infinity DB (23817/23820) all public via bypass docker ps --format '{{.Ports}}' shows all bound 0.0.0.0 Source-code host, internal wiki, support API, object-storage console, and a vector database are each on the public internet.
APP2-6 Info git.itpropartner.com, hudu.itpropartner.com, unifi.itpropartner.com, unms.forefrontwireless.com, ragflow.itpropartner.com, gps.fleettracker360.com proxied via Caddy /etc/caddy/Caddyfile The reverse proxy is correctly terminating TLS for the intended public names; the exposure is the direct Docker port publish bypassing it.

6. app3 (152.53.241.111, Netcup RS 4000) - CloudPanel shared web host

6.1 Open ports (non-loopback)

Port Proto Process Bound UFW Publicly reachable?
22 tcp sshd 0.0.0.0 ALLOW Yes
80/443 tcp/udp nginx (CloudPanel) 0.0.0.0 ALLOW Yes (intended)
8443 tcp nginx (CloudPanel panel) 0.0.0.0 ALLOW 8433:8443 Yes (intentional)
8090 tcp backup-restore web app (python) 0.0.0.0 ALLOW Anywhere Yes (intentional)
21 tcp proftpd FTP 0.0.0.0 not listed No (UFW), bound 0.0.0.0
25 tcp postfix SMTP 0.0.0.0 not listed No (UFW)
3000 tcp buzz-prod-relay (docker) 0.0.0.0 not listed Yes - bypass
6081 tcp varnish 0.0.0.0 not listed No (UFW)
8080 tcp nginx (alt vhost) 0.0.0.0 not listed No (UFW)
33060 tcp mysqld (MySQL X) * not listed No (UFW), bound *

6.2 Findings

ID Severity Finding Evidence Why it matters
APP3-1 High CloudPanel admin panel (8443) publicly exposed ufw: 8433:8443/tcp ALLOW Anywhere; ss: 0.0.0.0:8443 nginx CloudPanel is the control plane for ~30 client websites on this box. Publicly exposing the admin panel (even with auth) is a high-value target.
APP3-2 High Backup-restore web UI (8090) publicly exposed ufw: 8090/tcp ALLOW Anywhere; ss: 0.0.0.0:8090 python /opt/backup-restore/app/app.py A web UI that can trigger restores is a destructive-capability surface and should be internal/Tailscale-only.
APP3-3 High Buzz relay (3000) public via Docker bypass docker: buzz-prod-relay-1 0.0.0.0:3000; nat DNAT 0.0.0.0/0 dpt:3000 to:172.19.0.5:3000; UFW does not list 3000 The Block/Buzz relay is publicly reachable with no UFW gate.
APP3-4 Medium MySQL X protocol (33060) bound to * ss: *:33060 mysqld Database protocol listener on all interfaces (currently UFW-blocked); should be loopback.
APP3-5 Medium FTP (21), SMTP (25), Varnish (6081) bound to 0.0.0.0 ss output FTP is cleartext (credential leakage if ever allowed); SMTP bound publicly invites relay abuse; Varnish cache admin not needed externally.

7. app1-bu (5.161.225.131, Hetzner CPX21) - warm standby

Minimal footprint. Only 22/tcp (sshd) and 41641/udp (tailscaled) listening on non-loopback. UFW active: 22/tcp and 51821/udp allowed.

ID Severity Finding Evidence Why it matters
APP1BU-1 Low UFW allows 51821/udp (WireGuard) but no WireGuard service is installed/listening ufw: 51821/udp ALLOW; ss shows no 51821; wg: command not found Leftover rule opens a port with no service behind it; indicates incomplete standby bring-up.
APP1BU-2 Info Tailscale device name drift tailscale status lists app1-bu (100.112.23.21, offline ~28d) and app1-bu-1 (100.95.212.28, online) The live standby is registered as app1-bu-1; the old app1-bu node is stale on the tailnet.

8. wphost02 (5.161.62.38, Hetzner) - legacy WordPress/RunCloud

Still live and serving traffic. Not decommissioned.

Port Proto Process Bound UFW Publicly reachable?
22 tcp sshd 0.0.0.0 ALLOW Yes
80/443 tcp nginx-rc 0.0.0.0 ALLOW Yes (legacy sites)
25 tcp postfix 0.0.0.0 not listed No (UFW)
34210 tcp runcloud agent * not listed No (UFW)
9100 tcp node_exporter * not listed No (UFW)
ID Severity Finding Evidence Why it matters
WPHOST-1 Medium Legacy WordPress host still publicly serving on 80/443 ss: 0.0.0.0:80,443 nginx-rc; ufw: 80,443 ALLOW Flagged as possibly decommissioned in scope; it is still a live public attack surface (legacy WordPress) that should be verified against the migration plan and decommissioned or hardened.
WPHOST-2 Low RunCloud agent (34210) and node_exporter (9100) bound to * ss: *:34210 runcloud, *:9100 node_exporter Management agent and metrics exporter on all interfaces (currently UFW-blocked).

Nameservers: ns1/ns2.siteground.net. All lookups against 1.1.1.1.

ID Severity Finding Evidence Why it matters
DNS-1 High Apex A record and ~10 legacy subdomains point to decommissioned GCP host 35.212.86.161 itpropartner.com A → 35.212.86.161 (no live server uses this IP). Also ssh, mail, ftp, autodiscover, autoconfig, clientmedia, www.clientmedia, media, www.media, apx, www.apx, www all → 35.212.86.161 The primary domain apex resolves to a retired host. Visitors and services hitting the apex go nowhere (or to an attacker if the IP is later reassigned). Live subdomains (ops, core, app1, git, panel, etc.) point to the correct hosts.
DNS-2 High SPF record is malformed (concatenated v=spf1 + truncated IP) "v=spf1 +a +mx +ip4:35.209.36v=spf1 +a +mx +ip4:35.212.110.90 include:... ~all" Two SPF records were merged and an IP (35.209.36) is truncated. Broken SPF breaks delivery and can allow spoofing depending on how receivers parse it.
DNS-3 Medium DMARC is p=none (monitoring only), and four related domains have no DMARC at all _dmarc.itpropartner.com → "v=DMARC1; p=none; aspf=r; adkim=r"; fleettracker360.com, voipsimplicity.com, iamgmb.com, debtrecoveryexperts.com → empty No enforcement means the domain can be spoofed with no receiver-side protection.
DNS-4 Medium fleettracker360.com has no MX, no SPF, no DMARC dig MX/TXT all empty (NS = Cloudflare) A live product domain with no mail/DMARC records is trivially spoofable.
DNS-5 Low voipsimplicity.com apex has no A record dig A voipsimplicity.com → (empty) Apex resolves to nothing; subdomain my.voipsimplicity.com works but the root does not.
DNS-6 Info DKIM present (dnssmarthost); wildcard absent; MX correct default._domainkey.itpropartner.com TXT → v=DKIM1...; *.itpropartner.com → empty; MX → mx10/20/30.antispam.mailspamprotection.com Good: DKIM configured, no wildcard, MX routes through SiteGround antispam.
DNS-7 Info Live subdomain map verified ops/core/my/sign/uptimekuma/app/status → 152.53.192.33; app1/n8n/ai/admin-ai/vault/wz/noc → 152.53.36.131; git/hudu/unifi → 152.53.39.202; panel/mainwp/support/auth2/docs/forms/mockups/proposals → 152.53.241.111; app1-bu → 5.161.225.131 Subdomains are correctly mapped to live hosts; only the apex + legacy names are stale.

10. VPN / private network paths

Path Technology Endpoints State
Server mesh Tailscale Core 100.71.155.7, app1 100.90.186.109, app3 100.72.15.12, app1-bu-1 100.95.212.28 (+ app2, personal devices) Up, full mesh
Core → home network WireGuard wg0 (10.77.0.1/24) peer home-gateway 10.77.0.2, endpoint 76.195.7.60:443 Up
Core → home lab / tower subnets WireGuard routed 10.1.0.0/16, 10.2.0.0/16, 172.16.1.0/24, 172.18.18.0/24 via wg0 Up
Core → WISP towers L2TP/IPsec (ppp0) server 76.195.7.60; routes 10.199.1-4.0/24, 10.199.100.0/24, 192.168.88.0/24 Down (charon not running, no ppp0, no 10.199 routes)
ID Severity Finding Evidence Why it matters
VPN-1 Medium Tower VPN (L2TP/IPsec) uses IKEv1 + AES128/SHA1/MODP1024 home-router-vpn.sh: ike=aes128-sha1-modp1024, esp=aes128-sha1-modp1024, keyexchange=ikev1 Legacy crypto for the path into the WISP tower network; weak and cryptographically dated.
VPN-2 Medium VPN credentials stored in plaintext config /root/.hermes/scripts/wisp-backup/config.yaml holds L2TP psk, username, password in cleartext (values [REDACTED]) A file-readable compromise of Core yields credentials to the home gateway and tower network. Cross-ref Sec-A for secret management.
VPN-3 Info Tower subnets only reachable while the nightly-backup VPN is up ipsec status → charon refused; no 10.199.* routes present Towers (T01-T04, MP100) are not persistently reachable; enumeration of their live config was not possible this session.

11. Edge devices (MikroTik CCR towers / UniFi / UISP)

Discoverable but not directly enumerated this session (VPN down; read-only constraint).

  • Home MikroTik gateway: public endpoint 76.195.7.60 (WireGuard :443, L2TP/IPsec :1701/udp). SSH reachable via WireGuard as home-gateway 10.77.0.2 (wisp_rsa key, user shonuff).
  • WISP tower routers (CCR): T01-RTR 10.199.1.4, T02-RTR 10.199.2.4, T03-RTR 10.199.3.4, T04-RTR 10.199.4.4, MP100-RTR 10.199.100.4 (source: wisp-backup/config.yaml).
  • UniFi controller runs on app2 (publicly exposed, see APP2-1). UNMS/UISP runs on app2 (publicly exposed, see APP2-2). Backup key deployment for towers is via deploy-key.rsc (SSH pubkey, not secret).
  • No edge-device config was modified; only inventory/paths recorded.

12. Access limitations

Host Status
Core, app1, app2, app3, app1-bu, wphost02 Reachable via itpp-infra key; full enumeration completed
MikroTik towers T01-T04, MP100 Not reachable - L2TP/IPsec VPN down (charon not running, no 10.199.* routes)
Home gateway 76.195.7.60 Public endpoint confirmed reachable at network level (WG/L2TP listeners); not SSH-enumerated this session

13. Consolidated severity summary

Severity Count Highlights
Critical 3 Docker bypass exposing Wazuh stack (APP1-1); UniFi controller public (APP2-1); UNMS/UISP public (APP2-2)
High 11 Grafana public, browserless/camofox public, Wazuh 1514/1515 public, Twenty/Komodo public, Technitium open resolver, Traccar range public, Gitea/BookStack/MinIO/RAGFlow public, CloudPanel public, backup-restore UI public, Buzz relay public, apex DNS stale, SPF broken
Medium 11 Monitoring exporters on 0.0.0.0, ad-hoc http.server, socat→Hermes, MySQL X on *, FTP/SMTP/Varnish on 0.0.0.0, DMARC p=none / missing, weak L2TP crypto, plaintext VPN creds, legacy wphost02 live
Low 4 avahi on public iface, app1-bu stale WG rule + tailscale name drift, runcloud/node_exporter on wphost02

Note on remediation: all items above are Phase Two candidates. No firewall, service, DNS, or VPN configuration was changed during this audit.