Headscale - OpenBSD

Page content

Running Headscale Server on OpenBSD

i like and widely use wireguard for my infrastructure. i’m also aware of it’s limitation and i know the tailscale project but never gave try. recently, i stumbled upon the headscale project, an opensource alternative to for the (closed) tailscale server. perfect, let’s give a try!

and, of course, i’m gooing to implement this with OpenBSD, what else ;)

Doku

on the Server

compile and install server

this is working on OpenBSD 7.1, and also on the upcomming Version 7.2

doas su -
pkg_add gmake go

cd ~
git clone https://github.com/juanfont/headscale.git

cd headscale
latestTag=$(git describe --tags $(git rev-list --tags --max-count=1))
git checkout $latestTag

time gmake build

chmod a+x headscale
cp headscale /usr/local/sbin

config

mkdir -p /etc/headscale
mkdir -p /var/lib/headscale
cp config-example.yaml /etc/headscale/config.yaml

touch /var/lib/headscale/db.sqlite
touch /etc/headscale/config.yaml

-> edit the config.yaml and update at least the server_url: http://192.168.1.1:8080

create and start service

cat << 'EOF' >> /etc/rc.d/headscale
#!/bin/ksh

daemon="/usr/local/sbin/headscale"
daemon_logger="daemon.info"
daemon_user="root"
daemon_flags="serve"
daemon_timeout=60

. /etc/rc.d/rc.subr

rc_bg=YES
rc_reload=NO

rc_cmd $1
EOF

# make executable
chmod a+x /etc/rc.d/headscale

# enable and start service
rcctl enable headscale
rcctl restart headscale

create namespace

headscale namespaces create myfirstnamespace

on the Client(s)

install tailscale

doas pkg_add tailscale

enable and start service

rcctl enable tailscaled
rcctl restart tailscaled

Connect to Server

the Server IP/Port must be reachable of course!

tailscale up --login-server http://192.168.1.1:8080
To authenticate, visit:

  http://192.168.1.1:8080/register/8fedxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Open URL

in your browser

http://192.168.1.1:8080/register/8fedxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

… and you get …

Machine registration
Run the command below in the headscale server to add this machine to your network:

headscale -n NAMESPACE nodes register --key 8fedxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

-> copy value, and replace NAMESPACE with myfirstnamespace. this seems to be an error in the current version

paste the line on the server terminal

List Nodes

root@server # headscale -n myfirstnamespace nodes register --key 8fedxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Machine register

root@server # headscale nodes list
ID | Hostname | Name _          | NodeKey | Namespace        | IP addresses                  | Ephemeral | Last seen           | Online | Expired
1  | puffy1   | puffy1-0yngxgh7 | [j+32a] | myfirstnamespace | 100.64.0.1, fd7a:115c:a1e0::1 | false     | 2022-09-21 20:16:54 | online | no

repeat this with another client …

… and you get this …

List Nodes

root@server # headscale nodes list
ID | Hostname | Name            | NodeKey | Namespace        | IP addresses                  | Ephemeral | Last seen           | Online | Expired
1  | puffy1   | puffy1-0yngxgh7 | [j+32a] | myfirstnamespace | 100.64.0.1, fd7a:115c:a1e0::1 | false     | 2022-09-21 20:20:54 | online | no
2  | puffy2   | puffy2-dcrguyov | [V5kND] | myfirstnamespace | 100.64.0.2, fd7a:115c:a1e0::2 | false     | 2022-09-21 20:20:26 | online | no

Tun Interface

and what do we get ? a Tunnelinterface “tun0” which is connected to each other. on the local network, this does not make much sense. but what about if the maschines are distributed over the internet ?

puffy1

root@puffy1 # ifconfig tun0
tun0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1280
  index 6 priority 0 llprio 3
  groups: tun
  status: active
  inet 100.64.0.1 --> 0.0.0.0 netmask 0xffffffff
  inet6 fe80::250:56ff:fe9f:daf9%tun0 -->  prefixlen 64 scopeid 0x6
  inet6 fd7a:115c:a1e0::1 -->  prefixlen 48

puffy2

root@puffy2 # ifconfig tun0
tun0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1280
  index 7 priority 0 llprio 3
  groups: tun
  status: active
  inet 100.64.0.2 --> 0.0.0.0 netmask 0xffffffff
  inet6 fe80::250:56ff:fe9f:c699%tun0 -->  prefixlen 64 scopeid 0x7
  inet6 fd7a:115c:a1e0::2 -->  prefixlen 48

connectifity checks

check icmp

root@puffy1 # ping 100.64.0.2
PING 100.64.0.2 (100.64.0.2): 56 data bytes
64 bytes from 100.64.0.2: icmp_seq=0 ttl=255 time=3.464 ms
64 bytes from 100.64.0.2: icmp_seq=1 ttl=255 time=2.431 ms

check icmp6

root@puffy1 # ping6 fd7a:115c:a1e0::2
PING fd7a:115c:a1e0::2 (fd7a:115c:a1e0::2): 56 data bytes
64 bytes from fd7a:115c:a1e0::2: icmp_seq=0 hlim=64 time=2.863 ms
64 bytes from fd7a:115c:a1e0::2: icmp_seq=1 hlim=64 time=1.858 ms

check ssh

root@puffy1 # ssh 100.64.0.2 "hostname"
puffy2

root@puffy1 # ssh fd7a:115c:a1e0::2 "hostname"
puffy2

cool stuff …!

sha256: 297791098a04b8fa685955c106b8f8fc0a7d8ec363e8e59a90452aeb66eeaed3