asimatasert/t-forward

By asimatasert

Updated 12 days ago

Tunnel runtime for t-forward: openconnect VPN / SSH / relay per container, socat forwards + SOCKS5

Image
Networking
Security
Developer tools
0

7.7K

asimatasert/t-forward repository overview

t-forward — tunnel runtime image

The per-tunnel container image for t-forward, a Docker-based multi-tunnel manager. Each VPN / SSH jump / local relay runs in its own container built from this image, with socat port-forwards and an optional SOCKS5 proxy — so tunnels can't clash with each other or touch the host's routing/DNS.

You normally don't run this image by hand. Install the t-forward CLI and it pulls this image automatically on first up:

git clone https://github.com/Asimatasert/t-forward && cd t-forward
ln -s "$PWD/t-forward" /usr/local/bin/t-forward
t-forward up office        # pulls asimatasert/t-forward and connects

What's inside

PieceRole
Alpine 3.20base (~17 MB total)
openconnectVPN protocols: fortinet, gp (GlobalProtect), anyconnect, nc, pulse, f5, array
openssh-client + sshpassssh -N tunnels, ProxyJump chains
socatper-port TCP forwards (connection-logged)
microsocksoptional SOCKS5 proxy (built from source)
/entrypoint.shthe tunnel lifecycle: auth → connect → forwards → ready

Tags: latest tracks the newest release; version tags (0.5.0, …) match GitHub releases. Multi-arch: linux/amd64 + linux/arm64.

Container contract (for the curious / integrators)

The CLI drives one tunnel per container via environment variables and a mounted /auth tmpdir:

docker run -d --name tf-office \
  --cap-add=NET_ADMIN --device /dev/net/tun \
  -v "$authdir:/auth" \                    # contains: password (0600)
  -p 127.0.0.1:2201:10001 \
  -e TUNNEL_TYPE=vpn \
  -e VPN_SERVER=vpn.example.com:10443 -e VPN_PROTOCOL=fortinet \
  -e VPN_USER=me \
  -e FORWARDS='10001|10.0.0.20|22' \
  asimatasert/t-forward:latest

Key environment variables:

VarMeaning
TUNNEL_TYPEvpn (default) | ssh | local
VPN_SERVER, VPN_PROTOCOL, VPN_USERopenconnect target
SERVERCERTpin-sha256:… pin; empty = auto-detect & trust the current cert (TOFU)
NO_DTLStrue → TLS-only tunnel (for gateways with half-broken DTLS)
TOTPtrue → wait for a verification code (/auth/code, written by t-forward code)
SSH_HOST, SSH_USER, SSH_PORT, SSH_JUMPssh tunnels (+ /auth/ssh_key)
FORWARDSlport|rhost|rport;… — container-internal listeners you publish with -p
SOCKStrue → SOCKS5 on :1080
CONNECT_TIMEOUT / CODE_TIMEOUTtunnel-up wait (180s) / TOTP code wait (600s)

Auth flow: the container reads the password once from /auth/password, erases it immediately, and drops /auth/ready when forwards are live. Manual-TOTP tunnels drop /auth/awaiting_code and block until the host writes /auth/code (the panel/CLI does this for you). Listeners bind the Docker-published side only — nothing on the far side of the tunnel can reach your forwards.

Tag summary

Content type

Image

Digest

sha256:8900eeed5

Size

15.3 MB

Last updated

12 days ago

docker pull asimatasert/t-forward