Install Tailscale on Steam Deck without root

Install Tailscale on Steam Deck without root

Make sure you have a password set for deck, because the install script will need sudo to suid root the tailscaled binary.

  • Create folder tailscale in home directory of deck user
    mkdir -p ~/tailscale
  • Make install script executable
    chmod +x ~/tailscale/tailscale-install-user.sh
  • Run install script
    ./tailscale/tailscale-install-user.sh
  • Run ./tailscale/tailscale up as elsewhere documented

[tailscale-install-user.sh]

#!/usr/bin/env bash

set -euo pipefail

dir="$(mktemp -d)"
pushd .
cd "${dir}"

tarball="$(curl 'https://pkgs.tailscale.com/stable/?mode=json' | jq -r .Tarballs.amd64)"
version="$(echo ${tarball} | cut -d_ -f2)"

curl "https://pkgs.tailscale.com/stable/${tarball}" -o tailscale.tgz

tar xzf tailscale.tgz

mkdir -p ~/tailscale
cp -av tailscale_*/tailscale ~/tailscale
sudo cp -av tailscale_*/tailscaled ~/tailscale
cp -av ~/tailscale/tailscaled.env ~/tailscale/tailscaled.env.backup || true
cp -av tailscale_*/systemd/tailscaled.defaults ~/tailscale/tailscaled.env
cp -av ~/tailscale/tailscaled.service ~/.config/systemd/user

sudo chown root:deck ~/tailscale/tailscaled
sudo chmod u+s ~/tailscale/tailscaled

systemctl --user daemon-reload
systemctl --user enable tailscaled
systemctl --user start tailscaled

[tailscaled.service]

[Unit]
Description=Tailscale node agent
Documentation=https://tailscale.com/kb/
Wants=network-pre.target
After=network-pre.target NetworkManager.service systemd-resolved.service

[Service]
EnvironmentFile=/home/deck/tailscale/tailscaled.env
ExecStartPre=/home/deck/tailscale/tailscaled --cleanup
ExecStart=/home/deck/tailscale/tailscaled --tun=userspace-networking --port=${PORT} $FLAGS
ExecStopPost=/home/deck/tailscale/tailscaled --cleanup

Restart=on-failure
Type=notify

[Install]
WantedBy=default.target

Caveats

This will run tailscaled as user, so no changes to the SteamOS system partitions are necessary. The daemon will not be able to create a tun device, routes, or firewall rules, though. Access from Deck to VPN is only possible using a local SOCKS proxy. It is possible, however, to access the Deck via SSH through the VPN (which is sufficient in my case).

Additional Information

Install Tailscale on Steam Deck ft. SquashFS & systemd-sysext

#!/usr/bin/env bash
#  reference:              
#   → https://tailscale.com/blog/steam-deck
#
# -----------------------------------------------------------------------------

set -euo pipefail

ext_dir="$HOME/.local/extensions"
dir="$(mktemp -d)"
pushd .
cd "${dir}"

tarball="$(curl 'https://pkgs.tailscale.com/stable/?mode=json' | jq -r .Tarballs.amd64)"
version="$(echo ${tarball} | cut -d_ -f2)"

curl "https://pkgs.tailscale.com/stable/${tarball}" -o tailscale.tgz

mkdir -p tailscale/usr/{bin,sbin,lib/{systemd/system,extension-release.d}}
tar xzf tailscale.tgz

cp -vrf "tailscale_${version}_amd64"/tailscale tailscale/usr/bin/tailscale
cp -vrf "tailscale_${version}_amd64"/tailscaled tailscale/usr/sbin/tailscaled
cp -vrf "tailscale_${version}_amd64"/systemd/tailscaled.service tailscale/usr/lib/systemd/system/tailscaled.service

sed -i 's/--port.*//g' tailscale/usr/lib/systemd/system/tailscaled.service

source /etc/os-release
echo -e "SYSEXT_LEVEL=1.0\nID=steamos\nVERSION_ID=${VERSION_ID}" >> tailscale/usr/lib/extension-release.d/extension-release.tailscale

if [ ! -h "/var/lib/extensions" ]; then
  mkdir -p "$ext_dir"
  sudo ln -fsv "$ext_dir" /var/lib/extensions
fi

sudo rm -fv "$ext_dir/tailscale.raw"
mksquashfs tailscale "$ext_dir/tailscale.raw"

if [ ! -f "/etc/default/tailscaled" ]; then
  mkdir -p /etc/default
  sudo touch /etc/default/tailscaled
fi

popd
rm -rf "${dir}"

sudo systemctl enable --now systemd-sysext
sudo systemd-sysext merge || sudo systemd-sysext refresh

sudo systemctl daemon-reload
sudo systemctl restart tailscaled.service
sudo tailscale up --operator=deck --qr --ssh --accept-dns=false