t-forward
Tunnel runtime for t-forward: openconnect VPN / SSH / relay per container, socat forwards + SOCKS5
7.7K
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
| Piece | Role |
|---|---|
| Alpine 3.20 | base (~17 MB total) |
openconnect | VPN protocols: fortinet, gp (GlobalProtect), anyconnect, nc, pulse, f5, array |
openssh-client + sshpass | ssh -N tunnels, ProxyJump chains |
socat | per-port TCP forwards (connection-logged) |
microsocks | optional SOCKS5 proxy (built from source) |
/entrypoint.sh | the 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.
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:
| Var | Meaning |
|---|---|
TUNNEL_TYPE | vpn (default) | ssh | local |
VPN_SERVER, VPN_PROTOCOL, VPN_USER | openconnect target |
SERVERCERT | pin-sha256:… pin; empty = auto-detect & trust the current cert (TOFU) |
NO_DTLS | true → TLS-only tunnel (for gateways with half-broken DTLS) |
TOTP | true → wait for a verification code (/auth/code, written by t-forward code) |
SSH_HOST, SSH_USER, SSH_PORT, SSH_JUMP | ssh tunnels (+ /auth/ssh_key) |
FORWARDS | lport|rhost|rport;… — container-internal listeners you publish with -p |
SOCKS | true → SOCKS5 on :1080 |
CONNECT_TIMEOUT / CODE_TIMEOUT | tunnel-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.
Content type
Image
Digest
sha256:8900eeed5…
Size
15.3 MB
Last updated
12 days ago
docker pull asimatasert/t-forward