To get X11 forwarding working over SSH, you'll need three things in place:
- Your client must be set up to forward X11.
- Your server must be set up to allow X11 forwarding.
- Your server must be able to set up X11 authentication.
If you have both #1 and #2 in place but are missing #3, then you'll end up with an empty DISPLAY
environment variable.
Soup-to-nuts, here is how to get X11 forwarding working:
On your server, make sure /etc/ssh/sshd_config
contains:
X11Forwarding yes
X11DisplayOffset 10
You may need to SIGHUP sshd
so it picks up these changes.
cat /var/run/sshd.pid | xargs kill -1
On your server, make sure you have xauth
installed.
belden@skretting:~$ which xauth
/usr/bin/xauth
If you do not have xauth
installed, you will run into the empty DISPLAY environment variable
problem.
On your client, connect to your server. Be certain to tell ssh to allow X11 forwarding. I prefer
belden@skretting:~$ ssh -X blyman@the-server
but you may like
belden@skretting:~$ ssh -o ForwardX11=yes blyman@the-server
or you can set this up in your ~/.ssh/config
.
I was running into this empty DISPLAY
environment variable earlier today when ssh'ing into a new server that I do not administer. Tracking down the missing xauth
part was a bit fun. Here is what I did, and what you can do too.
On my local workstation, where I am an administrator, I verified that /etc/ssh/sshd_config
was set up to forward X11. When I ssh -X
back in to localhost, I do get my DISPLAY
set correctly.
Forcing DISPLAY
to get unset was not too hard. I just needed to watch what sshd
and ssh
were doing to get it set correctly. Here is the full output of everything I did along the way.
blyman@skretting:~$ mkdir ~/dummy-sshd
blyman@skretting:~$ cp -r /etc/ssh/* ~/dummy-sshd/
cp: cannot open `/etc/ssh/ssh_host_dsa_key' for reading: Permission denied
cp: cannot open `/etc/ssh/ssh_host_rsa_key' for reading: Permission denied
Instead of using sudo to force copying my ssh_host_{dsa,rsa}_key
files into place, I used ssh-keygen to create dummy ones for myself.
blyman@skretting:~$ ssh-keygen -t rsa -f ~/dummy-sshd/ssh_host_rsa_key
Generating public/private rsa key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/blyman/dummy-sshd/ssh_host_rsa_key.
Your public key has been saved in /home/blyman/dummy-sshd/ssh_host_rsa_key.pub.
Rinse-and-repeate with -t dsa
:
blyman@skretting:~$ ssh-keygen -t dsa -f ~/dummy-sshd/ssh_host_dsa_key
# I bet you can visually copy-paste the above output down here
Edit ~/dummy-sshd/sshd_config
to point to the correct new ssh_host
key files.
# before
blyman@skretting:~$ grep ssh_host /home/blyman/dummy-sshd/sshd_config
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_dsa_key
# after
blyman@skretting:~$ grep ssh_host /home/blyman/dummy-sshd/sshd_config
HostKey /home/blyman/dummy-sshd/ssh_host_rsa_key
HostKey /home/blyman/dummy-sshd/ssh_host_dsa_key
Fire up sshd
on a new port in non-detach mode:
blyman@skretting:~$ sshd -p 50505 -f ~/dummy-sshd/sshd_config -d
sshd re-exec requires execution with an absolute path
Whoops, better correct that path:
blyman@skretting:~$ /usr/sbin/sshd -p 50505 -f ~/dummy-sshd/sshd_config -d
debug1: sshd version OpenSSH_5.5p1 Debian-4ubuntu6
debug1: read PEM private key done: type RSA
debug1: Checking blacklist file /usr/share/ssh/blacklist.RSA-2048
debug1: Checking blacklist file /etc/ssh/blacklist.RSA-2048
debug1: private host key: #0 type 1 RSA
debug1: read PEM private key done: type DSA
debug1: Checking blacklist file /usr/share/ssh/blacklist.DSA-1024
debug1: Checking blacklist file /etc/ssh/blacklist.DSA-1024
debug1: private host key: #1 type 2 DSA
debug1: setgroups() failed: Operation not permitted
debug1: rexec_argv[0]='/usr/sbin/sshd'
debug1: rexec_argv[1]='-p'
debug1: rexec_argv[2]='50505'
debug1: rexec_argv[3]='-f'
debug1: rexec_argv[4]='/home/blyman/dummy-sshd/sshd_config'
debug1: rexec_argv[5]='-d'
Set /proc/self/oom_adj from 0 to -17
debug1: Bind to port 50505 on 0.0.0.0.
Server listening on 0.0.0.0 port 50505.
debug1: Bind to port 50505 on ::.
Server listening on :: port 50505.
Pop a new terminal and ssh into localhost
on port 50505
:
blyman@skretting:~$ ssh -p 50505 localhost
The authenticity of host '[localhost]:50505 ([::1]:50505)' can't be established.
RSA key fingerprint is 81:36:a5:ff:a3:5a:45:a6:90:d3:cc:54:6b:52:d0:61.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[localhost]:50505' (RSA) to the list of known hosts.
Linux skretting 2.6.35-32-generic #67-Ubuntu SMP Mon Mar 5 19:39:49 UTC 2012 x86_64 GNU/Linux
Ubuntu 10.10
Welcome to Ubuntu!
* Documentation: https://help.ubuntu.com/
1 package can be updated.
0 updates are security updates.
Last login: Thu Aug 16 15:41:58 2012 from 10.0.65.153
Environment:
LANG=en_US.UTF-8
USER=blyman
LOGNAME=blyman
HOME=/home/blyman
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
MAIL=/var/mail/blyman
SHELL=/bin/bash
SSH_CLIENT=::1 43599 50505
SSH_CONNECTION=::1 43599 ::1 50505
SSH_TTY=/dev/pts/16
TERM=xterm
DISPLAY=localhost:10.0
Running /usr/bin/xauth remove unix:10.0
/usr/bin/xauth add unix:10.0 MIT-MAGIC-COOKIE-1 79aa9275ced418dd445d9798b115d393
Look at the last three lines there. I fortuitously had DISPLAY
set, and had those two nice-looking lines from /usr/bin/xauth
.
From there it was child's play to move aside my /usr/bin/xauth
to /usr/bin/xauth.old
, disconnect from ssh
and stop the sshd
, then launch sshd
and ssh
back in to localhost.
When /usr/bin/xauth
was gone, I did not see DISPLAY
reflected in my environment.
There is nothing brilliant going on here. Mostly I got lucky in choosing a sane approach to try reproducing this on my local machine.