Tailscale on FreeBSD - TUN interface lacks IP binding, requires manual ifconfig after every tailscale up

Environment:
  • FreeBSD 15.0-RELEASE-p5 (amd64)
  • Tailscale 1.96.4 (from pkg)
  • Using Tailscale as exit node
Problem Description:When starting Tailscale via tailscale up, the tailscale0 TUN interface comes up and routing works (exit node functions, I can reach the internet through it), but the interface lacks an IP address binding in the kernel:

Code:
# After tailscale up
root@freebased:~ # ifconfig tailscale0
tailscale0: flags=1008043<UP,BROADCAST,RUNNING,MULTICAST,LOWER_UP> metric 0 mtu 1280
        options=4080000<LINKSTATE,MEXTPG>
        groups: tun
        nd6 options=101<PERFORMNUD,NO_DAD>
        Opened by PID 90646
# Notice: no "inet 100.x.x.x" line

This causes services listening on *:22 (sshd) to not respond to connections via Tailscale, resulting in "Connection timeout" and netstat -s showing "dropped due to no socket" despite packets arriving on the interface.

Workaround:Manually binding the IP works:
Code:
ifconfig tailscale0 inet $(tailscale ip -4)/32 alias
But this must be run after every tailscale up (and tailscale down &amp;&amp; tailscale up cycle).

What I've Tried:

1. devd
- Created /etc/devd/tailscale.conf:
Code:
notify 100 {
        match "system"          "IFNET";
        match "subsystem"       "tailscale0";
        match "type"            "LINK_UP";
        action "/sbin/ifconfig tailscale0 inet $(/usr/local/bin/tailscale ip -4 2>/dev/null)/32 alias 2>/dev/null";
}
  • Also tried tailscale0, RENAME, UP, and no subsystem filter
  • devd -d shows config parses successfully but no events fire when Tailscale brings interface up/down:
2. rc.d poststart - Modified /usr/local/etc/rc.d/tailscaled:
  • Added IP binding logic to tailscaled_poststart()
  • Only works at daemon startup (service tailscaled start)
  • Does NOT run when user runs tailscale up (since daemon is already running)

3. Verified:
  • net.inet.ip.forwarding=1 is set
  • No firewall (PF/IPFW/IPF disabled)
  • TCP Wrappers allows all
  • sockstat shows sshd on *:22

dmesg output showing interface lifecycle:

Code:
tun0: link state changed to UP
tun0: changing name to 'tailscale0'
tailscale0: promiscuous mode enabled
tailscale0: promiscuous mode disabled
tailscale0: link state changed to DOWN
tun0: link state changed to UP
tun0: changing name to 'tailscale0'


Question:
Is there a proper way to hook into tailscale up completion or the TUN interface creation to automate this IP binding? Or is this a bug in how Tailscale handles TUN devices on FreeBSD?

Or am I just not knowledgeable enough of devd: https://wiki.freebsd.org/Devd ?
 
Back
Top