SSH TUN gateway with TCP/UDP and SOCKS5. https://github.com/killdns/ssh-tun-gateway
228
GitHub repository | Docker Hub image | Release v0.1.0
ssh-tun-gateway is a small Linux container that creates an IPv4 point-to-point
OpenSSH TUN tunnel and can expose the tunnel as:
CONNECT and UDP ASSOCIATE;LAN client -> router or Docker host -> container -> OpenSSH TUN -> Linux server -> Internet
The SOCKS5 service is provided by HevSocks5Server. It is built statically from a pinned release archive whose SHA-256 checksum is verified during the image build.
| Platform | Typical target |
|---|---|
linux/amd64 | x86-64 servers and PCs |
linux/arm64 | 64-bit ARM routers and single-board computers |
linux/arm/v7 | 32-bit ARM devices, including MikroTik RB4011 |
Published tags are multi-platform images, so Docker selects the correct variant automatically.
RUN_MODE | L3 gateway | SOCKS5 |
|---|---|---|
gateway | yes | no |
socks | no | yes |
both | yes | yes |
The default mode is gateway. Every mode still uses the OpenSSH TUN tunnel;
the SOCKS5 server opens its outbound connections through that tunnel.
/dev/net/tun.NET_ADMIN capability.known_hosts file.iproute2, iptables, and sudo.PermitTunnel point-to-point for restricted tunnel accounts./30 network per client.The templates in server configure restricted accounts without shell, PTY, agent, X11, or TCP forwarding access. See server/README.md.
Copy examples/compose.yaml into a deployment
directory and copy examples/env.example there as
.env.
Create a config directory containing:
config/id_ed25519
config/known_hosts
Set restrictive permissions on the private key and edit .env for your
network.
The example uses the published
docker.io/killdns/ssh-tun-gateway:0.1.0 image. Change only the tag when
selecting another release.
Start the container:
docker compose up -d
docker compose logs -f
For a direct docker run deployment:
docker run -d \
--name ssh-tun-gateway \
--restart unless-stopped \
--cap-add NET_ADMIN \
--device /dev/net/tun:/dev/net/tun \
--env-file .env \
--mount type=bind,src="$PWD/config",dst=/config,readonly \
docker.io/killdns/ssh-tun-gateway:0.1.0
| Variable | Description |
|---|---|
SSH_HOST | Numeric IPv4 address of the SSH server |
CONTAINER_GATEWAY | Original gateway in the container network |
LAN_CIDRS | Comma-separated networks that must remain reachable outside the TUN |
LAN_CIDRS is required even in socks mode. The container moves its default
route into the tunnel, so explicit return routes to SOCKS clients are necessary.
| Variable | Default | Description |
|---|---|---|
SSH_ROUTE_IP | SSH_HOST | Server address pinned to the original gateway |
SSH_USER | ssh-tunnel | Restricted SSH tunnel account |
SSH_PORT | 22 | SSH server port |
UPLINK_INTERFACE | automatic | Original uplink interface |
IDENTITY_FILE | /config/id_ed25519 | Private SSH key |
KNOWN_HOSTS_FILE | /config/known_hosts | Verified OpenSSH host keys |
STRICT_HOST_KEY_CHECKING | yes | OpenSSH host key policy |
LOCAL_TUN_ID | 0 | Container-side TUN number |
REMOTE_TUN_ID | 0 | Server-side TUN number |
TUN_LOCAL | 10.255.255.2 | Container TUN address |
TUN_REMOTE | 10.255.255.1 | Server TUN address |
TUN_MTU | 1400 | Tunnel MTU |
ENABLE_NAT | 1 | Masquerade routed LAN clients behind TUN_LOCAL |
Each client must have a unique SSH_USER, SSH key, REMOTE_TUN_ID, and /30
network. LOCAL_TUN_ID=0 may be reused because containers have separate network
namespaces.
| Variable | Default | Description |
|---|---|---|
SOCKS_BIND | 0.0.0.0 | SOCKS5 listen address |
SOCKS_PORT | 1080 | TCP control and CONNECT port |
SOCKS_USER | empty | Optional username |
SOCKS_PASSWORD | empty | Optional password |
SOCKS_ALLOW_NO_AUTH | 1 | Permit startup without credentials |
SOCKS_DNS_SERVER | 1.1.1.1 | Resolver used after the TUN is established |
SOCKS_WORKERS | 2 | HevSocks5Server worker count |
SOCKS_UDP_PORT_MIN | 20000 | First UDP relay port |
SOCKS_UDP_PORT_MAX | 20999 | Last UDP relay port |
SOCKS_UDP_ADVERTISE_IP | empty | Relay address returned to UDP clients |
For a few trusted clients, a smaller UDP range such as 20000-20031 is usually
enough. Allow TCP 1080 and the selected UDP range only from trusted networks.
SOCKS_UDP_ADVERTISE_IP should stay empty when clients route directly to the
container address. Set it to the host or router address only when clients reach
the proxy through destination NAT, and forward the complete UDP range to the
container as well.
SOCKS5 UDP requires client-side UDP ASSOCIATE support. A browser's basic SOCKS
setting often proxies TCP only. For transparent whole-device UDP, use
RUN_MODE=gateway or RUN_MODE=both and route the device through the container.
RouterOS examples are under examples/routeros:
container-only.rsc creates the container without changing LAN routing;policy-routing.rsc also demonstrates policy routing and DNS redirection.Review every variable before importing a script. The files contain documentation
addresses, not deployment values. For an RB4011, use the linux/arm/v7 image.
Ready-to-import archives are attached to release v0.1.0:
ssh-tun-gateway-armv7.tar for MikroTik RB4011;ssh-tun-gateway-arm64.tar for 64-bit ARM devices;ssh-tun-gateway-amd64.tar for x86-64 devices;SHA256SUMS.txt for download verification.Alternatively, create a RouterOS-compatible ARMv7 TAR from Docker Hub:
docker pull --platform linux/arm/v7 docker.io/killdns/ssh-tun-gateway:0.1.0
docker save -o ssh-tun-gateway-armv7.tar docker.io/killdns/ssh-tun-gateway:0.1.0
Build one architecture into the local Docker image store:
docker buildx build --platform linux/amd64 -t ssh-tun-gateway:amd64 --load .
docker buildx build --platform linux/arm64 -t ssh-tun-gateway:arm64 --load .
docker buildx build --platform linux/arm/v7 -t ssh-tun-gateway:armv7 --load .
Build all variants and push a multi-platform manifest:
docker buildx build \
--platform linux/amd64,linux/arm64,linux/arm/v7 \
-t docker.io/killdns/ssh-tun-gateway:0.1.0 --push .
The container is a network component with elevated privileges even though the SOCKS process runs as an unprivileged user. Read SECURITY.md before deployment. In particular:
AllowTcpForwarding no.This project is licensed under the MIT License. HevSocks5Server is also MIT-licensed; its license is copied into the container image.
Content type
Image
Digest
sha256:d780fbc6d…
Size
7.2 MB
Last updated
about 2 months ago
docker pull killdns/ssh-tun-gateway