X11 Forwarding is very useful when you want to run GUI based applications on a remote machine. I needed it to run IntelliJ IDE on HPC. But while X11 forwarding can be easily enabled using the -X (or -Y) option of ssh, it doesn't work if xauth is not installed on the remote server - in my case the HPC compute nodes. In this case, ssh can be used to create a reverse tunnel from the remote server to the local machine. X11Forwarding can then be done by setting the display on the remote server as the entry port of the tunnel and making the X-server listen on the exit port of the tunnel in the local machine.
Here I'll describe how I went about creating a SSH reverse tunnel from HPC compute nodes to my local machine and used that to enable X11 Forwarding. As a prerequisite, I assume that a Display Manager that launches the X-server is installed on the local machine. Popular ones are XQuartz for macOS and XMing for Windows.
-
Enable X11 forwarding on local machine.
- Add this to /private/etc/ssh/sshd_config:
X11Forwarding yes ForwardX11 yes
- Restart sshd.
- Add this to /private/etc/ssh/sshd_config:
-
Run display manager (eg. XQuartz) on local machine.
-
Make XOrg-X11 listen to incoming connections on TCP 6000.
- For this "-no-listen" needs to be removed from its arguments. Since XOrg is launched from display manager, how to do this depends on the display manager.
- For macOS with XQuartz, go to Preferences > Security and check Allow connections from network clients.
- For Ubuntu with lightdm display manager, add the following to /etc/lightdm/lightdm.conf and reboot.
xserver-allow-tcp=true xserver-command=X -listen tcp
- Restart sshd.
- Make sure X11 is listening on TCP 6000 port.
$ netstat -na | grep LISTEN
- For this "-no-listen" needs to be removed from its arguments. Since XOrg is launched from display manager, how to do this depends on the display manager.
-
SSH to HPC cluster normally.
$ ssh <user>@<hpc_hostname>
-
Submit job to get compute nodes normally. Eg.
$ qsub -I -P cc -N test -lselect=2:ncpus=24
Note the hostname of the compute nodes assigned. Eg. cn036.
-
Open a new terminal and setup the reverse tunnel as described in the remaining steps.
- SSH to HPC cluster with a reverse tunnnel.
This will setup TCP Port 6020 on login node to forward incoming connections to TCP Port 6000 on local machine.
$ ssh -R 6020:localhost:6000 <user>@<hpc_hostname>
- Now ssh to the compute nodes that were assigned to the job.
This will setup TCP Port 6020 on compute node to forward incoming connections to TCP Port 6020 on login node. We now have a reverse tunnel from the compute node's port 6020 to local machine's port 6000. The choice of the TCP port will be explained in the next step.
$ ssh -R 6020:localhost:6020 <user>@<compute_node_hostname>
- SSH to HPC cluster with a reverse tunnnel.
-
TCP port is 6000+display_number, so 6000 is display 0, 6001 is display 1 and so on. When client sees something like "DISPLAY=xserver:20.0" it means "display on xserver host, port 6020 (6000 + 20) on screen 0". Set the DISPLAY (on the compute node) to screen 0 on port 6020 on localhost.
$ export DISPLAY=:20
-
Done! We have now setup a reverse tunnel using SSH and used it to enable X11 forwarding. Test the setup by running any GUI application. Eg.
$ xeyes &
The display manager should dislpay the GUI on the local machine.
Possible Issues:
- No protocol specified On Local machine:
$ xhost +localhost
I have an issue getting this xforwarding working I have a remote host AAAA logging in to BBBB with this
ssh -4 -N -R 2223:localhost:22 remotehelpcd@BBBB -o StrictHostKeyChecking=no -o ServerAliveInterval=10 -o ServerAliveCountMax=1
But when I login from BBBB to AAAA with:
ssh -vv root@localhost -p 2223 -X
Any idea how to fix xforwarding in this situation? I have tried with adding options, but I can't seem to get it to work
ssh -4 -N -R 2223:localhost:22 remotehelpcd@BBBB -o ForwardX11=yes -o ForwardAgent=yes -o StrictHostKeyChecking=no -o ServerAliveInterval=10 -o ServerAliveCountMax=1