New stack tailscale-proxy: a LAN HTTP proxy (192.168.0.35:3128) that egresses
through the dedicated Hetzner Tailscale exit node fedora-technohim, so proxied
LAN clients appear on the internet as 89.167.72.79 without routing the docker
host itself through the tunnel.
- ts-proxy: Tailscale in userspace mode (--exit-node=100.121.234.85), exposing a
SOCKS5 proxy on :1055. Userspace mode makes no host route/firewall changes.
- tinyproxy: LAN-facing forward proxy on :3128 (Allow 192.168.0.0/22), upstream
socks5 to ts-proxy. Access log shipped to Alloy/Loki via the syslog
log-driver (tag tailscale-proxy).
The Tailscale auth key stays outside Git in /mnt/containers/tailscale-proxy/
ts.env (0600); node state persists in the state/ dir. tinyproxy.conf is tracked
here as source of truth. See tailscale-proxy/README.md.
Also adds logging/grafana-dashboards/tailscale-proxy.json: a Loki dashboard
(request rate by method, top destinations, top clients, totals, live access
log) built from the tinyproxy syslog stream, matching the existing dashboards'
schemaVersion 39 + ${datasource} template-var pattern.
Full build record in ops-knowledge
diagnostics/2026-07-23-02-tekhnohim-docker-tailscale-exit-proxy-stack.md.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
35 lines
2.0 KiB
Markdown
35 lines
2.0 KiB
Markdown
# Tailscale exit-node LAN proxy
|
|
|
|
LAN HTTP proxy that egresses through the dedicated Hetzner Tailscale exit node,
|
|
so proxied clients appear on the internet as `89.167.72.79` without routing the
|
|
docker host itself through the tunnel.
|
|
|
|
- client endpoint: `192.168.0.35:3128/tcp` (HTTP/HTTPS forward proxy);
|
|
- `tinyproxy` accepts LAN clients (`Allow 192.168.0.0/22`) and forwards upstream
|
|
over SOCKS5 to the Tailscale container;
|
|
- `ts-proxy` runs Tailscale in **userspace** mode and sends outbound traffic
|
|
through the exit node `fedora-technohim` (`100.121.234.85`);
|
|
- userspace mode adds **no host route/firewall changes** — the docker host's own
|
|
services (NPM, KMS, IPsec) keep egressing via the normal gateway;
|
|
- tinyproxy's access log ships to the logging stack (Alloy → Loki) via the
|
|
syslog log-driver (`tag: tailscale-proxy`); the Grafana dashboard
|
|
`logging/grafana-dashboards/tailscale-proxy.json` visualises it.
|
|
|
|
The stack deliberately keeps credential-bearing / stateful files outside Git:
|
|
|
|
| Host path | Purpose | Required mode |
|
|
|---|---|---|
|
|
| `/mnt/containers/tailscale-proxy/ts.env` | `TS_AUTHKEY=<tailscale auth key>` | `0600`, owner `root:root` |
|
|
| `/mnt/containers/tailscale-proxy/state/` | Tailscale node state (persists identity across restarts) | dir, owner `root:root` |
|
|
| `/mnt/containers/tailscale-proxy/tinyproxy.conf` | tinyproxy config (also tracked in this directory as the source of truth) | `0644` |
|
|
|
|
Before deploying: create `ts.env` on the host with a Tailscale auth key, and in
|
|
the Tailscale admin console approve the exit node and allow this node to use it.
|
|
Deploy this directory as a Portainer Git stack named `tailscale-proxy`, or run it
|
|
with Docker Compose using project name `tailscale-proxy`. The absolute
|
|
configuration files must already exist on the host before deployment.
|
|
|
|
Full build record and rationale (userspace vs TUN dead-ends, SOCKS5-vs-HTTP,
|
|
monitoring) is in ops-knowledge:
|
|
`diagnostics/2026-07-23-02-tekhnohim-docker-tailscale-exit-proxy-stack.md`.
|