X11 Port Forwarding Using Windows SSH Client

puttysshwindowsxmingxorg

I use PuTTY's X11 port forwarding option to connect my PC to my Raspberry Pi and run X11 apps, but I can't figure out how to do the same thing using Windows Terminal. Apparently, X11 requires more than just forwarding the remote port 6000 to the PC, but I have no idea what.

I used this command line to connect:

ssh -R 6000:localhost:6000 [email protected]

I also tried adding ForwardX11 yes to my local .ssh\config with similar results.

I can run X11 apps only as long as I have an active PuTTY session in parallel. When I terminate the PuTTY session I start getting

Error: Can't open display: localhost:10.0

sudo netstat -tlp shows that port 6000 is open on the remote machine:

Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
...
tcp        0      0 localhost:x11           0.0.0.0:*               LISTEN      881524/sshd: pi@pts
...

What do I have to do to enable X11 in Windows' native SSH client?

Best Answer

ForwardX11 and ForwardX11Trusted (the -X and -Y options) are the OpenSSH equivalent to PuTTY's "Enable X11 forwarding".

(ForwardX11Trusted or -Y is actually the closest – it gives unrestricted access to the X11 server, whereas ForwardX11 or -X restricts the clients from accessing the clipboard or seeing your local windows.)

You might have to manually tell Win32-OpenSSH about where your X11 display is (i.e. it doesn't automatically try to guess "localhost:0"). To do that, set the DISPLAY environment variable before making the SSH connection, e.g. in PowerShell:

PS>  $env:DISPLAY = "localhost:0"
PS>  ssh -Y raspi

(The syntax for environment variables depends on your local shell.) The terminal that you're using (whether it's Windows Terminal or MinTTY or something else) isn't important at all.

Apparently X11 requires more than just forwarding the remote port 6000 to the PC

The "X11 forwarding" option is not a "port forwarding" option – they're different both in client/server behavior and even at protocol level.

For example, X11 requires each client to supply authentication data – most commonly a static key ("magic cookie") that clients read from their ~/.Xauthority file. The SSH client has to forward this authentication data to the SSH server, so that remote clients would be permitted to connect.

Also, the port might not necessarily be 6000 – that's the port for display <HOST>:0 specifically, but if the local display is e.g. at <HOST>:1 then the port would be 6001, etc. The "X11 forwarding" feature makes the SSH client automatically look at your local $DISPLAY to figure out where the X11 server is (which is how normal X11 apps work as well), whereas the SSH server has to provide $DISPLAY to remote apps.

(Of course, there might not even be a TCP port – - X11 often uses other socket types besides TCP; most X11 servers on Linux use UNIX sockets and never enable TCP at all, and this won't always be the same on the SSH client and server side either. A display address of localhost:0 goes over TCP, but a bare :0 does not – on Linux it would indicate a UNIX socket.)

Because of this, the X11 forwarding feature doesn't use SSH's "TCP tunnel" facility at all, it has a whole separate kind of tunnel specifically for X11.

I can run X11 apps only as long as I have an active PuTTY session in parallel. When I terminate the PuTTY session I start getting

Error: Can't open display: localhost:10.0

This sounds like you're manually copying $DISPLAY from one session to another, or using a tty multiplexer like tmux or Screen to access one session's tty from another (carrying over the $DISPLAY). Don't do that.

Each connection that enables "X11 forwarding" will allocate a new display address on the SSH server's side – for example, your initial PuTTY session might create display :10 while your second OpenSSH session might create :11, even though they both are forwarded to the same display on your local machine (and which is probably neither ":10" nor ":11" but :0).

So for example, when you connect to the SSH server via OpenSSH, it automatically sets $DISPLAY to the X11 display address that'll go through that specific OpenSSH-based connection. Your X11 apps don't care about which tty they're running in – they only care about the $DISPLAY.

But if your $DISPLAY is set to the display address assigned to the original PuTTY session, all X11 access will of course go through that PuTTY session, completely independent of what terminal you're running the X11 apps from.

Related Question