As far as I can tell, this is a bug in WSL. Hopefully, Microsoft will fix it in the next build. But for now, we can use this slightly ugly hack.
Update #1: Definitely a bug. Found this issue on Github. Thier proposed workaround of relaunching the shell works for me as well if you don't want to go through all of this.
TL;DR Add this to END your SSH config (usually located at ~/.ssh/config
):
Host *
ProxyCommand nc %h %p %r
Here's why it works:
Our SSH issue is not a firewall issue because nc
and telnet
work to the same host and port (try telnet <host> <port>
or nc <host> <port>
: you should see something like SSH-2.0-OpenSSH_6.6.1p1 Ubuntu-2ubuntu2.7
). This we can use to our advantage.
SSH allows the use of proxies that take standard input and send it to the server's port via the ProxyCommand
option. This is normally used to tunnel into networks to a protected host by using an in-between bastion SSH server, sometimes called a jump host (see this link for more info).
This hack tells SSH to use a proxy with no jump host(s). So, it gets around SSH's failed allocation of TCP resources by pushing all of the network resource allocation onto Netcat, which does work. SSH just does its SSH thing without any network connections, and Netcat sends the raw data over a TCP connection to the SSH server.
WARNING: Since this modifies the ProxyCommand
for all hosts, I do not know how it interacts with other SSH config hosts that use ProxyCommand
. I have a few servers with which I can test this, and I will update this answer with the results. There is a chance that there are no detrimental side effects, but I cannot guarantee that.
Update #2: I did some testing with a few of my servers, and this appears to work. SSH uses the uppermost entry in the config when multiple entries apply. Thus, an existing ProxyCommand
present above this hack would override it. When the new SSH command is executed, it re-reads the SSH config, and if there is no other ProxyCommand
, SSH uses our hack ProxyCommand
, allowing it to only apply to the "outermost" SSH session. Word of warning: if you put the hack at the top of the config file (or above the entry you are trying to SSH to), SSH sessions that require a ProxyCommand
will ignore the other ProxyCommand
and instead attempt to resolve the address of the host and connect directly with Netcat.
Best Answer
This is definitely possible given your current setup. Note that you also have the option of using Putty but either way, you'll need to have an X server running on the client machine, your Windows Subsystem for Linux — WSL. The client-server model of the X window system is partially what makes X forwarding so easy to pull off. All you need is an X server running on host and client.
Raspberry Pi (Host) Configuration
First, you'll want to make a minor config adjustment to your SSH server on the host machine (your Raspberry Pi). First, find your sshd_config file within the etc directory. You can run these commands by ssh-ing into the Raspberry Pi (with a sudo-capable account), or accessing the Pi directly and then opening a terminal.
Once you're in, run the command:
Make a backup of your sshd config file:
Now open the original file in a text editor with:
You can choose any text editor you're comfortable with (see here for the nano text editor shortcuts). This is the main config file for the ssh server. Find and uncomment the following lines:
Save and exit. Now you'll need to restart your Pi's SSH server with:
Windows (Client) Setup
You're done with your host. Now all you need to do is install an X server for Windows. There are a few options to choose from but I would go with Cygwin X which you can download here. Install it and once you run it, it should spawn a little window on your client which will be used to display the X program. You can now test that X forwarding is happening by returning to your WSL shell and running the simple command:
A simple clock should appear in the window spawned by Cygwin. You can terminate the clock by returning to your WSL shell and hitting Ctrl+C. If this command isn't recognized, you may first need to install x11-graphics applications on the host machine with:
X forwarding should now be enabled for you and you can now run most if not all of your Raspberry Pi's applications from Windows.
Note on XDMCP, FreeNX
You may wish to take things a step further and set things up to run an entire desktop environment from your Pi rather than just app-by-app which is what X forwarding allows. Here are a couple common options available to you: