How to setup tailscale as a "vpn host" on my LAN

I run a small homelab, a docker server with a number of services that I use on my private LAN.

I’d like to extend that to my mobile devices when I’m out and about.

Previously I had this working with DDNS, portforwarding and wireguard, but this is not possible with my current ISP. I then had it working with Cloudflare Tunnels, but decided to abandon that due to how they MITM the connection.

It is my understading I can use tailscale to run a VPN host that I can then connect to from my mobile devices?

I’ve started a docker container with tailscape, and it seems to run - the log does not show any errors. I use a github auth_key, but https://login.tailscale.com/admin/machines does not show it as connected. What am I missing?

docker-compose.yml:

services:
  tailscale: 
    container_name: tailscale 
    hostname: tailscale-nas 
    image: tailscale/tailscale:stable 
    volumes: 
      - ./tailscale:/var/lib # State data will be stored in this directory 
      - /dev/net/tun:/dev/net/tun # Required for tailscale to work 
    network_mode: host
    cap_add: # Required for tailscale to work 
      - net_admin 
      - net_raw 
      - sys_module 
    environment:
      - TS_AUTH_KEY tskey-*redacted*
    command: tailscaled 
    privileged: true 
    restart: unless-stopped

Installing the tailscale app on my mobile device and logging in with the same github user, it does show on the admin page.

I’m on holidays and didn’t check your full compose, but you can Check my past post, might have something useful

https://www.reddit.com/r/Tailscale/comments/104y6nq/docker_tailscale_and_caddy_with_https_a_love_story/

Can you run “tailscale up” and post results?

I run it in docker so this is docker-compose logs, assume that’s ok?

tailscale  | 2023/02/03 09:36:00 logtail started
tailscale  | 2023/02/03 09:36:00 Program starting: v1.36.0-tab998de98, Go 1.19.4-tsdc0ce6324d: []string{"tailscaled"}
tailscale  | 2023/02/03 09:36:00 LogID: *redacted*
tailscale  | 2023/02/03 09:36:00 logpolicy: using system state directory "/var/lib/tailscale"
tailscale  | 2023/02/03 09:36:00 wgengine.NewUserspaceEngine(tun "tailscale0") ...
tailscale  | 2023/02/03 09:36:00 router: v6nat = true
tailscale  | 2023/02/03 09:36:00 dns: [rc=unknown ret=direct]
tailscale  | 2023/02/03 09:36:00 dns: using "direct" mode
tailscale  | 2023/02/03 09:36:00 dns: using *dns.directManager
tailscale  | 2023/02/03 09:36:00 link state: interfaces.State{defaultRoute=enx0050b6df31e7 ifs={br-0c9ca552955f:[192.168.192.1/20] br-158dd113eb6c:[172.19.0.1/16] br-2d1eb100bcf8:[172.21.0.1/16] br-452acbffd4cb:[192.168.112.1/20] br-54a67828c089:[192.168.64.1/20] br-59883da25732:[192.168.80.1/20] br-5dcd6a0859db:[172.23.0.1/16] br-7e2a272aef3b:[172.27.0.1/16] br-7f268b908fb3:[192.168.32.1/20] br-bdaecf6a722a:[172.24.0.1/16] br-bea15950828c:[192.168.144.1/20] br-d22b9f45608f:[192.168.160.1/20] br-de9c8c05d493:[192.168.224.1/20] br-e0a9464cd3eb:[172.22.0.1/16] br-e6b041c084f0:[192.168.16.1/20] docker0:[172.17.0.1/16] enx0050b6df31e7:[192.168.10.10/24]} v4=true v6=false}
tailscale  | 2023/02/03 09:36:00 magicsock: disco key = *redacted*
tailscale  | 2023/02/03 09:36:00 Creating WireGuard device...
tailscale  | 2023/02/03 09:36:00 Bringing WireGuard device up...
tailscale  | 2023/02/03 09:36:00 Bringing router up...
tailscale  | 2023/02/03 09:36:00 external route: up
tailscale  | 2023/02/03 09:36:00 Clearing router settings...
tailscale  | 2023/02/03 09:36:00 Starting link monitor...
tailscale  | 2023/02/03 09:36:00 Engine created.
tailscale  | 2023/02/03 09:36:00 pm: migrating "_daemon" profile to new format
tailscale  | 2023/02/03 09:36:00 got LocalBackend in 29ms
tailscale  | 2023/02/03 09:36:00 Start
tailscale  | 2023/02/03 09:36:00 Backend: logs: be:*redacted* fe:
tailscale  | 2023/02/03 09:36:00 Switching ipn state NoState -> NeedsLogin (WantRunning=false, nm=false)
tailscale  | 2023/02/03 09:36:00 blockEngineUpdates(true)
tailscale  | 2023/02/03 09:36:00 health("overall"): error: state=NeedsLogin, wantRunning=false
tailscale  | 2023/02/03 09:36:00 wgengine: Reconfig: configuring userspace WireGuard config (with 0/0 peers)
tailscale  | 2023/02/03 09:36:00 wgengine: Reconfig: configuring router
tailscale  | 2023/02/03 09:36:00 wgengine: Reconfig: configuring DNS
tailscale  | 2023/02/03 09:36:00 dns: Set: {DefaultResolvers:[] Routes:{} SearchDomains:[] Hosts:0}
tailscale  | 2023/02/03 09:36:00 dns: Resolvercfg: {Routes:{} Hosts:0 LocalDomains:[]}
tailscale  | 2023/02/03 09:36:00 dns: OScfg: {Nameservers:[] SearchDomains:[] MatchDomains:[] Hosts:[]}

“Error state needs login”. Looks like the docker version of tailscale needs to be signed into an account according to the logs.

Isn’t that what the TS_AUTH_KEY is supposed to do?

I’m not sure about that one but I also don’t see tailscale handing out IP addresses. Is the 172 network on your lan? How many subnets do you have.

174 is an rfc-1918 address handed out by docker networks. It routes to the 192.168 LAN.

I would double check the authentication because I’m not seeing the Tailscale lan interface that it builds out from the node. Do you have a secondary device running tailscale on the network?

I went to https://login.tailscale.com/admin/settings/keys and created an auth key, then used that with the TS_AUTH_KEY variable in the docker-compose.yml, but that didn’t work. The example showed the key starting tskey-, something, so I tried to add that, but still no cigar.

Actually the tailscale keys page calls it ID - I presume it means key - or am I looking the wrong place? This is really not very clear…

EDIT

Ok I just created a new key, and now it opened a new window with the actual key. I don’t know what happened first time but now I have a key. It still doesn’t work though. The key tskey-auth-kssSLE1CNTRL- followed by, I guess, the actual code. I presume I need to include the whole string? I tried both that and just the key part, but nothing turns up on the machine page. How long does it take to register?

It still says “needslogin” in the log though … do I need more than the key variable set?

LATER

After some more poking around, I saw a suggestion to run “docker exec tailscaled tailscale status” on the tailscale docker hub page. This said “logged out”. So I tried running “docker exec tailscaled tailscale up” with gave a notice to go to a URL to login, and after following this I finally got logged in.

This is very unusual for docker, normally you run your docker compose up, and then its up. Don’t see why I need to explicitly go to a website to login when the key is already in the docker-compose.yml, this is not best practice…

Anyway, it works. Thanks.

Thank you for that, your input helped me fix a similar issue running Tailscale as a Docker container on OpenMediaVault.

For some reason, it seems like the Tailscale container on that platform completely ignores all of the arguments passed through the “environment” section of the Docker Compose File so they have to be entered from the SSH shell.

On top of the commands you’ve already run, I also had to run these to make my node fully configured:

docker exec tailscaled tailscale up --advertise-routes=192.168.1.0/24

docker exec tailscaled tailscale up --advertise-exit-node

That fully configured the node and even shutting down and restarting the container retains the correct configuration.

Also, given the context, I assume running

docker exec tailscaled tailscale up --authkey tskey-abcdef1432341818

instead of just

docker exec tailscaled tailscale up

Would automate the login process and remove the need to use the URL to login.

I would double check step 1 in this kb article.

https://tailscale.com/kb/1085/auth-keys/

Both server and client are now listed on the machines page, but when I enable the client, it loses connection to the internet. “machine has no internet access”.