I eagerly decided to try out WSL2 under the promise of massive I/O performance improvements (e.g. running git commands) and a more native Linux feel. This post goes through how I got set up with WSL2, and in particular how I solved network issues when using a VPN.
See this article by Microsoft for a comparison of WSL1 and WSL2.
There are various posts online with instructions for the initial setup of WSL2, e.g. https://www.omgubuntu.co.uk/how-to-install-wsl2-on-windows-10 - this part all went smoothly for me.
I’m using Ubuntu 20.04 (‘focal’). Note this comes with python3.8 and no python2. Below are the basic setup steps I went through to install packages I regularly use - these are personal to me, and this is mainly intended to serve as an example!
.bashrc
.screenrc
.inputrc
.profile
.gitconfig
sudo visudo
’<user> ALL=(ALL) NOPASSWD:ALL
’sudo apt-add-repository <repo>
’:
ppa:deadsnakes/ppa
- for Python packagessudo apt install <pkg>
’ (after ‘sudo apt update
’):
python3-pip python3-venv
- Python3.8 packagespython2.7 python2.7-dev
python3.5 python3.5-dev python3.5-venv
npm
- for web development stuffpkg-config
- needed for discovery of OpenSSLruby-full build-essential zlib1g-dev
- for Jekyll (GH pages)pip3 install --user pipx
pipx install virtualenv
pipx install ipython
pipx install black
pipx install isort
pipx install mypy
pipx install pylint
sudo npm install -g yarn
sudo npm install -g elm --unsafe-perm=true --allow-root
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
cargo install cargo-edit
gem install bundler
gem install jekyll
Everything worked fine for me at first, but once I connected to my work VPN (Cisco Anyconnect), WSL lost any network connectivity (unable to ping IP addresses).
After lots of searching online, I’ve managed to arrive at a somewhat-workable solution. It feels a bit hacky and unfortunately I haven’t managed to automate it fully, but at least I’m able to get things working. My solution is effectively the one given in this GitHub issue comment.
It seems the main issue here is that the VPN is setting itself as the highest priority in terms of getting network packets, meaning packets never reach WSL. The following commands can be run in Windows PowerShell (in admin mode) to correct this:
Get-NetIPInterface -InterfaceAlias "vEthernet (WSL)" | Set-NetIPInterface -InterfaceMetric 1
Get-NetAdapter | Where-Object {$_.InterfaceDescription -Match "Cisco AnyConnect"} | Set-NetIPInterface -InterfaceMetric 6000
After running the above, I found I was able to ping IP addresses from WSL, but DNS still wasn’t working. There’s a load more discussion online about this issue (and I’ve previously hit it in WSL1 too), but my solution is given below.
In WSL, edit /etc/resolve.conf
to point to the correct DNS server. By default it will point to an IP address it has for the Windows host, but when the VPN is running it should point to the VPN’s DNS server.
The correct DNS server IP address can be obtained by running ‘ipconfig /all
’ in Windows PowerShell (look for entry with “Cisco AnyConnect” in the description).
I managed to boil this down to an alias in WSL (after installing dos2unix
through apt
):
alias powershell='/mnt/c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe'
alias fixdns='powershell -Command "Get-DnsClientServerAddress -AddressFamily IPv4 | Select-Object -ExpandProperty ServerAddresses" | tac | sed "s/^/nameserver /" | dos2unix | sudo tee /etc/resolv.conf'
With this in place (e.g. in your .bashrc
), DNS can be fixed by running ‘fixdns
’ whenever things break (due to VPN going on/off).
I use wsltty
as my terminal for WSL (would recommend). For some reason it didn’t seem to want to start with WSL2, but installing a newer version seemed to fix it.
After doing this, I found that within screen
the mouse scroll wheel would map onto the up/down arrows, rather than scrolling in the terminal like it used to. To fix this, I needed this line in my .screenrc
(the glob star is important):
termcapinfo xterm* ti@:te@
When trying to use screen
I hit “Cannot make directory '/var/run/screen': Permission denied
”, which I fixed using this workaround.
DISPLAY
environment variable. I did this with:
export DISPLAY="$(cat /etc/resolv.conf | grep nameserver | awk '{print $2}' | head -n 1):0"
I also had to select the box in XLaunch to “Disable Server Access Control”.
Unfortunately I haven’t managed to get this working with VPN on - I’m unable to even ping the Windows host for some reason.
What’s more, the performance seems to be much worse than it was with WSL1, and in some cases simply insufficient.
jekyll serve
’ specifically), despite it working fine under WSL1… This is precisely the kind of thing I expected to get better with WSL2, not worse!I’m a bit disappointed with this transition to WSL2 not being more of a smooth ride. I think part of the problem is that I’ve got used to being able to treat Windows and WSL as running on the same machine, whereas WSL2 is more noticeably its own (virtual) machine.
The biggest issues for me are:
I may end up switching back to WSL1 because of these problems, but hopefully they will be addressed in WSL2 at some point!