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,268 @@
|
||||
# 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). |
|
||||
|
||||
---
|
||||
|
||||
## 9. Public DNS - itpropartner.com and related domains
|
||||
|
||||
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.
|
||||
Reference in New Issue
Block a user