Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use gvisor-tap-vsock binaries directly #187

Merged
merged 16 commits into from
Mar 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
71 changes: 0 additions & 71 deletions .github/workflows/codeql-analysis.yml

This file was deleted.

2 changes: 1 addition & 1 deletion .github/workflows/distro.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:

- name: Build
run: |
docker build -t $TAG_NAME -f ./distro/Dockerfile --build-arg REF=$RUN_URL --build-arg VERSION=${GITHUB_REF#refs/tags/} .
docker build -t $TAG_NAME -f ./distro/alpine.dockerfile --build-arg REF=$RUN_URL --build-arg VERSION=${GITHUB_REF#refs/tags/} .

- uses: anchore/scan-action@v3
with:
Expand Down
28 changes: 0 additions & 28 deletions .github/workflows/go.yml

This file was deleted.

2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
wsl-vpnkit.tar.gz
wsl-gvproxy.exe
wsl-vm
149 changes: 88 additions & 61 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,41 +1,37 @@
# wsl-vpnkit

The `wsl-vpnkit` v0.3 script uses [gvisor-tap-vsock](https://github.com/containers/gvisor-tap-vsock) to provide network connectivity to the WSL 2 VM while connected to VPNs on the Windows host. This requires no settings changes or admin privileges on the Windows host.
The `wsl-vpnkit` v0.4 script uses [gvisor-tap-vsock](https://github.com/containers/gvisor-tap-vsock) to provide network connectivity to the WSL 2 VM while connected to VPNs on the Windows host. This requires no settings changes or admin privileges on the Windows host.

The releases bundle the script together with the binaries in an [Alpine](https://alpinelinux.org/) distro.

For v0.2, please see the [v0.2.x branch](https://github.com/sakai135/wsl-vpnkit/tree/v0.2.x).
For previous versions, see [v0.3](https://github.com/sakai135/wsl-vpnkit/tree/v0.3.x) and [v0.2](https://github.com/sakai135/wsl-vpnkit/tree/v0.2.x).

## Setup

Download the prebuilt file `wsl-vpnkit.tar.gz` from the [latest release](https://github.com/sakai135/wsl-vpnkit/releases/latest) and import the distro into WSL 2. Running the distro will show a short intro and exit.
Try the following troubleshooting steps from Microsoft first.

* [WSL has no network connection on my work machine or in an Enterpise environment](https://learn.microsoft.com/en-us/windows/wsl/troubleshooting#wsl-has-no-network-connection-on-my-work-machine-or-in-an-enterpise-environment)
* [WSL has no network connectivity once connected to a VPN](https://learn.microsoft.com/en-us/windows/wsl/troubleshooting#wsl-has-no-network-connectivity-once-connected-to-a-vpn)

If those steps do not resolve the issue, `wsl-vpnkit` should be able to provide network connectivity.

### Setup as a distro

#### Install

Download the prebuilt file `wsl-vpnkit.tar.gz` from the [latest release](https://github.com/sakai135/wsl-vpnkit/releases/latest) and import the distro into WSL 2.

```pwsh
# PowerShell

wsl --import wsl-vpnkit --version 2 $env:USERPROFILE\wsl-vpnkit wsl-vpnkit.tar.gz
wsl -d wsl-vpnkit
```

Start `wsl-vpnkit` from your other WSL 2 distros. Add the command to your `.profile` or `.bashrc` to start `wsl-vpnkit` when you open your WSL terminal.
Run `wsl-vpnkit`. This will run `wsl-vpnkit` in the foreground.

```sh
wsl.exe -d wsl-vpnkit --cd /app service wsl-vpnkit start
```

You can also check service status to start service only if needed.

```sh
wsl.exe -d wsl-vpnkit --cd /app service wsl-vpnkit status >/dev/null || \
wsl.exe -d wsl-vpnkit --cd /app service wsl-vpnkit start
wsl.exe -d wsl-vpnkit --cd /app wsl-vpnkit
```

### Notes

* Ports on the WSL 2 VM are accessible from the Windows host using `localhost`.
* Ports on the Windows host are accessible from WSL 2 using `host.internal`, `192.168.67.2` or [the IP address of the host machine](https://docs.microsoft.com/en-us/windows/wsl/networking#accessing-windows-networking-apps-from-linux-host-ip).

### Update
#### Update

To update, unregister the existing distro and import the new version.

Expand All @@ -46,92 +42,123 @@ wsl --unregister wsl-vpnkit
wsl --import wsl-vpnkit --version 2 $env:USERPROFILE\wsl-vpnkit wsl-vpnkit.tar.gz
```

### Uninstall
#### Uninstall

To uninstall, unregister the distro.

```pwsh
# PowerShell

wsl --unregister wsl-vpnkit
rm -r $env:USERPROFILE\wsl-vpnkit
```

### Build
### Setup as a standalone script

This will build and import the distro.
The `wsl-vpnkit` script can be used as a normal script in your existing distro. This is an example setup script for Ubuntu.

```sh
git clone https://github.com/sakai135/wsl-vpnkit.git
cd wsl-vpnkit/
./build.sh
./import.sh
./test.sh
# install dependencies
sudo apt-get install iproute2 iptables iputils-ping dnsutils wget

# download wsl-vpnkit and unpack
VERSION=v0.4.x
wget https://github.com/sakai135/wsl-vpnkit/releases/download/$VERSION/wsl-vpnkit.tar.gz
tar --strip-components=1 -xf wsl-vpnkit.tar.gz \
app/wsl-vpnkit \
app/wsl-gvproxy.exe \
app/wsl-vm \
app/wsl-vpnkit.service
rm wsl-vpnkit.tar.gz

# run the wsl-vpnkit script in the foreground
sudo VMEXEC_PATH=$(pwd)/wsl-vm GVPROXY_PATH=$(pwd)/wsl-gvproxy.exe ./wsl-vpnkit
```

Optionally you may build with `podman` instead of `docker` (default) by overriding environment variable `DOCKER`:
### Setup systemd

WSL versions 0.67.6 and later [support systemd](https://learn.microsoft.com/en-us/windows/wsl/wsl-config#systemd-support). Follow the instructions in the link to enable systemd support for your distro.

Create the service file and enable the service. Now `wsl-vpnkit.service` should start with your distro next time.

```sh
DOCKER=podman ./build.sh
# wsl-vpnkit setup as a distro
wsl.exe -d wsl-vpnkit --cd /app cat /app/wsl-vpnkit.service | sudo tee /etc/systemd/system/wsl-vpnkit.service

# copy and edit for wsl-vpnkit setup as a standalone script
sudo cp ./wsl-vpnkit.service /etc/systemd/system/
sudo nano /etc/systemd/system/wsl-vpnkit.service

# enable the service
sudo systemctl enable wsl-vpnkit

# start and check the status of the service
sudo systemctl start wsl-vpnkit
systemctl status wsl-vpnkit
```

## Using `wsl-vpnkit` as a standalone script
## Build

The `wsl-vpnkit` script can be used as a normal script in your existing distro. This is an example setup script for Ubuntu.

```sh
# download wsl-vpnkit
VERSION=v0.3.x
wget https://github.com/sakai135/wsl-vpnkit/releases/download/$VERSION/wsl-vpnkit.tar.gz
tar --strip-components=1 -xf wsl-vpnkit.tar.gz app/wsl-vpnkit files/wsl-gvproxy.exe files/wsl-vm
rm wsl-vpnkit.tar.gz
# build with alpine image to ./wsl-vpnkit.tar.gz
./build.sh alpine

# place Windows exe
USERPROFILE=$(wslpath "$(powershell.exe -c 'Write-Host -NoNewline $env:USERPROFILE')")
mkdir -p "$USERPROFILE/wsl-vpnkit"
mv wsl-gvproxy.exe "$USERPROFILE/wsl-vpnkit/wsl-gvproxy.exe"
# build with fedora using Podman
DOCKER=podman ./build.sh fedora

# place Linux bin
chmod +x wsl-vm
sudo chown root:root wsl-vm
sudo mv wsl-vm /usr/local/sbin/wsl-vm
# import the built distro from ./wsl-vpnkit.tar.gz
./import.sh

# run the wsl-vpnkit script
chmod +x wsl-vpnkit
sudo ./wsl-vpnkit
# run using the imported distro
wsl.exe -d wsl-vpnkit --cd /app wsl-vpnkit
```

## Troubleshooting

### Configure VS Code Remote WSL Extension
### Notes

If VS Code takes a long time to open your folder in WSL, [enable the setting "Connect Through Localhost"](https://github.com/microsoft/vscode-docs/blob/main/remote-release-notes/v1_54.md#fix-for-wsl-2-connection-issues-when-behind-a-proxy).
* Ports on the WSL 2 VM are [accessible from the Windows host using `localhost`](https://learn.microsoft.com/en-us/windows/wsl/networking#accessing-linux-networking-apps-from-windows-localhost).
* Ports on the Windows host are accessible from WSL 2 using `host.containers.internal`, `192.168.127.254` or [the IP address of the host machine](https://docs.microsoft.com/en-us/windows/wsl/networking#accessing-windows-networking-apps-from-linux-host-ip).

### Cannot connect to WSL 2 VM IP while connected to VPN
### Error messages from `wsl-vpnkit`

This is due to the VPN blocking connections to the WSL 2 VM network interface. Ports on the WSL 2 VM are accessible from the Windows host using `localhost`.
#### resolv.conf has been modified without setting generateResolvConf

For this and other networking considerations when using WSL 2, see [Accessing network applications with WSL](https://docs.microsoft.com/en-us/windows/wsl/networking).
`wsl-vpnkit` uses `/mnt/wsl/resolv.conf` to get the WSL 2 gateway IP. If modifying `/etc/resolv.conf` to set a custom DNS configuration, set [`generateResolvConf=false` in `wsl.conf`](https://learn.microsoft.com/en-us/windows/wsl/wsl-config#network-settings).

### Run in foreground
#### wsl-gvproxy.exe is not executable due to WSL interop settings or Windows permissions

`wsl-vpnkit` requires that the WSL 2 distro be able to run Windows executables. This [`interop` setting](https://learn.microsoft.com/en-us/windows/wsl/wsl-config#interop-settings) is enabled by default in WSL 2 and in the `wsl-vpnkit` distro.

Security configurations on the Windows host may prevent executables from running. You can copy `wsl-gvproxy.exe` to an appropriate location and use the `GVPROXY_PATH` environment variable to specify the location.

```sh
wsl.exe -d wsl-vpnkit --cd /app wsl-vpnkit
wsl.exe -d wsl-vpnkit --cd /app GVPROXY_PATH=/mnt/c/path/wsl-gvproxy.exe wsl-vpnkit
```

### Configuring proxies and certificates

`wsl-vpnkit` currently only handles creating a network connection. Proxies and certificates must be configured separately in your distro.

### Configure VS Code Remote WSL Extension

If VS Code takes a long time to open your folder in WSL, [enable the setting "Connect Through Localhost"](https://github.com/microsoft/vscode-docs/blob/main/remote-release-notes/v1_54.md#fix-for-wsl-2-connection-issues-when-behind-a-proxy).

### Try shutting down WSL 2 VM to reset

```pwsh
# PowerShell

# shutdown WSL to reset networking state
wsl --shutdown

# kill any straggler wsl-gvproxy processes
kill -Name wsl-gvproxy
```

### Run service with debug

If you set DEBUG variable before calling service you can see more debug information

Example:
```sh
wsl.exe -d wsl-vpnkit --cd /app DEBUG=1 service wsl-vpnkit restart
# set the DEBUG environment variable
wsl.exe -d wsl-vpnkit --cd /app DEBUG=1 wsl-vpnkit
```
3 changes: 2 additions & 1 deletion build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,14 @@
: "${DOCKER:=docker}" # docker/podman command (default: docker)
DUMP=wsl-vpnkit.tar.gz # exported rootfs file
TAG_NAME=wslvpnkit # build tag
BASE_DISTRO=$1

# build
build_args=()
[ -z "${http_proxy}" ] || build_args+=( --build-arg http_proxy="${http_proxy}" )
[ -z "${https_proxy}" ] || build_args+=( --build-arg https_proxy="${https_proxy}" )
[ -z "${no_proxy}" ] || build_args+=( --build-arg no_proxy="${no_proxy}" )
${DOCKER} build --network host "${build_args[@]}" --tag ${TAG_NAME} --file ./distro/Dockerfile .
${DOCKER} build --network host "${build_args[@]}" --tag ${TAG_NAME} --file ./distro/$BASE_DISTRO.dockerfile .
CONTAINER_ID=$(${DOCKER} create ${TAG_NAME})
${DOCKER} export "${CONTAINER_ID}" | gzip > ${DUMP}
${DOCKER} container rm "${CONTAINER_ID}"
Expand Down
Loading