Tailscale update / fetch control key not possible due to DNS redirect


my network admins made a DNS block for tailscale. Using MagicDNS I usually would not care, however, in the update process to 1.40 I saw that I can’t reach tailscale.com (my admins just DNS-redirect to a “security issue” page, and I can download the file with the legacyPublicKey):

not logged in, last login error=fetch control key: Get “https://controlplane.tailscale.com/key?v=61”: x509: certificate signed by unknown authority

During an update, I am forced to use the internal DNS. On machines where I am root, I can of course just modify, e.g., /etc/hosts but what can I do on a machine where I have userspace networking? I could imagine giving the control key server as IP or similar as parameter, …, or copy the control key manually to a location. But I would not know how to do this (is the downloaded file stored as a file somewhere?) Can anyone help?

I solved it myself, using linux namespaces, unshare, socat, and slirp. The following does not require root at all, and will allow userspace networing with tailscale on a DNS-blocked machine (specifically I need to unblock controlplane.tailscale.com). All necessary executables (socat, slirp4nets, tailscale{d}) are available without the need to install them as root. This will allow updating, but I will show how these tools can be used in a Linux world to get tailscale running again, how to connect to the DNS-blocked machine via ssh, and how to use it as exit node.

Let’s get started:

On the DNS-blocked machine (host), I create a namespace (namespace):

(host) unshare --user --map-root-user --net --mount
(namespace)$ echo $$ > /tmp/pid

I start slirp4netns on the host
(host) slirp4netns --configure --mtu=65520 --disable-host-loopback $(cat /tmp/pid) tap0

I copy the complete /etc dir (I think only /etc/hosts is relevant) to a directory, create a “run” dir for the namespace (/run is necessary, otherwise the tailscale status will say “/run/xtables.lock: Permission denied”)

(host) copy -r /etc /tmp
(host) mkdir /tmp/run

Now bind-mount the following in the namespace :

(namespace) mount --bind /tmp/etc /etc
(namespace) mount --bind /tmp/run /run

Now the crucial change: add to /etc/hosts the following (or whatever IP you get with an nslookup on an unblocked machine for the controlplane): controlplane.tailscale.com

Now listen on port 8822 for ssh connection in the new namespace (where tailscale will be started), use socat to give the connection to a socket
(namespace) socat TCP-LISTEN:8822,fork UNIX:/tmp/socat.sock

on the host a connection via the socket is given to TCP 22 (sshd)
(host) socat UNIX-LISTEN:/tmp/socat.sock,fork tcp:

In the namespace I start tailscaled:
(namespace) $HOME/bin/tailscaled --state --tun=userspace-networking --socks5-server=localhost:1081 --socket=$HOME/tailscaled.sock

and bring up tailscale:
$HOME/bin/tailscale --socket=$HOME/tailscaled.sock up --reset

Now from any machine on the tailscale network I can connect via
ssh -p 8822 100.X.X.X

to the DNS-blocked host.

In the namespace, I also allow forwarding, such that I can use the machine as exit node, too (I was surprised that that worked as non-root [or: root in namespace only], but it indeed does, that’s quite nice). The following assumes of course --advertise-exit-node.

(namespace) echo "1" > /proc/sys/net/ipv4/ip_forward
(namespace) echo "1" > /proc/sys/net/ipv6/conf/all/forwarding

Cool. That was fun to solve.


1 Like

I don’t have an immediate use for it, but it’s always refreshing when someone shares how they resolved a problem.
Kudos, and thank you kind ser! :beers: