Tailscale for illumos

Current status: Up to date with Tailscale 1.24.2. My SMF manifest and build script are checked in to my branch. I've added notes on how to set up an exit node.

NOTE: This page is probably still a work in progress. I'm slowly working on upstreaming the necessary changes in small bits of spare time as I find them. If others have time/interest to help, I'd certainly appreciate it!

June 2022

Someone asked on Twitter and while my response was enough for them:

my ipnat.conf contains "map net0 100.64.0.0/10 -> 0/32" and "svc:/network/ipfilter:default" and "svc:/network/ipv4-forwarding:default" should be online.

... I should probably spell out the details for others.

So, notes on running an ipv4 exit node as demonstrated in a SmartOS zone:

json payload for vmadm:

{
  "alias": "exitnode-illumos",
  "hostname": "exitnode-illumos",
  "brand": "joyent",
  "max_physical_memory": 256,
  "quota": 10,
  "image_uuid": "39f99738-9a4c-11ec-8e1c-3b65b9abc26a",
  "resolvers": ["8.8.8.8","8.8.4.4"],
  "nics": [
    {
      "nic_tag": "admin",
      "ips": ["dhcp"]
    }
  ]
}

Preparatory steps to run inside the zone to setup NAT and forwarding:

echo "map net0 100.64.0.0/10 -> 0/32" > /etc/ipf/ipnat.conf
svcadm enable ipfilter
svcadm enable ipv4-forwarding

Obtain tailscale, tailscaled, and tailscale.xml and put them into place (make sure the binaries are marked executable):

cp ./tailscale{,d} /usr/local/sbin/
svccfg import tailscale.xml
mkdir -p /var/lib/tailscale
svcadm enable tailscale
tailscale up --advertise-exit-node

Authenticate the machine and mark it as allowed to be an exit node in the admin console (give it a nice ACL tag if you're feeling fancy.)

Note, the current branch has a build.sh script that you can run anywhere you have a golang toolchain (it assumes the build system is GOARCH=amd64 so if that's not the case on your build system, modify it accordingly) or as always, hit me up on IRC or DM me on Twitter and I can provide the link to my binaries.

July 2021

Work on wireguard-go has been paused. I've been working on getting Event Ports support into x/sys/unix. The code for that seems to be complete but is blocked on landing until the release of Go 1.17. See CR324630
After that lands, I can finish cleaning up my work adding Event Ports to fsnotify, though that project isn't looking very active which has me a little nervous. See fsnotify#371
Hopefully I'll find some time to pick up wireguard-go again soon, but in the meantime, last week I did a quick cleanup and rebase of my Tailscale branch. It is now based on Tailscale 1.10.1 and today I even checked in my current SMF manifests for reference: https://github.com/nshalman/tailscale/tree/illumos-1.10.1
I have been doing my builds with go 1.16.5 natively in a SmartOS zone, but because my fork of wireguard-go no longer uses cgo, it should be possible to cross compile binaries using a go 1.16.5 toolchain anywhere.
Rough instructions for a non-global zone (not fully tested; if you test or have changes let me know so that I can fix them and remove this note):

git clone https://github.com/nshalman/tailscale -b illumos-1.10.1
cd tailscale
GOOS=illumos go build ./cmd/tailscaled
GOOS=illumos go build ./cmd/tailscale
sudo cp ./tailscale{,d} /usr/local/sbin/
sudo svccfg import ./cmd/tailscaled/tailscale.xml
sudo mkdir -p /var/lib/tailscale
sudo svcadm enable tailscale
sudo tailscale up

Thanks to @richlowe for the nudge for this update. If anyone would like binaries, let me know and I'll post some and link them here.

March 2021

Alpha grade binaries of Tailscale 1.6 for illumos:
https://www.shalman.org/files/tailscale-v1.6-illumos-alpha/tailscale
https://www.shalman.org/files/tailscale-v1.6-illumos-alpha/tailscaled

There's progress in getting lots of the syscall and ioctl bits into golang's x/sys/unix and that should pave the way for a simplified patch against wireguard-go which should eventually be good enough to be upstreamed. I've rebased and rebuilt a bunch of my changes on top of Tailscale 1.6.0 and even ipv6 support seems to work. More to come.

Original Post (August 2020)

Background reading:

A while back, Josh Clulow did an initial port of wireguard-go to illumos. I was able to make some small modifications to it sufficient to get it to point the Tailscale client code at it and build tailscale binaries for illumos. Here's how to build them yourself:

You'll need git and a Go toolchain. I tested in a SmartOS zone using go114-1.14.4 and that seems to work. In the future we'll need Go 1.15.

<install git and a go toolchain>
git clone https://github.com/nshalman/wireguard-go -b tailscale-illumos wireguard-go
git clone https://github.com/nshalman/tailscale -b illumos tailscale
cd tailscale
sed -e "s|/home/admin/wireguard-go|$(cd ../wireguard-go ; pwd)|" -i go.mod
GOOS=illumos go build tailscale.com/cmd/tailscale
GOOS=illumos go build tailscale.com/cmd/tailscaled

As of the time of writing, my initial pull request to get the wireguard-go bits upstreamed is waiting on a combination of cleanups, and hopefully some additional functionality being added to x/sys/unix. Once that's done, a cleanup of my fork of tailscale to be ready for upstreaming will hopefully follow (the feature request where it's being tracked is here).

Since you shouldn't trust random people on the internet, you should probably review the code and build it yourself, however, if you know and trust me, I've uploaded binaries and my SMF manifest which you can download and experiment with (the version strings in the binaries are patched so that you know you got them from me):

To use them, drop the binaries into /usr/local/sbin, mkdir /etc/tailscale import them manifest (svccfg import tailscale.xml), start the daemon svcadm enable tailscale, then run tailscale up (I'm assuming you've already set up your Tailscale account, etc.)

Help is welcome and I intend to update this page as the work makes progress. Last updated August 31,2020. Feel free to troll me on Twitter if this note is still here and it's 2021. :)

On a related note, if you only need Wireguard and not Tailscale, you should also check out Mike Zeller's illumos port of boringtun which is a rust implementation. I think I managed to get it working, but stopped experimenting with it when Tailscale came out...