# 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=` | `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`. ## Telemt monitoring Telemt exports Prometheus metrics on container port `9090`, published as `http://192.168.0.35:9092/metrics` because host port `9090` is reserved by Cockpit. The Telemt application whitelist permits only the client-02 Zabbix server (`192.168.0.34/32`). In Zabbix, import Telemt's upstream `tools/zbx_telemt_template.yaml`, link it to the Docker host, and set `{$TELEMT_URL}` to the URL above. Prometheus deliberately exposes only active-IP counts. The files in `zabbix/` add the text key `telemt.active_ips.list` without publishing Telemt's control API. A root timer enters only the container's network namespace, reads `/v1/users`, discards links/secrets in memory, and writes a sanitized username/IP list readable by the Zabbix agent: ```bash install -o root -g root -m 0755 zabbix/zabbix-telemt-active-ips \ /usr/local/libexec/zabbix-telemt-active-ips install -o root -g root -m 0644 zabbix/zabbix-telemt-active-ips.service \ zabbix/zabbix-telemt-active-ips.timer /etc/systemd/system/ install -o root -g root -m 0644 zabbix/telemt-active-ips.conf \ /etc/zabbix/zabbix_agent2.d/telemt-active-ips.conf systemctl daemon-reload systemctl enable --now zabbix-telemt-active-ips.timer systemctl start zabbix-telemt-active-ips.service systemctl restart zabbix-agent2 ``` Create a Zabbix agent item on `Fedora Kirochnaya` with key `telemt.active_ips.list`, information type **Text**, a 30-second update interval, and one-day history. IP addresses are operationally sensitive; do not retain this item longer or expose it on unrestricted dashboards.