539

I have a machine running Ubuntu which I SSH to from my Fedora 14 machine. I want to forward X from the Ubuntu machine back to Fedora so I can run graphical programs remotely. Both machines are on a LAN.

I know that the -X option enables X11 forwarding in SSH, but I feel like I am missing some of the steps.

What are the required steps to forward X from a Ubuntu machine to Fedora over SSH?

Braiam
  • 35,380
  • 25
  • 108
  • 167
Mr. Shickadance
  • 6,884
  • 6
  • 26
  • 28
  • 11
    I know this is rather common, but I am having issues. A definitive answer for this question would be helpful for many. Lots of examples around seem omit important details. – Mr. Shickadance May 06 '11 at 17:41
  • 8
    One thing to be aware of when reading about X11 is that the terminology is a little weird. Usually the machine that we are sitting at is the client, and the server is the machine that is remote to us.But in the X world, that is flipped around. The machine we are sitting at is creating windows and drawing shapes at the request of the remote machine. So the remote machine making the requests to draw is the "Client", and the local machine that is servicing those requests is the "Server". – Mike DeAngelo Dec 28 '19 at 22:28

13 Answers13

638

X11 forwarding needs to be enabled on both the client side and the server side.

On the client side, the -X (capital X) option to ssh enables X11 forwarding, and you can make this the default (for all connections or for a specific connection) with ForwardX11 yes in ~/.ssh/config.

On the server side, X11Forwarding yes must be specified in /etc/ssh/sshd_config. Note that the default is no forwarding (some distributions turn it on in their default /etc/ssh/sshd_config), and that the user cannot override this setting.

The xauth program must be installed on the server side. If there are any X11 programs there, it's very likely that xauth will be there. In the unlikely case xauth was installed in a nonstandard location, it can be called through ~/.ssh/rc (on the server!).

Note that you do not need to set any environment variables on the server. DISPLAY and XAUTHORITY will automatically be set to their proper values. If you run ssh and DISPLAY is not set, it means ssh is not forwarding the X11 connection.

To confirm that ssh is forwarding X11, check for a line containing Requesting X11 forwarding in the output of ssh -v -X. Note that the server won't reply either way, a security precaution of hiding details from potential attackers.

bryant1410
  • 127
  • 7
Gilles 'SO- stop being evil'
  • 807,993
  • 194
  • 1,674
  • 2,175
  • Don't we need sometimes to set `sudo xhost +client`? When I connect from xubuntu1 to xubuntu2, xubuntu2 running sshd, I do ssh -X from 1, on 2 I type above xhost-command, and then I start a graphical program. Is it a workaround if no modificaton of /etc/*config is wanted? – user unknown May 06 '11 at 22:33
  • 46
    @user: No, you never need `xhost +`. `xhost` is from a gentler era when having a machine connected to the network meant you were trustworthy. `xhost +` means anyone who can spoof your IP can take control of your X server session. `ssh -X` will set up all the required authorizations. If X11 forwarding disabled in the server config, talk to your administrator; if that doesn't work, see [Forwarding X11 over SSH if the server configuration doesn't allow it](http://unix.stackexchange.com/questions/12777/forwarding-x11-over-ssh-if-the-server-configuration-doesnt-allow-it). – Gilles 'SO- stop being evil' May 06 '11 at 22:52
  • Thanks, gilles. Since it was a 192.168.*-address, everybody in the net (eth-xlink-cable) was pretty trustworthy. :) – user unknown May 06 '11 at 23:52
  • Is this answer valid if the client is Mac OS X? It doesn't seem to be working, just sends display to `localhost:10`. – McKAMEY Aug 02 '12 at 19:21
  • @McKAMEY Yes, the client can be OSX. On the server (i.e. inside the SSH session), `$DISPLAY` is typically `localhost:10` (the number can vary, it's the first free number starting at 10). If `$DISPLAY` is set in the ssh session, everything should work. If it doesn't, you can [ask here](http://unix.stackexchange.com/questions/ask); be sure to describe exactly what you did (contents of `.ssh/config`, command line, etc.), and say precisely what is wrong (copy-paste any error message). – Gilles 'SO- stop being evil' Aug 02 '12 at 20:19
  • 9
    Thanks for mentioning xauth! Lack of that on a barebones server was causing me trouble. – vasi Apr 09 '13 at 06:53
  • 5
    +1 for making the distinction between `~/.ssh/config` and `/etc/ssh/sshd_config` in the same place. I could not tell if they were different' files or just a change in nomenclature. – puk Nov 13 '13 at 07:48
  • @Gilles Is it still possible to use this method when server is already running a GUI environment? My home server is running basic gnome-panel classic & but when I try `ssh -X user@server` it gives me error: `/usr/bin/xauth: /home/$user/.Xauthority not writable.` Any idea why? – Khurshid Alam Jan 06 '14 at 08:10
  • 1
    @KhurshidAlam It doesn't matter whether the server is also running a GUI environment. Check the permissions on the `.Xauthority` file. If using Red Hat or other system with SELinux, check the SELinux context, see http://unix.stackexchange.com/questions/36540/why-am-i-still-getting-a-password-prompt-with-ssh-with-public-key-authentication/36687#36687 – Gilles 'SO- stop being evil' Jan 06 '14 at 12:30
  • @Gilles Ok I deleted `.Xauthority` (as root) on server, now its working fine from one machine (`machine-A`).I have several computers (Desktops,Netbooks, Tablets). I share same private ssh-key across all machines (just copied the `~/.ssh`). But now its showing same error when I try to connect to server from `machine-B`.I think permission set by a machine (on `.Xauthority`) during `ssh -X` doesn't really work for other machine with same ssh-key. I wonder, if there is a nice way to share same ssh-key pair across multiple computers. – Khurshid Alam Jan 06 '14 at 13:32
  • 1
    @KhurshidAlam Your setup sounds fine, you can share the same keypair (it's purely a matter of security vs convenience). The permissions on `.Xauthority` have nothing to do with SSH. There's something unusual in your setup, post a new question and be sure to mention the permissions on `.Xauthority` (output of `ls -l ~/.Xauthority`), your distribution, and anything else that seems relevant. – Gilles 'SO- stop being evil' Jan 06 '14 at 13:36
  • For googlers: A Kubuntu 13.10 server and Kubuntu 13.10 client failed with "Cannot connect to X server". After investigating all other options, found that DISPLAY environment was not set automatically. So, adding DISPLAY to AcceptEnv in sshd_config solved my case. [AcceptEnv DISPLAY LANG LC_*] – Malkocoglu Mar 11 '14 at 10:29
  • @Malkocoglu That's odd: `DISPLAY` is not transmitted from the client to the server, it's set on the server side, so it should *not* be in `AcceptEnv`. What value of `DISPLAY` do you get on the remote side? I suspect that your X connection isn't going through the SSH. Also I can confirm that X forwarding works out of the box on Ubuntu 13.10, without adding `DISPLAY` to `AcceptEnv`. – Gilles 'SO- stop being evil' Mar 11 '14 at 10:42
  • Both machines are behind distinctive firewalls on distance locations, so no other port or connection available. However, I tried removing DISPLAY from AcceptEnv, it works as intended. I must have forgotten reloading sshd_config at some point so I mixed the results of two consequtive trials. For notation, out of the box configuration did not throw any error in -v mode but was not setting DISPLAY properly. – Malkocoglu Mar 11 '14 at 13:08
  • 12
    after `ssh -X` run `xterm &` to get a graphical terminal as the ultimate test to see if it's working. – Alexander Taylor May 29 '14 at 17:18
  • 1
    [Pretty useful link](http://superuser.com/a/805060/185665). This exact issue prevented X11 Forwarding from working for me. I had `~/.ssh/rc` file. And it turned it it's responsible for running `xauth` as such. – x-yuri Apr 11 '15 at 14:32
  • In case `xclock` works but other applications don't check out this answer: https://unix.stackexchange.com/a/709789/116710 – holzkohlengrill Jun 23 '23 at 17:01
134

To get X11 forwarding working over SSH, you'll need three things in place:

  1. Your client must be set up to forward X11.
  2. Your server must be set up to allow X11 forwarding.
  3. 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:

  1. 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
    
  2. 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.

  3. 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.

Serge Stroobandt
  • 2,314
  • 3
  • 32
  • 36
Belden
  • 1,441
  • 1
  • 9
  • 4
  • 5
    Wow, thank you so much for your anwer. I was doing everything good except the `export DISPLAY=:10`. I never guessed that number of display. – m3nda Oct 31 '15 at 22:34
  • 1
    It's a _display offset_ of 10! :D – 41754 Jul 23 '19 at 20:07
  • 3
    On the client side, a significant speedup can be achieved by **enabling compression** through the `-C` option, as in: `$ ssh -X -C blyman@the-server` – Serge Stroobandt Feb 07 '21 at 18:00
  • 2
    `AddressFamily inet` in `sshd_config` helps if "X11 forwarding request failed on channel 0" error raises ([source](https://bbs.archlinux.org/viewtopic.php?id=139175)) – bartolo-otrit Mar 19 '21 at 13:00
61

Make sure that:

  • You've xauth installed on the server (see: xauth info/xauth list).
  • On the server your /etc/ssh/sshd_config file have these lines:

    X11Forwarding yes
    X11DisplayOffset 10
    X11UseLocalhost no
    
  • On the client side your ~/.ssh/config file have these lines:

    Host *
      ForwardAgent yes
      ForwardX11 yes
    
  • On the client side, you've X server installed (e.g. macOS: XQuartz; Windows: Xming).


Then to do X11 forwarding using SSH, you need to add -X to your ssh command, e.g.

ssh -v -X user@host

then verify that your DISPLAY is not empty by:

echo $DISPLAY

If it is, then having verbose parameter for ssh (-v), check for any warnings, e.g.

debug1: No xauth program.
Warning: untrusted X11 forwarding setup failed: xauth key data not generated

In case you've got untrusted X11 as shown above, then try -Y flag instead (if you trust the host):

ssh -v -Y user@host

See: What does “Warning: untrusted X11 forwarding setup failed: xauth key data not generated” mean when ssh'ing with -X?


In case you've warning: No xauth data, you may try to generate a new .Xauthority file, e.g.

xauth generate :0 . trusted
xauth list

See: Create/rebuild a new .Xauthority file


If you've got a different warnings than above, follow the further clues.


kenorb
  • 20,250
  • 14
  • 140
  • 164
26

The fix is to add this line to your /etc/ssh/sshd_config:

X11UseLocalhost no

https://joshua.hoblitt.com/rtfm/2013/04/how_to_fix_x11_forwarding_request_failed_on_channel_0/

Anthon
  • 78,313
  • 42
  • 165
  • 222
Ace
  • 261
  • 3
  • 2
  • 1
    I have 2 Ubuntu server. On the one I needed it set to yes, on the other it had to be no. I am sure there is a explanation, but it's worth to try both. – alfonx Aug 19 '15 at 13:08
  • 3
    Please clarify if you mean to put this setting on the server or client – Klik Mar 09 '18 at 02:35
  • @Klik `/etc/ssh/sshd_config` is on the server. The `d` stands for `daemon` -- https://en.wikipedia.org/wiki/Daemon_(computing) -- Clients tend not to be daemon processes. – dijksterhuis Jun 01 '20 at 02:57
  • @alfonx it looks like The need for `X11UseLocalhost no` depends on whether IPv6 is activated on the server, see http://icaci.info/posts/x11-forwarding-with-x11uselocalhost-no.html ! – MoonCactus Mar 02 '21 at 17:16
6

Letting Ubuntu bash on Windows 10 run ssh -X to get a GUI environment on a remote server

  • First

Install all the following. On Window, install Xming. On Ubuntu in the terminal, use sudo apt install to install ssh xauth xorg.

sudo apt install ssh xauth xorg
  • Second

Go to the folder contains ssh_config file, mine is /etc/ssh.

  • Third

Edit ssh_config as administrator(USE sudo). Inside ssh_config, remove the hash # in the lines ForwardAgent, ForwardX11, ForwardX11Trusted, and set the corresponding arguments to yes.

# /etc/ssh/ssh_config

Host *
    ForwardAgent yes
    ForwardX11 yes
    ForwardX11Trusted yes
  • Forth

In ssh_config file, remove the front hash # before Port 22 and Protocol 2, and also append a new line at the end of the file to state the xauth file location, XauthLocation /usr/bin/xauth, remember write your own path of xauth file.

# /etc/ssh/ssh_config

#   IdentifyFile ...
    Port 22
    Protocol 2
#   Cipher 3des
#   ...
#   ...
    ...
    ...
    GSSAPIDelegateCredentials no
    XauthLocation /usr/bin/xauth
  • Fifth

Now since we are done editing ssh_config file, save it when we leave the editor. Now go to folder ~ or $HOME, append export DISPLAY=localhost:0 to your .bashrc file and save it.

# ~/.bashrc
...
...
export DISPLAY=localhost:0
  • Last

We are almost done. Restart your bash shell, open your Xming program and use ssh -X yourusername@yourhost. Then enjoy the GUI environment.

ssh -X yourusername@yourhost

The problem is also in Ubuntu subsystem on Windows, and the link is at

https://gist.github.com/DestinyOne/f236f71b9cdecd349507dfe90ebae776

JeromeFr
  • 103
  • 1
  • 1
  • 4
DestinyOne
  • 161
  • 1
  • 3
4

Add X11UseLocalhost no to /etc/ssh/sshd_config and restart the SSH server.

If you get no DISPLAY, check if xauth is installed correctly and then try it again.

RHE/CEntos doesn't have this issue, this is a Ubuntu thing!

polym
  • 10,672
  • 9
  • 41
  • 65
4

If you are doing ssh from Windows (10) to a Linux system - do yourself a favour and use a SSH client like Putty ( regular ssh -X etc does not work).

Step 1: Install a XServer in Windows : Example XMing Server (listens on localhost:0.0)

Step 2: In putty enable X11 forwarding

Step 3: Connect to remote Linux server

Make sure all conditions here are met in Linux server - that is X11Forwarding is yes and xauth is present as explained in the answer https://unix.stackexchange.com/a/12772/121634

Fire up XClock and wait a minute for the display to appear in your Windows machine

Note - If from this Linux server you are connecting to another server and want to forward X11 back to your Windows, you just need to connect to the next in chain with ssh -X.

That is

[Windows] Putty (with X11forwarding) --> [Server1] (xclock works) --> ssh -X [Server 2] (xclock works)

enter image description here

Alex Punnen
  • 143
  • 5
1

X11Forwarding must be set on the SSH server (in your case the Ubuntu box) in its sshd_config, and you must allow X11 to be forwarded for the SSH client (your Fedora box) by passing the -X option or editing the ssh_config file to add the ForwardX11 default.

underscore_d
  • 153
  • 13
Caleb
  • 69,278
  • 18
  • 196
  • 226
  • 1
    You also need `xauth` installed on the remote machine, otherwise the x authority stuff won't work. – Faheem Mitha May 06 '11 at 18:22
  • What about setting `DISPLAY`? – Mr. Shickadance May 06 '11 at 18:36
  • 1
    ssh will automatically set `$DISPLAY` if `X11Forwarding` is enabled and `xauth` is present on the client system. – Shadur May 06 '11 at 18:58
  • 2
    @Shadur Not for me. It works when I `export DISPLAY=:10.0` but not otherwise. Otherwise, it complains that it cannot find `:0`. Maybe something else is needed for this to happen automatically? – cfr Mar 06 '17 at 17:39
1

For me the problem was in nodev mount option for /tmp filesystem. X11 needs a special file to be created in there.

So check what are the mount options for /tmp filesystem if you use a separate partition or disk for that.

yakovpol
  • 11
  • 1
  • 2
    I think you might want to see other answers to the original question and take a moment to think how your own answer improves on them. –  Jun 19 '14 at 11:28
1

xauth can get locked.

   -b      This  option  indicates  that  xauth  should  attempt to break any authority file locks before proceeding.  Use this
           option only to clean up stale locks.

Using

xauth -b

On the machine that I was trying to ssh into broke the lock on xauth. Logging out of the ssh session after issuing xauth -b then logging back in finally allowed me to successfully echo $DISPLAY. Definitely try this before re-creating .Xauthority

0

To add to the previous excellent answers (setting up ~/.ssh/config and checking to see if the DISPLAY environment variable is set on the client, setting up /etc/ssh/sshd_config and installing xauth on the server), also make sure xterm is installed on the client, e.g.

sudo apt-get install xterm
Patrick Mevzek
  • 3,130
  • 2
  • 20
  • 30
Aliz Rao
  • 9
  • 1
0
  • Follow this steps on both server and client sides
    • For the server I have a unix-like OS
      • make sure on file /etc/ssh/sshd_config you have yes line
        X11Forwarding yes
        
      • if was just enabled, restart ssh. In my case
        sudo systemctl restart ssh
        
    • On the client side I am on a macOS
      • Provide xterm
        brew install --cask xquartz
        
      • Restart the computer was necessary before the first connect to server
        ssh -Y user@host
        
      • Check if it’s working
        chromium http://google.com
        
Ax_
  • 121
  • 6
0

If you're using connection sharing, you need to close all existing connections before any changes to your client ssh options will take effect.

I was using a script to connect to a remote machine with these options set.

-oControlPath=${control_path}
-oControlMaster=auto

I was trying to change my client ssh options to enable X11 forwarding and couldn't figure out why they weren't taking effect. I had to close the existing connections and reconnect with the new client ssh options for enabling X11 forwarding for it to work. You could also just open a new connection by removing any options for setting the control path.

Took me awhile to figure this out. Hope this helps someone.

Callan
  • 201
  • 1
  • 3