…but still not with official sanction. By which I mean that it is a feature from the actual WSL team themselves, for WSL on Windows 11, versions 0.51.2 and above - but, well, in the words of Craig Loewen himself:
Hi folks! We ran an internal experiment to start investigating bridged networking mode in WSL as part of improving WSL's overall networking story. As always I'm impressed by this community since you've discovered this experimental, unreleased, and undocumented feature! As a reminder we didn't intend for users to find and start using this functionality, so please keep in mind that the functionality and experience for this feature can change. Thank you!
Having said that, for my fellow members of damn-the-torpedoes club, here’s my documentation on how to make this undocumented feature work. Thanks to xlr88888 on GitHub for originally finding the feature.
First, you need to create a bridged Hyper-V adapter, if you don’t already have one for virtual machine purposes. Documentation on how to do this is here, and please note that this requires that you have the Hyper-V feature installed on your machine (you want Windows 11 Pro) in order to be able to see Hyper-V Manager.
Make sure WSL is currently shut down, and then add these lines to your .wslconfig file:
[wsl2]
networkingMode = bridged
vmSwitch = Bridge
…substituting the name of the bridged adapter you created (or already had) for “Bridge”. When you next start up WSL, you’ll have bridged networking.
Further Notes
This is the minimum you have to do. Having done this, when I look at my eth0 configuration inside WSL, I see this:
7: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 5c:bb:f6:9e:ee:fa brd ff:ff:ff:ff:ff:ff
inet 172.16.1.4/16 brd 172.16.255.255 scope global eth0
valid_lft forever preferred_lft forever
i.e., I now have a single IPv4 address acquired via DHCP, on the same network - but not the same address - that my host is connected to. But there are a couple of things to note.
First, obviously, WSL now has its own address independent of the host, so if you were relying on WSL being able to use VPNs or other such networking trickery set up on the host, that’s not going to happen any more. Logically, it’s a separate network adapter - you’ll need to set up VPN access inside the WSL distribution, and manage it independently.
Second: while this is a DHCP address, you’ll note from the ip a output above that it doesn’t know that it’s a DHCP address. Since WSL distros don’t natively run networking daemons, WSL itself grabs a DHCP address and assigns it to the adapter before your distro starts up. As such, you can’t go mucking about with DHCP tools to renew it or change it inside WSL.
There also isn’t an IPv6 address, only IPv4, which may pain those of you who wanted bridged networking largely for IPv6.
But wait! There’s more!
There are four additional options you can set in the .wslconfig file: macAddress, dhcp, dhcpTimeout, and ipv6.
IPv6
I have not, sadly, yet been able to make ipv6 do anything useful. (More on this later.)
(Edit: with assistance from shigenobuokamoto on GitHub, I have found my error:
ipv6 = true
enables IPv6 in the kernel parameters, i.e.
net.ipv6.conf.all.disable_ipv6 = 0
where it would otherwise be disabled. This may not be apparent to you if you use systemd-networkd or similar for network configuration because it sets disable_ipv6 off for the interface, even while it remains on globally.
Anyway, turn it on when you want IPv6 to work.)
Other Options
As for the others, macAddress lets you set a fixed MAC address for the WSL adapter, which is useful if you want to set up a DHCP reservation for WSL on your PC and similar, while DHCP timeout… well, is exactly what it says on the tin.
dhcp, on the other hand, lets you turn off WSL’s own address assignment. Do by adding the line
dhcp = false
to your .wslconfig, then starting up your distro, you get this from ip a:
7: eth0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000
link/ether 5c:bb:f6:9e:ee:fa brd ff:ff:ff:ff:ff:ff
Which then lets you start with a blank slate in the instance and set the address yourself in the usual ways permitted by ip and ifconfig.
Fully Equipped Luxury Addressing
Which is where the regular setup comes in. Using a tool like genie or one of its equivalents, you can run systemd under WSL, along with all its services, including the distro’s standard set of networking daemons, which on a bridged adapter, can do everything they could do under native Linux.
For me, under Debian, that means systemd-networkd. I have a nice vanilla hybrid configuration in my wired.network, like so:
[Match]
Name=eth0
[Network]
Description=Virtual switch
DHCP=true
IPv6AcceptRA=true
MulticastDNS=true
LLDP=true
EmitLLDP=true
[DHCP]
CriticalConnection=true
RouteMetric=10
UseDomains=true
and thus the network configuration I end up with is this:
7: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 5c:bb:f6:9e:ee:fa brd ff:ff:ff:ff:ff:ff
inet 172.16.1.4/16 brd 172.16.255.255 scope global eth0
valid_lft forever preferred_lft forever
inet 172.16.1.16/16 metric 10 brd 172.16.255.255 scope global secondary eth0
valid_lft forever preferred_lft forever
inet6 fdc9:b01a:9d26:0:5ebb:f6ff:fe9e:eefa/64 scope global dynamic mngtmpaddr noprefixroute
valid_lft 3494sec preferred_lft 3494sec
inet6 2600:1700:6495:50f:5ebb:f6ff:fe9e:eefa/64 scope global dynamic mngtmpaddr noprefixroute
valid_lft 2591894sec preferred_lft 604694sec
inet6 fe80::5ebb:f6ff:fe9e:eefa/64 scope link
valid_lft forever preferred_lft forever
Behold, IPv6 addresses and all!
(You will note that in the above list are two IPv4 addresses. This is because I left WSL’s own DHCP service active by not setting “dhcp = false” in my .wslconfig, and so I get both the address WSL provides me - 172.16.1.4 - and the one systemd-networkd manages - 172.16.1.16. I’m leaving this in place because I also use a couple of distributions that I don’t use genie/systemd with, and not disabling WSL-DHCP means that they still get an address automatically.
Purists and those who only use one distro may wish to turn this off, in which case you will only see the systemd-networkd, or other network daemon assigned, IPv4 address.)
Hope you find this write-up useful, and more news when I have it!
Will this work on Windows 10?
Thanks you. I have a question. Why does the bridged network still use the MAC adapter on Win11 instead of the MAC address on WSL. Is it just simulating a bridged network?