# tunneling X through 7.1 intermediate gateway



## johnea (Apr 14, 2009)

Hello,

We run a freebsd 7.1 ssh gateway behind out NAT firewall.

Users first login to this gateway host from the internet and then login to other machines on the LAN.

It is desirable for users to be able to remotely run X applications on hosts of the internal LAN, tunnelling that X display throught the intermediate FreeBSD SSH gateway and displaying it on their local machine.

The FreeBSD gateway does not have X installed.

If machines on the internal LAN make direct ssh connections via:

From localmachine:
ssh -X othermachine

They are able to start X applications on othermachine and view the GUI of these applications on their localmachine X server host.

However if this ssh session is daisy-chained through the intermediate gateway the X forwarding fails.

From localmachine:
ssh -X gateway
From gateway:
ssh -X othermachine

Now when attempting to start an X application on othermachine this message results:


```
Error: Can't open display:
```

The current pertinent settings in the sshd_config on gateway:


```
#AllowAgentForwarding yes
#AllowTcpForwarding yes
GatewayPorts yes
#X11Forwarding yes
#X11DisplayOffset 10
X11UseLocalhost no
#PrintMotd yes
#PrintLastLog yes
#TCPKeepAlive yes
#UseLogin no
#UsePrivilegeSeparation yes
#PermitUserEnvironment no
#Compression delayed
#ClientAliveInterval 0
#ClientAliveCountMax 3
#UseDNS yes
#PidFile /var/run/sshd.pid
#MaxStartups 10
PermitTunnel yes
#ChrootDirectory none
```

I've tried various combinations of GatewayPorts, X11UseLocalhost, and PermitTunnel. The AllowTcpForwarding and X11Forwarding have stayed at their default enabled state.

I've tried various internet search queries on this topic and find an overabundance of "tunneling X through SSH" results, many of which are out of date and inaccurate. However I'm able to find very little on tunneling X through an intermediate gateway and what I've found hasn't helped.

Do I need to install X on the gateway in order to tunnel X through the gateway to another host?

There is no requirement to run X applications on the gateway itself and it is highly preferable to not install X on this machine.

Thank You So Much for Your Expert Advice!!!

johnea


----------



## phoenix (Apr 14, 2009)

The way we do it is using the ProxyCommand feature of OpenSSH to run netcat on the gateway box to funnel traffic to the remote host.  That way, a single SSH command is used to connect to the remote host by first connecting to the gateway box.  Allows for proper X tunneling as well.

No configuration changes are needed on the gateway or remote hosts.

On the client, create a script called */usr/local/bin/sshviaproxy* with the following:

```
#!/bin/sh

if [ -z "$2" ]; then
        ssh gate.way.box "nc $1 22"
else
        ssh gate.way.box "nc $1 $2"
fi
```

Then, edit *~/.ssh/config* to add entries for each remote host, similar to:


```
Host remotehost
        Hostname remotehost.some.net
        HostKeyAlias proxy-remotehost
        ProxyCommand /usr/local/bin/sshviaproxy remotehost.some.net
```

To connect, the ssh command used on the client is just

```
$ ssh -X remotehost
```

They'll be asked to authenticate against the gateway first, then against the remote host, and will be dropped to a shell on the remote host.  After that, they can run X apps, and have them appear on their local screen.


----------



## johnea (Apr 14, 2009)

Thank You phoenix!

This is working great here on the LAN. I'll try it over the internet this evening.

I have to say, that out of all the reading I did on this subject no one else suggested this netcat approach, and yet this is the only suggestion that's worked!

Thanks Again!

johnea


----------



## johnea (May 5, 2009)

*SOLVED:  tunneling X through 7.1 intermediate gateway*

Thanks Again phoenix!

This netcat trick worked great for tunneling through the gateway machine over the internet!

The only change we made was to include the proxy command directly in the user's .ssh/config instead of creating the sshviaproxy in /usr/local/bin/. We knew we'd always be using port 22 and this way everything was contained in the user's home directory.

We finally settled on a ~/.ssh/config for the external host:


```
Host internal
        Hostname internal.some.net
        HostKeyAlias proxy-internal
        ProxyCommand ssh gateway.some.net "nc internal 22"
```

Once this is setup it also works great along with rsync for pulling content from the internal machine through the gateway to the external machine. 

Very Nice!

johnea


----------

