This tutorial describes how to run remote X applications on a local X server using ssh -X under Debian, for example to log into our Linksys NSLU2 from a host machine.
We would like to run an X application on a remote machine (which does not necessarily have an X server installed), displaying the application's GUI on the X server of a local machine. Both the local and the remote machine are assumed to run Debian. The specific need I had for this was to be able to communicate with my Linksys NSLU2 through SSH.
How not to do it (xhost)
Check the X server setting on your local machine:
local-machine:~$ ps -ef | grep nolisten
If you see a line like
root 3282 3256 2 10:22 tty7 00:09:04 /usr/bin/X :0 vt7 -nolisten tcp -auth /var/lib/xdm/authdir/authfiles/A:0-OMq6vs
your X server does not listen to incoming TCP connections, most likely for security reasons. However, this can be avoided by editing /etc/X11/xinit/xserverrc: Remove "-nolisten tcp" and then restart X (Ctrl+Alt+Backspace, startx).
local-machine:~$ xhost +IP.of.remote.machine
On the remote machine, you need to set your DISPLAY environment variable:
remote-machine:~$ export DISPLAY=IP.of.local.machine:0.0
You now should be able to display the GUI of an application running on the remote machine through the local machine's X server. Try xcalc (or xeyes, etc.) as an example:
This method represents a security risk due to the necessity of opening the X server on the local machine to incoming TCP connections. Most online tutorials (e.g. 4th post here) suggest to abandon it altogether and instead use the following - more secure - method:
How to do it (ssh -X or ssh -Y)
local-machine:~$ ssh -X -C -2 username@IP.of.remote.machine
The -2 flag forces ssh to try protocol version 2 only (not strictly required). The -C flag is for sending the data over ssh compressed (not strictly required, but speeds things up).
This approach has the following advantages compared to the xhost approach discussed earlier.
- The X server on the local machine does not need to accept incoming TCP connections, which represents a security improvement.
- The handling of the DISPLAY environment variable is done automatically by the ssh daemon on the remote machine.
Be aware that some online tutorials (e.g. this one) seem to not be aware of this and mix up the xhost and the ssh -X approach, which results in using ssh -X without the additional security.
In order to make this favorable approach work, we need to add some configurations to both the local and the remote machine:
Configuration of the local machine
On the local machine (the one you want the application's GUI to be displayed on), make sure /etc/ssh/ssh_config is configured to
Configuration of the remote machine
On the remote machine (the one you want the application to run on), make sure /etc/ssh/sshd_config (note that this is a different file than the one we just edited on the local machine!) is configured to
If this is not the case, edit the file accordingly and restart the SSH daemon:
remote-machine:~$ /etc/init.d/ssh startWhat most tutorials do not tell you is that xauth needs to be installed on the remote machine, most likely because it usually comes with your distribution anyway. However, this was the reason why I failed to run X apps remotely on a Linksys NSLU2 (aka Slug) running Debian. If you do not have xauth installed, you will be able to ssh -X into the remote machine, but then get an error message with regards to display when actually trying to start your desired application. If you experience such symptoms, try ssh's -v flag for a more verbose output:
local-machine:~$ ssh -2 -X -C -v username@IP.of.remote.machine
If this returns the following line:
debug1: Remote: No xauth program; cannot forward with spoofing.
Then you probably do not have xauth installed on the remote machine, which on Debian is part of the xbase-clients package. Install it on the remote machine, for example by typing
remote-machine:~$ sudo aptitude install xbase-clients
Note that this does not install a full-blown X server on the remote machine.
Try whether you've been successful by running some graphical application (like xcalc or xeyes) on the remote machine:
You can also do a
ps aux | grep xcalc
on both the local and the remote machine, which should demonstrate that the application is actually running on the remote machine.