Files
docker-infrastructure/tailscale-proxy
pipistrello 331c274b8b tailscale-proxy: pin 3proxy's nofile limit too
Completes the pair started in e41b55c, which deliberately left the proxy service
out because it was still on a runtime prlimit only and had not yet had its
maintenance window.

ts-lan-proxy was subject to the same Docker default soft limit of 1024 that took
Telemt down on 2026-09-09 — 3proxy does not raise its own limit either, and the
container's HostConfig.Ulimits was null. Steady state is ~22 descriptors, so the
ceiling was ~2% used in normal operation.

Applied on the client-02 host at 22:45 MSK with
  docker compose up -d --no-deps --force-recreate proxy
never a whole-stack up -d, which would also recreate ts-vpn and leave
ts-lan-ikev2 holding a stale namespace. Verified afterwards: HostConfig.Ulimits
now 65536/524288, container IP unchanged (172.31.0.4), egress through the proxy
still measures the exit node 89.167.72.79 against a direct-egress control of
212.116.102.42, 3proxy.cfg untouched so the conditional-auth behaviour is
unchanged, and the syslog log driver still emits access lines (confirmed on the
wire).

This file is STILL missing ts-vpn and ts-lan-ikev2, which have run on the host
since 2026-09-05 — deploying it as-is would take the IKEv2 VPN down. That drift
is unrelated to this commit and still needs its own.
2026-09-09 22:48:00 +03:00
..

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.

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:

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.