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>
This commit is contained in:
2026-07-23 17:03:16 +03:00
co-authored by Claude Opus 4.8
parent 46bb775939
commit 155db049b0
3 changed files with 39 additions and 9 deletions
+8
View File
@@ -0,0 +1,8 @@
nserver 127.0.0.11
nscache 65536
timeouts 1 5 30 60 180 1800 15 60
log
auth iponly
allow * 192.168.0.0/22
parent 1000 socks5 ts-proxy 1055
socks -p1080 -i0.0.0.0
+16 -9
View File
@@ -1,19 +1,25 @@
# 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.
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.
- 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;
- 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;
- 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.
- 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:
@@ -22,6 +28,7 @@ The stack deliberately keeps credential-bearing / stateful files outside Git:
| `/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.
+15
View File
@@ -30,6 +30,21 @@ services:
tag: tailscale-proxy
networks: [proxynet]
socks5:
image: ghcr.io/3proxy/3proxy:latest
container_name: ts-lan-socks5
restart: unless-stopped
depends_on: [ts-proxy]
volumes: ["/mnt/containers/tailscale-proxy/3proxy.cfg:/etc/3proxy/3proxy.cfg:ro,z"]
ports: ["192.168.0.35:1080:1080"]
logging:
driver: syslog
options:
syslog-address: "udp://192.168.0.35:514"
syslog-format: rfc3164
tag: tailscale-socks5
networks: [proxynet]
networks:
proxynet:
name: tailscale-proxynet