Make Windows private-only port available for WSL2

2021-04-20
wsl

Background

For security consideration, we always make services only receive inbound connections from private network and block connections from public network using Windows Firewall.

Sometime when using WSL2, we need to connect to windows addresses (connecting to a proxy, access a service, etc). But unfortunately, WSL2’s network interface is set as public to Windows host due to security reasons, so we cannot directly connect to them.

The Issue#4619 WSL 2 cannot access windows service via localhost:port from 1.5 years ago has received nearly 100 comments by now, but seems Microsoft is not going to fix it.

Solution

We will add several scripts to enable or disable public access of some ports, so we can toggle them as wish.

  1. Add firewall rule for your port

    • Add a firewall rule, name it as PublicPort for example
    • Enable port, application or what ever you need
    • Set scope to Public

    And now we can enable or disable it with powershell command (you need confirm the administrator requirement)

    # Enable
    function Enable-WSLAccess {
        Start-Process -FilePath powershell.exe -ArgumentList {
            Enable-NetFirewallRule -DisplayName PublicPort
        } -verb RunAs
    }
    
    # Disable
    function Disable-WSLAccess {
        Start-Process -FilePath powershell.exe -ArgumentList {
            Disable-NetFirewallRule -DisplayName PublicPort
        } -verb RunAs
    }
    
  2. Setup functions in bashrc

    alias portup="powershell.exe -Command \"Enable-WSLAccess\""
    alias portdown="powershell.exe -Command \"Disable-WSLAccess\""
    

And now, you can toggle the port availability by Enable-WSLAccess/Disable-WSLAccess in Windows powershell or by portup/portdown in WSL2 shell.

Addition

We may also need Windows' ip address, this can be retrieved by:

cat /etc/resolv.conf | grep nameserver | tail -1 | awk '{print $NF}'