tailscale-proxy: unify HTTP+SOCKS on 3proxy with LAN-free / external-password auth
Retire the tinyproxy HTTP container (tinyproxy has no per-source-IP conditional auth) and serve both the HTTP proxy (:3128) and SOCKS5 (:1080) from a single 3proxy instance. LAN (192.168.0.0/22) stays passwordless; any non-LAN source (i.e. external clients via the router port-forward) must authenticate. Credentials live in a host-only /etc/3proxy/3proxy.secret (0600, not in git), included by 3proxy.cfg. A deny rule on the gateway IP makes the proxy fail closed if the port-forward ever SNATs to 192.168.0.1. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1,8 +1,47 @@
|
|||||||
|
# Unified LAN proxy for the tekhnohim Tailscale exit-node egress.
|
||||||
|
#
|
||||||
|
# One 3proxy instance serves BOTH an HTTP proxy (:3128) and a SOCKS5 proxy
|
||||||
|
# (:1080), each chained to the Tailscale userspace SOCKS5 (ts-proxy:1055) so
|
||||||
|
# clients exit the internet as the Hetzner exit-node IP (89.167.72.79).
|
||||||
|
# TCP only (Tailscale userspace SOCKS5 has no UDP ASSOCIATE -> no QUIC/HTTP3).
|
||||||
|
#
|
||||||
|
# Access model (LAN free, outside password):
|
||||||
|
# * LAN 192.168.0.0/22 -> authorised by source IP, NO password.
|
||||||
|
# * everyone else -> must authenticate (external clients arriving via
|
||||||
|
# the router port-forward keep their public source
|
||||||
|
# IP, so they fall through to the password rule).
|
||||||
|
# The username/password lives in a host-only file (0600, NOT in git), mounted
|
||||||
|
# separately and pulled in with the include below - same pattern as ts.env.
|
||||||
|
|
||||||
nserver 127.0.0.11
|
nserver 127.0.0.11
|
||||||
nscache 65536
|
nscache 65536
|
||||||
timeouts 1 5 30 60 180 1800 15 60
|
timeouts 1 5 30 60 180 1800 15 60
|
||||||
log
|
log
|
||||||
auth iponly
|
|
||||||
|
# Account(s) for external, password-authenticated access (host-only secret):
|
||||||
|
include /etc/3proxy/3proxy.secret
|
||||||
|
|
||||||
|
# iponly authorises the LAN by address; strong forces login for the rest.
|
||||||
|
auth iponly strong
|
||||||
|
|
||||||
|
# Safety guard: never treat the router's own address as a trusted LAN client.
|
||||||
|
# If the port-forward ever SNATs external traffic to the gateway IP, this rule
|
||||||
|
# makes the proxy fail CLOSED (external denied) instead of becoming an open
|
||||||
|
# proxy. Verify after opening the port: an unauthenticated external client
|
||||||
|
# must be refused.
|
||||||
|
deny * 192.168.0.1
|
||||||
|
|
||||||
|
# LAN clients: allowed by source IP, no password. Egress via the Tailscale
|
||||||
|
# userspace SOCKS5 (a `parent` binds to the `allow` line directly above it).
|
||||||
allow * 192.168.0.0/22
|
allow * 192.168.0.0/22
|
||||||
parent 1000 socks5 ts-proxy 1055
|
parent 1000 socks5 ts-proxy 1055
|
||||||
|
|
||||||
|
# External clients: must present the configured account, same egress.
|
||||||
|
allow thproxy
|
||||||
|
parent 1000 socks5 ts-proxy 1055
|
||||||
|
|
||||||
|
# Anything else: denied.
|
||||||
|
deny *
|
||||||
|
|
||||||
|
proxy -p3128 -a -i0.0.0.0
|
||||||
socks -p1080 -i0.0.0.0
|
socks -p1080 -i0.0.0.0
|
||||||
|
|||||||
@@ -15,13 +15,20 @@ services:
|
|||||||
volumes: ["/mnt/containers/tailscale-proxy/state:/var/lib/tailscale:z"]
|
volumes: ["/mnt/containers/tailscale-proxy/state:/var/lib/tailscale:z"]
|
||||||
networks: [proxynet]
|
networks: [proxynet]
|
||||||
|
|
||||||
tinyproxy:
|
# Unified 3proxy front: HTTP proxy (:3128) + SOCKS5 (:1080), LAN passwordless
|
||||||
image: vimagick/tinyproxy:latest
|
# and external password-authenticated. Replaces the former tinyproxy HTTP
|
||||||
|
# container (tinyproxy cannot do per-source-IP conditional auth).
|
||||||
|
proxy:
|
||||||
|
image: ghcr.io/3proxy/3proxy:latest
|
||||||
container_name: ts-lan-proxy
|
container_name: ts-lan-proxy
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
depends_on: [ts-proxy]
|
depends_on: [ts-proxy]
|
||||||
volumes: ["/mnt/containers/tailscale-proxy/tinyproxy.conf:/etc/tinyproxy/tinyproxy.conf:ro,z"]
|
volumes:
|
||||||
ports: ["192.168.0.35:3128:3128"]
|
- "/mnt/containers/tailscale-proxy/3proxy.cfg:/etc/3proxy/3proxy.cfg:ro,z"
|
||||||
|
- "/mnt/containers/tailscale-proxy/3proxy.secret:/etc/3proxy/3proxy.secret:ro,z"
|
||||||
|
ports:
|
||||||
|
- "192.168.0.35:3128:3128"
|
||||||
|
- "192.168.0.35:1080:1080"
|
||||||
logging:
|
logging:
|
||||||
driver: syslog
|
driver: syslog
|
||||||
options:
|
options:
|
||||||
@@ -30,21 +37,6 @@ services:
|
|||||||
tag: tailscale-proxy
|
tag: tailscale-proxy
|
||||||
networks: [proxynet]
|
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:
|
networks:
|
||||||
proxynet:
|
proxynet:
|
||||||
name: tailscale-proxynet
|
name: tailscale-proxynet
|
||||||
|
|||||||
@@ -1,7 +0,0 @@
|
|||||||
Port 3128
|
|
||||||
Listen 0.0.0.0
|
|
||||||
Allow 192.168.0.0/22
|
|
||||||
DisableViaHeader Yes
|
|
||||||
Timeout 600
|
|
||||||
LogLevel Info
|
|
||||||
upstream socks5 ts-proxy:1055
|
|
||||||
Reference in New Issue
Block a user