The Year of Linux on the (Windows) Desktop
or: Setting up a CLAT on Windows 10, with the help of Linux
Background and Motivation
A Client Layer for Address Translation (CLAT) is a software component that allows IPv4-only applications to more or less fully function on IPv6-only networks. It works by converting IPv4 packets to IPv6 packets on the client device, this is primarily useful for keeping the network's routing tables from growing too much during the transition to IPv6. IPv6-mostly builds on this to allow IPv4-only devices to also use the network: devices with a CLAT can negotiate IPv6-only operation, while devices without one can negotiate a private IPv4.[1]
Microsoft has said they plan on providing a CLAT on Windows 11[2], but those plans have yet to materialize. Furthermore, there are no indications of any current plans to provide a CLAT on Windows 10. As such, Windows devices currently cannot operate in IPv6-only mode on these networks. Nevertheless, after watching the talk on the deployment of IPv6-mostly at Imperial College London[1], we felt motivated to at least attempt to set up our own idea of a CLAT, on Windows 10.
Software and Setup
For this experiment, we used Windows 10 Home, version 22H2, build 19045.5247, as this is the Windows we have access to. The experiment was done in a VM for convenience, but the VM was directly attached to a real IPv6-only network. We also used the following software that we were able to download without IPv4 connectivity:
- QEMU[3], version 9.1.91 (2024-11-24).[4]
- OpenWRT[5], version 23.05.5 (x86-64, generic, ext4-combined-efi).[6]
And we also used the following, but this time we had to use IPv4 connectivity to download it, then transfer it into Windows some other way:
- OpenVPN Tap Adapter (part of OpenVPN[7], version 2.6.12).[8]
We then proceeded to run the installers.
Installation
The QEMU install was the most straightforward, we only tweaked the "System emulation" component since nearly all system emulators are unnecessary for our goals. We deselected "System emulation", then proceeded to select "x86_64" under it.
On the other hand, OpenVPN was a little trickier. We chose "Customize", and deselected every component under "OpenVPN", leaving only "OpenVPN" itself and all the "Drivers" selected. While only "TAP-Windows6" should be necessary, we found out that the tool to manage tap devices is only available under "OpenVPN".
With everything installed, it was time to set things up.
Setting up tap adapters
To set up tap adapters we ran the tapctl.exe
tool provided with OpenVPN to create a new tap adapter. OpenVPN sets up a single tap
adapter when you run the installer, so only one more was necessary. We opened a "Command Prompt (Admin)" by right-clicking the "Start" button on the
taskbar, then ran cd "\Program Files\OpenVPN\bin"
to change directory and tapctl.exe create
to create the tap adapter.
Now that we have the tap adapters, we have to rename and configure them. We right-clicked "Start", selected "Network Connections", then selected "Change adapter options". We picked one of the "TAP-Windows Adapter V9" devices, renamed it "clatd", and bridged it with our main connection. We picked the other, renamed it "ipv4", selected "Properties", and disabled IPv6 (as it's not necessary).
Setting up QEMU and OpenWRT
At this point, all we needed to do was set up a QEMU VM and configure OpenWRT. We opened PowerShell in the QEMU install directory, then launched
QEMU with the command .\qemu-system-x86_64.exe -m 128 -drive 'file=C:\Users\SoniEx2\Downloads\openwrt-23.05.5-x86-64-generic-ext4-combined-efi.img,id=disk,format=raw'
-netdev tap,ifname=clatd,id=clatd -device virtio-net,netdev=clatd,mac=52:54:98:76:54:32 -netdev tap,ifname=ipv4,id=ipv4 -device
virtio-net,netdev=ipv4,mac=52:54:98:76:54:33 -rtc base=utc -smp 2
, with the MAC addresses chosen to not conflict with other MAC
addresses. This command runs a VM with 128MB of RAM, a given disk image, the tap devices we configured earlier, and a specific real-time clock and
virtual CPU configuration.
Unfortunately, we quickly realized things weren't working correctly.
Issues and Workarounds
QEMU for Windows is not as stable as QEMU for Linux.[9] As it turns out, QEMU does not handle tap devices correctly on Windows. To put it simple, QEMU for Windows uses a global (static) variable to refer to the selected tap device, and attempting to select multiple tap devices will overwrite the variable. (At the time of writing, this has not been reported on the QEMU issue tracker.)
This didn't take long to debug. However, we opted not to try and fix it, due to the complexities involved in compiling on Windows. Thankfully, we were able to find a workaround: QEMU supports linking multiple VMs together to form a virtual network, via network sockets. While it is a bit ridiculous to use an entire Linux VM as a glorified virtual Ethernet switch... that's exactly what we ended up doing, because it works.
So we unpacked a new copy of OpenWRT, renamed to openwrt-bridge.img
, ran it: .\qemu-system-x86_64.exe -m 128 -drive
'file=C:\Users\SoniEx2\Downloads\openwrt-bridge.img,id=disk,format=raw' -netdev socket,listen=127.0.0.1:1234,id=ipv4 -device
virtio-net,netdev=ipv4,mac=52:54:98:76:54:33 -netdev tap,ifname=clatd,id=clatd -device virtio-net,netdev=clatd,mac=52:54:98:76:54:32 -rtc
base=utc -smp 2
, and started configuring it. This command sets up a network tap device and a socket device in listen mode.
We opened the VM's console, logged in, and edited /etc/config/network
. The goal here is to set up a bridge between eth0
and eth1
and not much else. The default config contains a section config device
which sets up a bridge. After list ports
'eth0'
, we added list ports 'eth1'
. Since we don't want this VM attempting to configure IP addresses on the
real network, we removed sections config interface 'lan'
, config interface 'wan'
, and config interface 'wan6'
altoghether, and then added the following section:
For some reason this is required to make OpenWRT configure the bridge. We then rebooted the VM, and that's the bridge configured.
Now we moved to configuring the VM for the CLAT. Starting over, we unpacked OpenWRT to openwrt-clat.img
and ran a similar command
to launch it: .\qemu-system-x86_64.exe -m 128 -drive 'file=C:\Users\SoniEx2\Downloads\openwrt-clat.img,id=disk,format=raw'
-netdev tap,ifname=ipv4,id=ipv4 -device virtio-net,netdev=ipv4,mac=52:54:98:76:54:35 -netdev socket,connect=127.0.0.1:1234,id=clatd -device
virtio-net,netdev=clatd,mac=52:54:98:76:54:34 -rtc base=utc -smp 2
. In this case, the socket device is set to connect to the bridge.
Before doing anything else, we need to rename the interfaces in OpenWRT, as it'll name them eth0
and eth1
at random. This
wasn't an issue for the bridge, where the interfaces are interchangeable, but it will be an issue here as we need one of the interfaces to talk IPv4
while the other talks IPv6.
For renaming the interfaces, we used a script found on the OpenWRT wiki[10], which we typed manually into /etc/hotplug.d/iface/00-dev-rename
.
However, rather than using the uci
commands provided, we did our own thing. In /etc/config/network
, we ended up with:
The first two sections are OpenWRT defaults. Some things worth highlighting are the use of option ipv6 0
on the LAN interface, to avoid
assigning extra IPv6 addresses to Windows, and option reqprefix 'no'
on the WAN interface - our IPv6-only network is SLAAC-based so there's
no need to request a prefix here, this may be different for other deployments.
At this point, we powered off the VM, and started it back up. We did not reboot the VM, as we wanted to make sure Windows would notice the network changes. But we aren't done yet, as we still need to install the CLAT.
Success
Once the VM finished booting, we now had internet connectivity. We then ran opkg update && opkg install 464xlat
to install the CLAT, and
rebooted the VM one more time so that it would pick it up. And that's all there is to it!
We then opened the browser, typed github.com
(at the time of writing, an infamously IPv4-only website) into the address bar, and it just worked!
Conclusion and Future Work
We are very happy to have a CLAT on Windows at all. However, there is more work that needs to be done before this can be widely deployed.
Packaging
The most obvious issue with this approach is the packaging. Our goal was to show a working proof of concept, not build a fully packaged solution. Indeed, this is the main "future work" that needs to be addressed: turning this into a self-contained package. Additionally, it would be very useful to set it up as a system service rather than manually starting it, and we haven't done any work towards that, either.
Security Considerations
The worst issue with this approach is that so long as QEMU has the bug with tap adapters, we have to use a network socket between two VMs, and anything could connect to said socket and start injecting packets onto the network. Meanwhile, the tap adapters themselves can be restricted such that an app needs admin privileges to access them. So, another "future work" item would be fixing QEMU's tap support on Windows.
Optimization
These VMs are currently set up with 128MB of RAM. This is way too much, and a little work could bring that down a lot. We would expect it to be possible to bring this down to 16 or 32MB fairly easily. For example, these VMs still have LuCI running, among other things. We chose OpenWRT because it's lightweight and has an officially supported CLAT, even if it needs to be installed as an additional package.
Limitations
As we briefly mentioned, this setup does require a Windows network bridge. You can only have one of those, so that could be an issue. We don't have enough Windows networking experience to comment any further on this point, tho.
References
- Stockdale, David (2024-11-19). IPv6-Mostly at Imperial. UK IPv6 Council Annual Meeting. Retrieved 2024-12-29.
- tojens (2024-03-07). Windows 11 Plans to Expand CLAT Support. Microsoft Networking Blog. Retrieved 2024-12-29.
- QEMU. QEMU. Retrieved 2024-12-29.
- Weil, Stefan (2024-11-24). QEMU for Windows - Installers. Retrieved 2024-12-11.
- OpenWRT. OpenWRT. Retrieved 2024-12-29.
- OpenWRT (2024-09-24). QEMU for Windows - Installers. Retrieved 2024-12-11.
- OpenVPN. OpenVPN. Retrieved 2024-12-29.
- OpenVPN (2024-07-18). OpenVPN Community Downloads. Retrieved 2024-12-10.
- QEMU. Hosts/W32. QEMU Wiki. Retrieved 2024-12-29.
- OpenWRT. Hotplug - Rename interfaces by MAC address. OpenWRT Wiki. Retrieved 2024-12-29.