fix(fleet-prometheus): bind listen socket to Tailscale IP, not 0.0.0.0
Previously published "9090:9090" → Docker bound to 0.0.0.0 (all host interfaces,
including the public Hetzner IP), leaving tailscale-internal enforced only by the
VPS firewall. Now bind explicitly to the VPS Tailscale interface for
defense-in-depth: the port does not exist on the public IP at all.
- ports -> "${TAILSCALE_BIND_IP}:9090:9090"
- env.example: add TAILSCALE_BIND_IP (VPS Tailscale IP, verify via `tailscale ip -4`)
- README: deploy section — .env is mandatory; a missing .env makes Compose
silently bind 0.0.0.0 (warns, does not fail), so use --env-file and verify host_ip
Smoke: config with --env-file and with co-located .env both resolve
host_ip=100.95.58.48; with .env absent Compose warns and falls back to 0.0.0.0
(documented). .env is gitignored (global *.env rule).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
01a0314176
commit
43c47a0a55
|
|
@ -47,7 +47,34 @@ TSDB lives in the named volume `fleet-prometheus_tsdb` → `/prometheus`.
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
- `prometheus.yml` — committed, **secret-free**. Global config + two scrape jobs.
|
- `prometheus.yml` — committed, **secret-free**. Global config + two scrape jobs.
|
||||||
- `env.example` — no secrets / no required env (kept only for layout parity).
|
- `env.example` → copy to `.env` (gitignored). Holds `TAILSCALE_BIND_IP`, the
|
||||||
|
VPS Tailscale interface IP the listen socket is bound to.
|
||||||
|
|
||||||
|
### Deploy — `.env` is mandatory
|
||||||
|
|
||||||
|
The port is published as `${TAILSCALE_BIND_IP}:9090:9090` so the socket is bound
|
||||||
|
**only** to the Tailscale interface, never `0.0.0.0`. Compose auto-loads a
|
||||||
|
co-located `services/fleet-prometheus/.env`, but if that file is **missing** the
|
||||||
|
variable resolves to a blank string and Compose **silently binds to 0.0.0.0**
|
||||||
|
(publicly reachable on the Hetzner IP) — it only warns, it does not fail.
|
||||||
|
|
||||||
|
Therefore, before `up -d`:
|
||||||
|
|
||||||
|
1. Create `services/fleet-prometheus/.env` from `env.example` with the real
|
||||||
|
`TAILSCALE_BIND_IP` (verify with `tailscale ip -4` on the VPS).
|
||||||
|
2. Deploy with the env file explicit, to be safe:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose -f services/fleet-prometheus/docker-compose.yml \
|
||||||
|
--env-file services/fleet-prometheus/.env up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Confirm the bind is Tailscale-only (must NOT show `0.0.0.0`):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose -f services/fleet-prometheus/docker-compose.yml \
|
||||||
|
--env-file services/fleet-prometheus/.env config | grep host_ip
|
||||||
|
```
|
||||||
|
|
||||||
### Scrape targets (scaffold)
|
### Scrape targets (scaffold)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,11 +20,14 @@ services:
|
||||||
- ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
|
- ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
|
||||||
- fleet_prometheus_tsdb:/prometheus
|
- fleet_prometheus_tsdb:/prometheus
|
||||||
ports:
|
ports:
|
||||||
# tailscale-internal: exposed exactly like control-plane (plain published
|
# tailscale-internal: the listen socket is bound ONLY to the VPS Tailscale
|
||||||
# HOST:CONTAINER mapping, no public npm reverse-proxy entry). Reachability
|
# interface IP (TAILSCALE_BIND_IP), never 0.0.0.0. The port therefore does
|
||||||
# is constrained to the Tailscale mesh at the VPS firewall layer, same as
|
# not exist on the public Hetzner IP at all — reachability is enforced in
|
||||||
# control-plane's 18180. Do NOT add this to npm / public DNS.
|
# the bind itself (defense-in-depth), not solely by the host firewall.
|
||||||
- "9090:9090"
|
# brain-watchdog on PIHA reaches this over the VPS Tailscale IP.
|
||||||
|
# Requires --env-file services/fleet-prometheus/.env at deploy (see README).
|
||||||
|
# Do NOT add this to npm / public DNS.
|
||||||
|
- "${TAILSCALE_BIND_IP}:9090:9090"
|
||||||
# node_exporter on the VPS runs with network_mode: host, so it listens on
|
# node_exporter on the VPS runs with network_mode: host, so it listens on
|
||||||
# the host's :9100. This bridged container reaches it via host-gateway.
|
# the host's :9100. This bridged container reaches it via host-gateway.
|
||||||
extra_hosts:
|
extra_hosts:
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,10 @@
|
||||||
# fleet-prometheus has NO secrets and NO required environment.
|
# fleet-prometheus has NO secrets, but it does require one host-local value for
|
||||||
|
# the Tailscale-only port bind. Copy this file to .env (gitignored) and pass it
|
||||||
|
# at deploy with --env-file services/fleet-prometheus/.env.
|
||||||
#
|
#
|
||||||
# Configuration lives entirely in prometheus.yml (secret-free by contract) and
|
# Configuration otherwise lives entirely in prometheus.yml (secret-free by
|
||||||
# the compose command flags. There is intentionally nothing to copy to a .env.
|
# contract) and the compose command flags.
|
||||||
#
|
|
||||||
# This template exists only to keep the standard service file layout. If a
|
# Tailscale IP węzła VPS (ubuntu-4gb-hel1-1). Bind nasłuchu Prometheus
|
||||||
# future step needs env (e.g. an Alertmanager URL), add it here and wire an
|
# TYLKO do mesha — nie 0.0.0.0. Zweryfikuj przy odtwarzaniu hosta: tailscale ip -4.
|
||||||
# env_file into docker-compose.yml at that point.
|
TAILSCALE_BIND_IP=100.95.58.48
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue