15 KiB
15 KiB
ByteLyst VM Exposure Inventory
Generated: 2026-05-27
Host: srv1491630
Purpose: Phase 0 inventory for docs/vm-security-blind-spots-roadmap.md.
This inventory is a pre-change control document. It does not approve exposure by itself. Each Needs decision row requires owner approval before firewall, Compose, Caddy, or SSH changes.
Classification Key
| Class | Meaning | Expected Controls |
|---|---|---|
public-caddy |
Public app/API intended to be reached through Caddy | Caddy TLS, hostname/path routing, app auth where needed, no direct host-port exposure |
public-direct |
Direct host-port access intentionally public | explicit approval, provider/UFW allowance, monitoring |
private-admin |
Admin/dev/internal tool | Tailscale/VPN, SSH tunnel, IP allowlist, or auth gate |
loopback-only |
Host-local service used by Caddy or local automation | bind 127.0.0.1:port; no external bind |
docker-internal |
Container-to-container only | no host port mapping |
retire |
Unused/deprecated | remove service or disable host exposure |
needs-decision |
Existing exposure with unknown/unclear intent | owner must classify before remediation |
Caddy Public Routes
| Hostname/path | Upstream | Initial class | Decision needed |
|---|---|---|---|
api.bytelyst.com/platform/* |
platform-service:4003 |
public-caddy |
Confirm auth posture |
api.bytelyst.com/extraction/* |
extraction-service:4005 |
public-caddy |
Confirm auth posture |
api.bytelyst.com/mcp/* |
mcp-server:4007 |
public-caddy |
Confirm public need |
api.bytelyst.com/peakpulse/* |
peakpulse-backend:4010 |
public-caddy |
Confirm direct host port can close |
api.bytelyst.com/chronomind/* |
chronomind-backend:4011 |
public-caddy |
Confirm direct host port can close |
api.bytelyst.com/jarvisjr/* |
jarvisjr-backend:4012 |
public-caddy |
Confirm direct host port can close |
api.bytelyst.com/nomgap/* |
nomgap-backend:4013 |
public-caddy |
Confirm direct host port can close |
api.bytelyst.com/mindlyst/* |
mindlyst-backend:4014 |
public-caddy |
Confirm direct host port can close |
api.bytelyst.com/lysnrai/* |
lysnrai-backend:4015 |
public-caddy |
Confirm direct host port can close |
api.bytelyst.com/notelett/* |
notelett-backend:4016 |
public-caddy |
Confirm direct host port can close |
api.bytelyst.com/flowmonk/* |
flowmonk-backend:4017 |
public-caddy |
Confirm direct host port can close |
api.bytelyst.com/actiontrail/* |
actiontrail-backend:4020 |
public-caddy |
Confirm direct host port can close |
api.bytelyst.com/localmemgpt/* |
localmemgpt-backend:4019 |
public-caddy |
Confirm direct host port can close |
api.bytelyst.com/invttrdg/* |
invttrdg-backend:4018 |
public-caddy |
Confirm direct host port can close |
api.bytelyst.com/devops/* |
devops-backend:4004 |
private-admin |
Should require auth/private access |
gitea.bytelyst.com |
gitea-npm-registry:3000 |
public-caddy |
Confirm direct 3300 can close |
admin.bytelyst.com |
admin-web:3001 |
private-admin |
Confirm route still resolves; upstream container not in current docker ps |
devops.bytelyst.com |
devops-web:3000 |
private-admin |
Should require auth/private access |
tracker.bytelyst.com |
tracker-web:3003 |
public-caddy |
Confirm direct host port can close |
llmlab.bytelyst.com |
llmlab-dashboard:3075 |
private-admin |
Dashboard currently unhealthy; decide public/private/retire |
ollama.bytelyst.com |
172.17.0.1:11434 |
private-admin |
Model endpoint should not be unauthenticated public |
trading-api.bytelyst.com |
trading-backend:5000 |
public-caddy |
Confirm auth posture |
invttrdg.bytelyst.com |
invttrdg-web:3085 |
public-caddy |
Confirm direct host port can close |
notes.bytelyst.com |
notelett-web:3045 |
public-caddy |
Confirm direct host port can close |
clock.bytelyst.com |
chronomind-web:3030 |
public-caddy |
Confirm direct host port can close |
Public Bind Inventory
These listeners were bound on 0.0.0.0 and/or [::] during review.
| Port | Service/container | Owner / Compose source | Current route | Initial class | Proposed action |
|---|---|---|---|---|---|
22 |
sshd |
host systemd | direct SSH | public-direct |
Keep public only after SSH key hardening |
80, 443 |
caddy |
/opt/bytelyst/learning_ai_common_plat/docker-compose.ecosystem.yml |
public ingress | public-caddy |
Keep public |
3000 |
notelett-web |
/opt/bytelyst/learning_ai_notes/docker-compose.yml |
notes.bytelyst.com |
public-caddy with direct bypass |
Bind loopback or remove host port after Caddy smoke |
3002 |
lysnrai-dashboard |
/opt/bytelyst/learning_ai_common_plat/docker-compose.ecosystem.yml |
none found in Caddy | loopback-only |
Bound to 127.0.0.1 on 2026-05-27; still needs public/private product decision |
3003 |
tracker-web |
/opt/bytelyst/learning_ai_common_plat/docker-compose.ecosystem.yml |
tracker.bytelyst.com |
public-caddy |
Bound to 127.0.0.1 on 2026-05-27; keep Caddy route |
3030 |
chronomind-web |
/root/bytelyst.ai/repos/learning_ai_clock/docker-compose.yml |
clock.bytelyst.com |
public-caddy with direct bypass |
Bind loopback or remove host port after Caddy smoke |
3035 |
jarvisjr-web |
/opt/bytelyst/learning_ai_common_plat/docker-compose.ecosystem.yml |
none found in Caddy | loopback-only |
Bound to 127.0.0.1 on 2026-05-27; still needs public/private product decision |
3040 |
flowmonk-web |
/opt/bytelyst/learning_ai_common_plat/docker-compose.ecosystem.yml |
none found in Caddy | loopback-only |
Bound to 127.0.0.1 on 2026-05-27; still needs public/private product decision |
3049 |
devops-web |
/opt/bytelyst/bytelyst-devops-tools/dashboard/docker-compose.yml |
devops.bytelyst.com |
private-admin with direct bypass |
Fix old repo path drift, then bind loopback/private |
3050 |
mindlyst-web |
/opt/bytelyst/learning_ai_common_plat/docker-compose.ecosystem.yml |
none found in Caddy | loopback-only |
Bound to 127.0.0.1 on 2026-05-27; still needs public/private product decision |
3055 |
nomgap-web |
orphan from older /opt/bytelyst/learning_ai_common_plat/docker-compose.ecosystem.yml |
none found in Caddy | retire |
Retired on 2026-05-27; current Compose says Nomgap web is deployed to Vercel |
3060 |
actiontrail-web |
/opt/bytelyst/learning_ai_common_plat/docker-compose.ecosystem.yml |
none found in Caddy | loopback-only |
Bound to 127.0.0.1 on 2026-05-27; still needs public/private product decision |
3070 |
localmemgpt-web |
/opt/bytelyst/learning_ai_common_plat/docker-compose.ecosystem.yml |
none found in Caddy | loopback-only |
Bound to 127.0.0.1 on 2026-05-27; still needs public/private product decision |
3075 |
llmlab-dashboard |
/opt/bytelyst/learning_ai_common_plat/docker-compose.ecosystem.yml |
llmlab.bytelyst.com |
private-admin |
Bound to 127.0.0.1 on 2026-05-27; still needs auth/private gate for Caddy route |
3085 |
invttrdg-web |
/opt/bytelyst/learning_ai_invt_trdg/docker-compose.yml |
invttrdg.bytelyst.com |
public-caddy with direct bypass |
Bind loopback or remove host port after Caddy smoke |
3100 |
loki |
/opt/bytelyst/learning_ai_common_plat/docker-compose.ecosystem.yml |
none found in Caddy | loopback-only |
Bound to 127.0.0.1 on 2026-05-27 |
3300 |
gitea-npm-registry |
non-Compose container labels absent | gitea.bytelyst.com |
public-caddy with direct bypass |
Bind loopback or private; keep Caddy route |
4004 |
devops-backend |
/opt/bytelyst/learning_ai_devops_tools/dashboard/docker-compose.yml |
api.bytelyst.com/devops/* |
private-admin with direct bypass |
Bind loopback/private |
4010 |
peakpulse-backend |
/opt/bytelyst/learning_ai_common_plat/docker-compose.ecosystem.yml |
api.bytelyst.com/peakpulse/* |
public-caddy |
Host port removed by Compose recreate on 2026-05-27; keep Caddy route |
4011 |
chronomind-backend |
/root/bytelyst.ai/repos/learning_ai_clock/docker-compose.yml |
api.bytelyst.com/chronomind/* |
public-caddy with direct bypass |
Bind loopback or remove host port after Caddy smoke |
4012 |
jarvisjr-backend |
/opt/bytelyst/learning_ai_common_plat/docker-compose.ecosystem.yml |
api.bytelyst.com/jarvisjr/* |
public-caddy |
Host port removed by Compose recreate on 2026-05-27; keep Caddy route |
4013 |
nomgap-backend |
/opt/bytelyst/learning_ai_common_plat/docker-compose.ecosystem.yml |
api.bytelyst.com/nomgap/* |
public-caddy |
Host port removed by Compose recreate on 2026-05-27; keep Caddy route |
4014 |
mindlyst-backend |
/opt/bytelyst/learning_ai_common_plat/docker-compose.ecosystem.yml |
api.bytelyst.com/mindlyst/* |
public-caddy |
Host port removed by Compose recreate on 2026-05-27; keep Caddy route |
4015 |
lysnrai-backend |
/opt/bytelyst/learning_ai_common_plat/docker-compose.ecosystem.yml |
api.bytelyst.com/lysnrai/* |
public-caddy |
Host port removed by Compose recreate on 2026-05-27; keep Caddy route |
4016 |
notelett-backend |
/opt/bytelyst/learning_ai_notes/docker-compose.yml |
api.bytelyst.com/notelett/* |
public-caddy with direct bypass |
Bind loopback or remove host port after Caddy smoke |
4017 |
flowmonk-backend |
/opt/bytelyst/learning_ai_common_plat/docker-compose.ecosystem.yml |
api.bytelyst.com/flowmonk/* |
public-caddy |
Host port removed by Compose recreate on 2026-05-27; keep Caddy route |
4019 |
localmemgpt-backend |
/opt/bytelyst/learning_ai_common_plat/docker-compose.ecosystem.yml |
api.bytelyst.com/localmemgpt/* |
public-caddy |
Host port removed by Compose recreate on 2026-05-27; keep Caddy route |
4020 |
actiontrail-backend |
/opt/bytelyst/learning_ai_common_plat/docker-compose.ecosystem.yml |
api.bytelyst.com/actiontrail/* |
public-caddy |
Bound to 127.0.0.1 on 2026-05-27; route mapping still needs Caddy/product verification |
4025 |
invttrdg-backend |
/opt/bytelyst/learning_ai_invt_trdg/docker-compose.yml |
api.bytelyst.com/invttrdg/* |
public-caddy with direct bypass |
Bind loopback or remove host port after Caddy smoke |
1025 |
mailpit SMTP |
/opt/bytelyst/learning_ai_common_plat/docker-compose.ecosystem.yml |
none found in Caddy | loopback-only |
Bound to 127.0.0.1 on 2026-05-27 |
8025 |
mailpit UI |
/opt/bytelyst/learning_ai_common_plat/docker-compose.ecosystem.yml |
none found in Caddy | loopback-only |
Bound to 127.0.0.1 on 2026-05-27 |
10000 |
azurite |
/opt/bytelyst/learning_ai_common_plat/docker-compose.ecosystem.yml |
none found in Caddy | loopback-only |
Bound to 127.0.0.1 on 2026-05-27 |
1234, 8081 |
cosmos-emulator |
/opt/bytelyst/learning_ai_common_plat/docker-compose.ecosystem.yml |
none found in Caddy | loopback-only |
Bound to 127.0.0.1 on 2026-05-27 |
11434 |
ollama host process |
host service | ollama.bytelyst.com |
private-admin |
Bind loopback/private or auth-gate; do not leave raw public |
Non-Public / Internal Listeners
| Address/port | Process/service | Initial class | Notes |
|---|---|---|---|
127.0.0.53:53, 127.0.0.54:53 |
systemd-resolve |
host-internal | Expected resolver listeners |
127.0.0.1:44561 |
ollama |
host-internal | Secondary loopback listener observed |
100.87.53.10:9119, 100.87.53.10:9120 |
hermes |
private-admin | Tailscale-only bind; keep private |
100.87.53.10:51855, [fd7a:115c:a1e0::3c33:350a]:43379 |
tailscaled |
private-admin | Tailscale control/data listeners |
| Docker-internal only | platform-service, mcp-server, extraction-service, prometheus, cadvisor, node-exporter, valkey, trading-backend |
docker-internal/private | No direct host bind seen, except Caddy may route to some by service name |
Unhealthy Containers At Inventory Time
| Container | Port exposure | Initial action |
|---|---|---|
learning_ai_common_plat-llmlab-dashboard-1 |
0.0.0.0:3075 and Caddy llmlab.bytelyst.com |
Fix/gate/retire before treating public |
learning_ai_common_plat-actiontrail-web-1 |
0.0.0.0:3060 |
Classify and fix/retire |
learning_ai_common_plat-jarvisjr-web-1 |
0.0.0.0:3035 |
Classify and fix/retire |
learning_ai_common_plat-localmemgpt-web-1 |
0.0.0.0:3070 |
Classify and fix/retire |
learning_ai_common_plat-nomgap-web-1 |
0.0.0.0:3055 |
Classify and fix/retire |
learning_ai_common_plat-flowmonk-web-1 |
0.0.0.0:3040 |
Classify and fix/retire |
learning_ai_common_plat-mindlyst-web-1 |
0.0.0.0:3050 |
Classify and fix/retire |
Drift / Follow-Up Findings
nomgap-webwas an orphan from an older Compose revision, had no Caddy route, and was retired on 2026-05-27.devops-backendruns from/opt/bytelyst/learning_ai_devops_tools/dashboard/docker-compose.yml.devops-webruns from/opt/bytelyst/bytelyst-devops-tools/dashboard/docker-compose.yml, an older path. Align this before changing devops dashboard port bindings.gitea-npm-registryhas no Compose labels in Docker inspect output. Find its systemd/compose owner before changing3300.admin.bytelyst.compoints atadmin-web:3001, but noadmin-webcontainer was present indocker psduring this inventory.
Proposed First Remediation Groups
Do these in separate commits/windows with smoke checks after each group.
- Internal emulators and mail tools:
1025,8025,10000,1234,8081.- Expected class:
docker-internalorprivate-admin. - Preferred fix: remove host port mappings or bind to
127.0.0.1.
- Expected class:
- Observability internals:
3100and any future Prometheus/Grafana/exporter direct binds.- Expected class:
private-admin. - Preferred fix: Docker-internal or Tailscale-only.
- Expected class:
- Admin/model surfaces:
11434,3075,3049,4004.- Expected class:
private-admin. - Preferred fix: auth gate/private route and no raw public port.
- Expected class:
- Caddy-backed app/API direct bypass ports:
3000,3003,3030,3085,4010-4025.- Expected class:
public-caddy. - Preferred fix: keep Caddy public, remove raw direct public binds.
- Expected class:
- SSH:
22.- Expected class:
public-direct. - Preferred fix: keep public only after key-only and root-login hardening.
- Expected class:
Verification Commands
date -Is
ss -ltnp
docker ps --format '{{.Names}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}'
docker ps -q | xargs -r docker inspect --format '{{.Name}}\tproject={{index .Config.Labels "com.docker.compose.project"}}\tservice={{index .Config.Labels "com.docker.compose.service"}}\tworkdir={{index .Config.Labels "com.docker.compose.project.working_dir"}}\tconfig={{index .Config.Labels "com.docker.compose.project.config_files"}}'
docker exec caddy caddy validate --config /etc/caddy/Caddyfile
sed -n '1,260p' /opt/bytelyst/Caddyfile
iptables -S DOCKER-USER