
Tailscale Container
2 minute read
Tailscale and container
There is this page on Tailscale website explaining how to use Tailscale within a Docker container. It shows you how to build the docker container, authenticate and serve any number of containers to your tailnet. But there was something I wanted this did not cover, how to do it in reverse: expose apps (served over TCP/UDP) from your tailnet to the host or to another container.
Solution
There is my solution for this:
services:
tailscale-container:
image: tailscale/tailscale:latest
hostname: tailscale-container
environment:
- TS_AUTHKEY=tskey-auth-xxxxxx
- TS_STATE_DIR=/var/lib/tailscale
- TS_SOCKS5_SERVER=:10055
volumes:
- tailscale-data:/var/lib/tailscale
# optionally expose services to host or to anyone
# ports:
# - 127.0.0.1:10022:10022/tcp
# - 10022:10022/tcp
devices:
- /dev/net/tun:/dev/net/tun
cap_add:
- net_admin
- sys_module
restart: unless-stopped
ssh-to-node2:
image: ghcr.io/gareins/socat5docker:main
environment:
- SOCAT_CMD=TCP-LISTEN:10022,fork SOCKS5:tailscale-container:100.0.0.2:22,socks5port=10055
depends_on:
- tailscale-container
network_mode: service:tailscale-container
snmp-to-node3
image: ghcr.io/gareins/socat5docker:main
environment:
- SOCAT_CMD=UDP-LISTEN:10161,fork SOCKS5:tailscale-container:100.0.0.3:161,socks5port=10055
depends_on:
- tailscale-container
network_mode: service:tailscale-container
volumes:
tailscale-data:
driver: local
Now just connect any container to the network of this stack. So for example lets say the name of this network is tailscale-container_default
. Do this to compose file to connect:
...
networks:
- tailscale-container_default
...
networks:
tailscale-container_default:
external: true
```
Now you can ssh to the node2 using ssh user@tailscale-container -p 10022
How does this work though
There are some details for this implementation:
- Tailscale container presents a socks5 proxy with which you can use to connect to any node on the tailscale network. In contrast to SOCKS4, version 5 allows us to connect to UDP ports and we take advantage of that on our snmp-to-node3 container.
- Socat is a program that is described as a multiporpose relay and in the case of ssh-to-node2 listens on a TCP/10022 port and relays any traffic there to node2’s TCP/22.
- Socat by default does not provide socks5 support, so this implementation uses runsisi’s fork, it builds it with the help of andrew-d’s static build scripts and then I build a docker image that accepts the
SOCAT_CMD
environmental variable. - This solution does not care about the number of tailscale connected containers, so you can connect as many as you need.