Skip to content
Advertisement

Remote PHP Debugging from within WSL2 in Visual Studio Code

I’m running Windows 10, with a WSL2 Ubuntu instance. I do my development within the WSL2 instance with the “Remote – WSL” extension of Visual Studio Code. So my VSC is running as a WSL2 application, not as a Windows application. I have an additional remote server (I’ll refer to this as “Server X” which actually hosts/runs the PHP code. This remote server does not support the use of the “Remote – WSL” extension, so I use an “SFTP” extension to push my changes to this server. And I cannot run the code locally (in either Windows or WSL2) due to the database connection being unsupported.

I’m trying to configure remote debugging of the code on Server X from within VSC running as a WSL2 application (IE: using the “Remote – WSL” extension). The intent is to listen for a browser request to initiate the debug session.

What’s happening is when I turn on “Listen for Remote Connection” in VSC when running as a WSL2 application, it doesn’t detect the browser when I refresh it. I’ve determined the reason is because while running as a WSL2 application, my IP is different than when I’m outside WSL (which is where I’m refreshing the browser). So in short, I’m initiating a browser session outside of WSL (IP: 192.168.1.2), the remote server attempts to connect to a debugger at 192.168.1.2:9003, but doesn’t find one because my VSC is listening on 192.168.1.3:9003 while it’s running as a WSL2 application.

I’ve confirmed if I instead run VSC as a Windows application (IE: not using Remote – WSL extension on WSL2 instance) everything works fine after adjusting some setting paths to point to Windows PHP rather than WSL2 PHP.

I’ve been trying to play around with using SSH tunnels to re-route my port 443 traffic from Windows through WSL, but have been unsuccessful so far.

Has anyone run into this issue and have any idea how to get around it? Or is what I’m trying to do unsupported/discouraged?

Advertisement

Answer

So WSL runs under the 172.16. 0.0/12 private address range and is not directly accessible by anything external to the host Windows machine. As such, populating xdebug.client_host with this IP, will not work.

My initial idea of using port forwarding was correct, but not in the direction I thought. Instead of redirecting the outgoing web traffic (443 since my site is using SSL) from Windows through WSL, then redirect from WSL to Server X. I instead just needed to redirect the incoming xdebug traffic (9003) from Windows to WSL. (Probably what @Derick was alluding to)

To do this, I left xdebug configured as it normally would have been if WSL wasn’t in the picture.

So:

zend_extension=xdebug
xdebug.mode=profile,debug
xdebug.idekey=<ide key value here>
xdebug.client_host=<ip of windows host, as backup>
xdebug.start_with_request=trigger
xdebug.trigger_value=<my trigger value>
xdebug.discover_client_host = 1

Then, using the following PowerShell script on the Windows host to redirect port 9003 from the Windows host to the WSL guest:

If (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) {   
  $arguments = "& '" + $myinvocation.mycommand.definition + "'"
  Start-Process powershell -Verb runAs -ArgumentList $arguments
  Break
}

$remoteport = bash.exe -c "ifconfig eth0 | grep 'inet '"
$found = $remoteport -match 'd{1,3}.d{1,3}.d{1,3}.d{1,3}';

if ($found) {
  $remoteport = $matches[0];
}
else {
  Write-Output "IP address could not be found";
  exit;
}

$ports = @(9003);

for ($i = 0; $i -lt $ports.length; $i++) {
  $port = $ports[$i];
  Invoke-Expression "netsh interface portproxy delete v4tov4 listenport=$port";
  Invoke-Expression "netsh advfirewall firewall delete rule name=$port";

  Invoke-Expression "netsh interface portproxy add v4tov4 listenport=$port connectport=$port connectaddress=$remoteport";
  Invoke-Expression "netsh advfirewall firewall add rule name=$port dir=in action=allow protocol=TCP localport=$port";
}

Invoke-Expression "netsh interface portproxy show v4tov4";

Above script is modified from the script found here:(https://dev.to/vishnumohanrk/wsl-port-forwarding-2e22) Which itself is modified from here: (https://github.com/microsoft/WSL/issues/4150#issuecomment-504209723)

Note*: You have to install net-tools in the WSL guest in order for the above script to work, so: sudo apt install net-tools.

User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement