Files
docker-infrastructure/tailscale-proxy/README.md
T
pipistrelloandClaude Opus 4.8 155db049b0 tailscale-proxy: add 3proxy SOCKS5 front (:1080)
Adds a LAN-facing SOCKS5 proxy alongside the existing tinyproxy HTTP proxy,
both egressing through the same Tailscale exit node.

- new service socks5 (ghcr.io/3proxy/3proxy): SOCKS5 on 192.168.0.35:1080,
  auth iponly / allow 192.168.0.0/22, chained via `parent socks5 ts-proxy 1055`
  to the Tailscale userspace SOCKS5, so clients exit as 89.167.72.79.
- 3proxy.cfg tracked here as source of truth; access log shipped to Loki via
  the syslog log-driver (tag tailscale-socks5).

Verified: curl --socks5 / --socks5-hostname 192.168.0.35:1080 -> 89.167.72.79,
wikipedia 200. Carries TCP only (no QUIC/UDP), same as the HTTP front - README
updated to note this.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-23 17:03:16 +03:00

42 lines
2.5 KiB
Markdown

# Tailscale exit-node LAN proxy
LAN HTTP and SOCKS5 proxies that egress 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.
- HTTP endpoint: `192.168.0.35:3128/tcp` (`tinyproxy`, HTTP/HTTPS forward proxy);
- SOCKS5 endpoint: `192.168.0.35:1080/tcp` (`3proxy`, LAN-only);
- both fronts accept LAN clients (`192.168.0.0/22`) and forward upstream over
SOCKS5 to the Tailscale container (`tinyproxy upstream socks5`, `3proxy parent
socks5`);
- `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;
- both fronts carry **TCP only** — QUIC/HTTP3 (UDP) is not proxied, so clients
must disable browser QUIC for e.g. YouTube video, or run the Tailscale client
directly and use the exit node for a full (UDP-capable) tunnel;
- proxy access logs ship to the logging stack (Alloy → Loki) via the syslog
log-driver (`tag: tailscale-proxy` for HTTP, `tag: tailscale-socks5` for
SOCKS5); the Grafana dashboard `logging/grafana-dashboards/tailscale-proxy.json`
visualises the HTTP proxy.
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` |
| `/mnt/containers/tailscale-proxy/3proxy.cfg` | 3proxy SOCKS5 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`.