Page 1 of 1

Tailscale VPN Integration

Posted: Sat Aug 08, 2026 7:40 pm
by twolifestyles
So we got the binary loaded for Tailscale per support with Katherine.
However when starting the tailscaled daemon, it fails to locate or create a TUN device.

Can someone help me get this working?
The binary packages for tailscale are here.
https://pkgs.tailscale.com/stable/#static
Make sure to select the correct one. 386 is x86 legacy bios and AMD64 is UEFI.

Support then provided the following instructions to access it.


1. Create ts.zip file with tailscale and/or tailscaled files for needed
architecture.

2.1. For wtware network boot place ts.zip into "Everyone" TFTP folder
(by default wtware intalls into C:\ProgramData\WTware\Everyone).

2.2. For wtware local disk boot place ts.zip into config/ folder using
wtware terminal web interface.

3. Write into wtware config:

extra = telnetd, ts

4. Boot wtware.

5. From another computer run telnet to wtware terminal IP:

telnet <<thinclient IP>>

You should get telnet connection to wtware.

From there we need to make the proper directory and issue two commands to get connected.
First is to start the daemon and setup the tun device.
Then the second connects to the tailscale network.

mkdir -p /var/run/tailscale /var/lib/tailscale /dev/net
[ -c /dev/net/tun ] || mknod /dev/net/tun c 10 200

/tailscaled \
--state=/var/lib/tailscale/tailscaled.state \
--socket=/var/run/tailscale/tailscaled.sock \
--tun=tailscale0 \
--port=0 \
>/tmp/tailscaled.log 2>&1 &

sleep 3

/tailscale \
--socket=/var/run/tailscale/tailscaled.sock \
up \
--auth-key="$TSAUTHKEY" \
--hostname="$HOSTNAME" \
--accept-dns=false \
--accept-routes=true \
--netfilter-mode=off \
>/tmp/tailscale-up.log 2>&1

It fails starting tailscaled due to a missing tun device.

How can we get this working?

Re: Tailscale VPN Integration

Posted: Sun Aug 09, 2026 4:56 am
by twolifestyles
Had our dev team work on this. We figured out a hacky workaround.

WTWARE + TAILSCALE INTEGRATION
TECHNICAL FINDINGS AND WORKING IMPLEMENTATION
=============================================

Environment
-----------

WTware Version:
6.2.76/UEFI

Tailscale Version:
1.102.2 AMD64

Final Status:
Tailscale is working successfully on WTware over both Ethernet and Wi-Fi, survives reboots using persistent node state, supports RDP connectivity over Tailscale, and allows WTware TFTP configuration downloads over Tailscale.


=============================================
1. INITIAL ATTEMPT USING extra=
=============================================

The first attempt was to use WTware's existing:

extra=

functionality to add the Tailscale Linux binaries to the WTware environment.

The package contained:

tailscale
tailscaled

WTware accepted the extra package and eventually made the binaries available.

However, this did not allow Tailscale to be started early enough in the WTware startup process for the intended use.


=============================================
2. DETERMINED THAT extra= LOADS TOO LATE
=============================================

After observing the WTware boot sequence, we determined that files supplied through:

extra=

are processed relatively late during startup.

By the time the extra package was unpacked and the Tailscale binaries became available, WTware had already completed several earlier stages of the boot process.

For this implementation, Tailscale needed to be available much earlier.

Therefore the standard:

extra=

mechanism was not suitable for loading Tailscale.


=============================================
3. DETERMINED THAT FIRMWARE FILES LOAD BEFORE NETWORKING
=============================================

We then investigated which WTware files are processed earlier during boot.

We determined that WTware firmware packages are extracted extremely early in the boot sequence.

Firmware extraction occurs before the normal networking startup process.

An existing WTware firmware archive being used by the test system was:

WTFW_iwlwifi-9000-pu-b0-jf-b0-46.ucode.zip

The archive normally contained the Intel Wi-Fi firmware:

iwlwifi-9000-pu-b0-jf-b0-46.ucode

Because WTware extracts this archive very early, it provided a possible method of making the Tailscale binaries available before networking begins.


=============================================
4. SUCCESSFULLY LOADED TAILSCALE THROUGH THE FIRMWARE ARCHIVE
=============================================

The Linux AMD64 Tailscale binaries were added directly to the existing firmware ZIP.

The resulting archive contained:

iwlwifi-9000-pu-b0-jf-b0-46.ucode
tailscale
tailscaled

WTware successfully extracted all of these files during the normal firmware-loading process.

The Tailscale binaries appeared as:

/lib/firmware/tailscale
/lib/firmware/tailscaled

The WTware log confirmed that both additional files were extracted.

This successfully made Tailscale available very early in the WTware boot process.


=============================================
5. TAILSCALE WOULD NOT START BECAUSE A TUN DEVICE WAS NOT AVAILABLE
=============================================

With the Tailscale binaries now available early enough, we attempted to start:

tailscaled

tailscaled requires Linux TUN support in order to create:

tailscale0

At this stage, a usable TUN device was not available.

The standard Linux method of creating:

/dev/net/tun

would normally use:

mknod /dev/net/tun c 10 200

However, WTware's early environment does not provide the mknod command.

Attempting:

mknod

returned:

/bin/sh: mknod: not found

BusyBox also did not provide the mknod applet.

Therefore Tailscale could not create its tunnel interface using the normal method.


=============================================
6. modprobe DID NOT PROVIDE TUN SUPPORT
=============================================

We then attempted to manually enable TUN support using:

modprobe tun

The early WTware environment did not provide a usable TUN kernel module through this method.

The initial result indicated that the normal tun module was not available as a loadable module.

At this point:

tailscale

and:

tailscaled

were both successfully available in the filesystem, but Tailscale could not start because the required TUN support was still unavailable.


=============================================
7. RESEARCH FOUND THAT ENABLING OPENVPN MAKES TUN SUPPORT AVAILABLE
=============================================

Research into WTware behavior and forum discussions showed that enabling WTware's OpenVPN functionality causes TUN support to become available.

Testing confirmed this behavior.

When WTware starts OpenVPN, the startup process successfully initializes TUN support and creates:

tun0

The WTware log showed the TUN driver becoming available during this process.

This provided a way to bootstrap the TUN functionality required by Tailscale.


=============================================
8. BOOTSTRAPPED TAILSCALE FROM OPENVPN
=============================================

OpenVPN was configured so that once its TUN interface was created, its:

up

hook started Tailscale.

The sequence became:

WTware starts OpenVPN



TUN support becomes available



OpenVPN creates tun0



OpenVPN "up" hook executes



/lib/firmware/tailscaled starts



tailscaled creates tailscale0



/lib/firmware/tailscale up runs

Tailscale now started correctly and was able to create:

tailscale0

This successfully solved the TUN problem.


=============================================
9. WTWARE DISPLAYED OPENVPN FAILED
=============================================

Although Tailscale was now starting correctly, WTware still expected OpenVPN itself to complete an actual VPN connection.

The OpenVPN instance was only being used to make TUN support available.

There was no remote OpenVPN server for it to connect to.

As a result, WTware eventually displayed:

ERROR: OpenVPN failed.

When WTware considered the OpenVPN connection failed, it would not continue normally into the next startup stage where the RDP client is launched.

Tailscale itself was operational, but WTware's OpenVPN success check still had to be satisfied.


=============================================
10. CREATED AN INTERNAL OPENVPN NETWORK ON 127.0.0.1
=============================================

To satisfy WTware's requirement that OpenVPN complete a connection, a second OpenVPN instance was created locally on the same WTware machine.

The two OpenVPN instances communicate entirely through:

127.0.0.1

The configuration uses:

Primary OpenVPN:

127.0.0.1:1194

Local OpenVPN peer:

127.0.0.1:1195

Dummy point-to-point addresses:

tun0 = 198.18.0.1
tun1 = 198.18.0.2

The connection is therefore completely internal:

OpenVPN #1
127.0.0.1:1194



127.0.0.1



OpenVPN #2
127.0.0.1:1195

No actual remote network traffic passes through this OpenVPN connection.

Its only purpose is to allow OpenVPN to reach a successful connected state so WTware will continue booting.

With the localhost OpenVPN peer in place:

OpenVPN successfully connects



WTware considers OpenVPN successful



Tailscale connects successfully



WTware continues normally



RDP becomes available

The actual remote network connection is provided by:

tailscale0

This configuration worked successfully.


=============================================
11. REBOOTED AND TAILSCALE NO LONGER CONNECTED
=============================================

After confirming that the complete configuration worked, the WTware system was rebooted.

On the first boot, Tailscale had connected successfully.

After rebooting, Tailscale no longer connected.

The rest of the WTware startup process still operated, but the Tailscale node did not return online.


=============================================
12. CHECKED THE TAILSCALE LOG USING TELNET
=============================================

WTware Telnet access was used to inspect:

/tmp/tailscale-up.log

The log showed that Tailscale was attempting to authenticate the machine again.

Example:

Warning: netfilter=off; configure iptables yourself.
backend error: invalid key: API key ... not valid

A newly generated Tailscale authentication key worked successfully on the first boot.

After rebooting, the same error returned.

This showed that Tailscale was behaving as though the WTware machine were a new node after every reboot.


=============================================
13. DETERMINED THAT TAILSCALE STATE WAS NOT BEING SAVED PERSISTENTLY
=============================================

The Tailscale daemon had originally been started with:

--state=/var/lib/tailscale/tailscaled.state

The state file stores the identity of the registered Tailscale node.

WTware's runtime filesystem is recreated during boot.

Therefore:

/var/lib/tailscale/tailscaled.state

did not survive a reboot.

The result was:

First boot



Tailscale authenticates



tailscaled.state is created



Node works


Reboot



tailscaled.state is gone



Tailscale has no existing node identity



Tailscale attempts authentication again

The WTware USB drive is available at:

/bootmedia

and provides persistent storage.

However, WTware mounts:

/bootmedia

read-only by default.

The mount showed:

/dev/sda1 on /bootmedia type vfat (ro,...)

Therefore Tailscale could not initially store its persistent state on the USB drive.


=============================================
14. CHANGED /bootmedia TO READ/WRITE
=============================================

We tested remounting the WTware USB filesystem as read/write using:

mount -o remount,rw /bootmedia

This worked successfully.

After the remount:

mount | grep bootmedia

showed:

/dev/sda1 on /bootmedia type vfat (rw,...)

Write access was confirmed using:

echo test > /bootmedia/configs/tailscale-write-test

and:

cat /bootmedia/configs/tailscale-write-test

which successfully returned:

test

The test file could also be removed successfully.

The Tailscale state location was then changed to:

/bootmedia/configs/tailscaled.state

tailscaled is now started using:

--state=/bootmedia/configs/tailscaled.state

The startup process first performs:

mount -o remount,rw /bootmedia

and then starts Tailscale using the persistent state location.

The startup logic also checks whether the state file already exists.

If no state exists, the Tailscale auth key is used for initial registration.

If the state file already exists, the existing node identity is loaded and the auth key is not submitted again.


=============================================
15. TAILSCALE STATE NOW SURVIVES REBOOTS
=============================================

With:

tailscaled.state

stored at:

/bootmedia/configs/tailscaled.state

the WTware machine now retains its Tailscale node identity.

After reboot:

/bootmedia is remounted read/write



existing tailscaled.state is found



tailscaled loads the existing node identity



no new authentication is required



the same Tailscale node reconnects

Tailscale now survives WTware reboots successfully.


=============================================
16. TESTED SUCCESSFULLY ON ETHERNET AND WI-FI
=============================================

The completed implementation was tested using both:

Ethernet

and:

Wi-Fi

Both network types work correctly.

The final interface layout is:

eth0
Physical Ethernet or Wi-Fi connection

tun0
Primary local OpenVPN interface
198.18.0.1

tun1
Local OpenVPN peer
198.18.0.2

tailscale0
Actual Tailscale network interface

Tailscale successfully receives a normal:

100.x.x.x

address and appears in the Tailscale administration console.

RDP connectivity through the Tailscale network works correctly.


=============================================
17. TFTP CONFIGURATION DOWNLOAD ALSO WORKS OVER TAILSCALE
=============================================

WTware TFTP configuration retrieval also works successfully through the Tailscale network.

A WTware server can be specified using its Tailscale address, for example:

tftpIP=100.x.x.x

The WTware server must have the Tailscale network interface enabled as an available interface in its interface settings.

Once the Tailscale interface is enabled on the WTware server:

WTware terminal boots



Tailscale connects



WTware reaches the server through its Tailscale IP



TFTP configuration download works normally

This was tested successfully.


=============================================
FINAL WORKING BOOT SEQUENCE
=============================================

The final implementation operates as follows:

WTware boots



Firmware archive is extracted



/lib/firmware/tailscale
/lib/firmware/tailscaled
become available



Ethernet or Wi-Fi initializes



WTware starts OpenVPN



TUN support becomes available



tun0 is created



OpenVPN "up" hook executes



/bootmedia is remounted read/write



Persistent Tailscale state is checked



Local OpenVPN peer starts on 127.0.0.1



tun1 is created



Primary OpenVPN connects to local peer



WTware sees a successful OpenVPN connection



tailscaled starts



tailscale0 is created



Existing Tailscale state is loaded
or first-time authentication occurs



Tailscale connects



Node state remains stored on USB



WTware continues normally



TFTP configuration retrieval works over Tailscale



RDP connectivity works over Tailscale


=============================================
FINAL RESULT
=============================================

The completed Tailscale integration is working successfully with WTware 6.2.76/UEFI.

Confirmed working:

Tailscale binaries load during early boot.

TUN support is bootstrapped through WTware OpenVPN.

tailscale0 is created successfully.

A localhost OpenVPN peer satisfies WTware's OpenVPN connection requirement.

WTware proceeds normally into the RDP stage.

Tailscale node state persists across reboots.

The same Tailscale node reconnects without reauthentication.

Ethernet works.

Wi-Fi works.

RDP over Tailscale works.

TFTP configuration download over Tailscale works.

For TFTP operation, the WTware server must have its Tailscale interface enabled in the server's interface settings.