45

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.

lexsys
  • 2,863
  • 5
  • 30
  • 34

8 Answers8

33

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.

dave
  • 484
  • 4
  • 3
  • 5
    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 – asdmin Aug 12 '09 at 07: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. – dave Aug 12 '09 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". – msb Mar 21 '18 at 00:13
  • ssh: connect to host ... port 22: Connection refused while executing the first command – user1868607 Sep 01 '18 at 15:34
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

slm
  • 7,355
  • 16
  • 54
  • 72
AgentK
  • 411
  • 2
  • 4
  • 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. –  Jun 03 '14 at 08: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" – msb Mar 21 '18 at 00:10
7

Have you tried with

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

The -Y flag "Enables trusted X11 forwarding."

pyhimys
  • 1,267
  • 10
  • 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
Michael Hampton
  • 237,123
  • 42
  • 477
  • 940
Brad Allison
  • 61
  • 1
  • 1
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
Jayen
  • 1,827
  • 3
  • 16
  • 27
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
Jayen
  • 1,827
  • 3
  • 16
  • 27
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).

hamnur
  • 21
  • 3
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.

asdmin
  • 2,020
  • 16
  • 28
  • @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" – Daniel Lawson Aug 12 '09 at 09: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 – asdmin Aug 12 '09 at 10:31
  • On some systems the default is "`yes`". – Brad Gilbert Aug 14 '09 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. – lexsys Aug 19 '09 at 06: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 – asdmin Aug 19 '09 at 06:40