[systemd-devel] Setting up a VPN daemon as a Portable Service

Duncan Gibson legowerewolf at gmail.com
Thu Oct 6 18:20:46 UTC 2022


Hi, everyone.

The high-level overview: I'm trying to install Tailscale
<https://tailscale.com/> as a portable service on my Steam Deck.

Tailscale is a point-to-point VPN service, essentially a wrapper around
Wireguard that helps with network setup and management. The Steam Deck is
Valve's handheld PC running SteamOS 3, which is derived from Arch. It uses
an A/B partition system for system files, meaning you can't install a
service the normal way.

There *is* a guide to do this <https://tailscale.com/blog/steam-deck/>,
posted on their own blog, but it uses system extensions which aren't good
for services that you want to run on startup. Indeed, following that guide
puts me in a state where I have to manually start the daemon every time I
reboot my Deck, even with the service enabled.

Let's move on to how I've started to do this.

Tailscale is available through most package managers, but they also
publish static
binaries with systemd unit files <https://pkgs.tailscale.com/stable/#static>.


This script grabs that binary, extracts it, and moves it into a portable
service directory structure.

# download and extract Tailscale
tarball="$(curl -s 'https://pkgs.tailscale.com/stable/?mode=json' | jq -r
.Tarballs.amd64)"
version="$(echo ${tarball} | cut -d_ -f2)"
tar_dir="$(echo ${tarball} | cut -d. -f1-3)"
curl -s "https://pkgs.tailscale.com/stable/${tarball}" -o tailscale.tgz
tar xzf tailscale.tgz
test -d $tar_dir

# Set up our target directory structure
mkdir -p
tailscaled/{usr/{bin,sbin,lib/systemd/system},etc,proc,sys,dev,run,/var/tmp}

# Copy tailscale-distributed files to the right place
cp -rf $tar_dir/tailscaled tailscaled/usr/sbin/tailscaled
cp -rf $tar_dir/systemd/tailscaled.service
tailscaled/usr/lib/systemd/system/tailscaled.service

# Write service os-release file
source /etc/os-release
cp -rf /etc/os-release tailscaled/etc/os-release

Not automated yet is patching the provided unit file - you need to remove
the EnvironmentFile line and "--port $PORT $FLAGS" options, and add
[Exec]
Environment="PATH=/usr/bin"

Attach the portable service: sudo portablectl attach ./tailscaled
--profile=trusted
and try starting it: sudo systemctl start tailscaled

It fails, leaving this in the logs:

logtail started
Program starting: v1.30.2-t24c524c78-gc399ae6fa, Go 1.19.1-tsb13188dd36:
[]string{"/usr/sbin/tailscaled",
"--state=/var/lib/tailscale/tailscaled.state",
"--socket=/run/tailscale/tailscaled.sock"}
LogID: 0f59ed267a2b19cc28aac9ee7119914000ca478234af8d56893a025ae72cc647
logpolicy: using $STATE_DIRECTORY, "/var/lib/tailscale"
wgengine.NewUserspaceEngine(tun "tailscale0") ...
wgengine.NewUserspaceEngine(tun "tailscale0") error: creating router: could
not get iptables version: fork/exec /usr/bin/iptables: no such file or
directory flushing log.
logger closing down
createEngine: creating router: could not get iptables version: fork/exec
/usr/bin/iptables: no such file or directory

iptables is, in fact, at /usr/bin/iptables, so what am I missing? Before I
added the Environment line, I was getting errors that iptables wasn't on
the PATH, so I suspect that now tailscaled can *see* iptables, but systemd
isn't letting tailscaled run it.

Thanks for having a look at this.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.freedesktop.org/archives/systemd-devel/attachments/20221006/fc19a342/attachment.htm>


More information about the systemd-devel mailing list