47

I have hosts A,B and C. From host A I can access through ssh only B. From B I can access C. I want to be able to run X11 programs on C and forward display to A.

I tried this:

A$ ssh -X B B$ ssh -X C C$ xclock Error: Can't open display: 

But it doesn't work.

8 Answers 8

34

There are several ways to do this, the one I prefer is to forward the ssh port:

First, connect to machine B and forward [localPort] to C:22 through B

A$ ssh -L [localPort]:C:22 B 

Next, connect to C from A through this newly-created tunnel using [localPort], forwarding X11

A$ ssh -X -p [localPort] localhost 

Now we can run X11 programs on C and have them display on A

C$ xclock 

[localPort] can be any port that you are not already listening to on A, I often use 2222 for simplicity.

4
  • 6
    not exactly... if X11Forwarding is not enabled on server C, it won't work. it also won't work unless one sets AllowTcpForwarding yes and GatewayPorts yes on server B. this answer is not acceptable at all Commented Aug 12, 2009 at 7:02
  • You make a good point, I did not notice this since I use debian, on which X11Forwarding and AllowTcpForwarding are enabled by default. GatewayPorts is not needed since when it is disabled, SSH still listens on localhost and that is what we are connecting to. You would only need it if you wanted to make the second connection via an external IP for machine A. Commented Aug 12, 2009 at 22:48
  • On step 1, it didn't ask me the password for host B, and I end up connected in host C. In another window I tried step 2 and I get "ssh_exchange_identification: Connection closed by remote host". Commented Mar 21, 2018 at 0:13
  • ssh: connect to host ... port 22: Connection refused while executing the first command Commented Sep 1, 2018 at 15:34
8

Have you tried with

A$ ssh -Y B B$ ssh -Y C C$ xlclock 

The -Y flag "Enables trusted X11 forwarding."

3
  • The same result. Commented Aug 12, 2009 at 6:13
  • 2
    This worked for me, but only to discover how slow is X11 Commented Sep 1, 2018 at 16:10
  • add also -C (compression). much faster Commented Nov 4, 2022 at 12:42
8

This can easily be accomplished using port forwarding:

A$ ssh -NL 2022:C:22 B & A$ ssh -X -p 2022 localhost C$ xclock 

Port localhost:2022 is forwarded to C:22 via B SSH to C via localhost:2022 Use X as normal

2
  • 2
    This won't work for the same reasons noted elsewhere in case B (the gateway) does not have the correct sshd forwarding options enabled. Commented Jun 3, 2014 at 8:24
  • didn't ask for my password to host B, which is weird; and it didn't work, I got the error message "channel 2: open failed: administratively prohibited: open failed ssh_exchange_identification: Connection closed by remote host" Commented Mar 21, 2018 at 0:10
5

For newer versions opensshd you have to disable X11UseLocalhost for this to work.

You need to do this on Host C's /etc/ssh/sshd_config and restart sshd for this to work:

X11Forwarding yes X11UseLocalhost no 
4

Assuming the problem is that the middle machine doesn't have X, but it otherwise configured to allow forwarding X11, just install xauth.

on a yum-based system (fedora, redhat, centos):

B$ sudo yum install xauth 

on an apt-based system (debian, ubuntu):

B$ sudo apt-get install xauth 
4
  • Yay- perfect for headless raspberry pi. Commented Apr 21, 2018 at 22:53
  • @cmc or using ssh like a vpn. Commented Apr 22, 2018 at 2:31
  • @cmc do you have yum on a pi? Commented Apr 22, 2018 at 2:31
  • nope- sudo apt-get install xauth Commented Apr 22, 2018 at 12:13
3

If you often go from A to C, you can configure B as a proxy:

A:~/.ssh/config:

Host C ForwardX11 yes ProxyCommand ssh -W %h:%p B 

then it's just:

A$ ssh C xclock 
2

You could combine -Y/-X command with the -J command line option:

A$ ssh -Y user@C -J user@B C$ xclock 

If you have more Hosts to hop than just do the following:

A$ ssh -Y user@C -J user@B,user@D,...,user@Z C$ xclock 

From man ssh:

-J [user@]host[:port] Connect to the target host by first making a ssh connection to the jump host and then establishing a TCP forwarding to the ultimate destination from there. Multiple jump hops may be specified separated by comma characters. This is a shortcut to specify a ProxyJump configuration directive. 

It was introduced in OpenSSH version 7.3 (released in August 2016).

1

You can't forward X11 display if you have X11Forwarding disabled in any sshd you are using.

man sshd_config:

X11Forwarding Specifies whether X11 forwarding is permitted. The argument must be “yes” or “no”. The default is “no”. 

You have to make sure X11Forwarding is enabled on destination and all intermediate sshds you are using.

Just a small hint: you should try to use VNC, X11 display forwarding is quite bandwidth consuming.

5
  • @AgentK's and @dave's suggestions only require X11Forwarding to be enabled on the final host, as they use an SSH tunnel to bypass the intermediate host. Your suggestion is almost definitely why the OP's method failed at first, but that doesn't mean other people's answers "are not acceptable" Commented Aug 12, 2009 at 9:36
  • their answers were defective and remedied the problem, not solving it. a right and useful answer would consider the original question and solving it, and providing other ways only in case the originals question is not solvable. by the way, neither of them mentioned X11Forwarding, which is essential Commented Aug 12, 2009 at 10:31
  • On some systems the default is "yes". Commented Aug 14, 2009 at 20:09
  • I checked, that X11Forwarding is enabled on B and C and AllowTcpForwarding is set to yes on B. But the result of my commands is the same. And dave's answer works fine for me. Commented Aug 19, 2009 at 6:02
  • then do that, but it's only a remedy. you also can start ssh with parameter '-v', or try echo $DISPLAY all the nested ssh commands to find it out where $DISPLAY get lost Commented Aug 19, 2009 at 6:40

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.