I‘ve ssh gateway behind my NAT firewall. So all users must first login to my gateway host from the internet and then login to other machines on the LAN. This works great for cli based apps. However, few users would like to run x apps from internal LAN hosts and tunnel X display through intermediate ssh gateway and display back output on their local system. For example, from localsystem user makes connection as follows:

ssh -X user@gateway.example.com
ssh -X user@somelan.example.com

X forwarding fails with an error:

Error: Can’t open display:

How do I fix this problem and allow users to use X apps with my intermediate Linux / BSD gateway?

You need to use ProxyCommand in your $HOME/.ssh/config for the external host connecting via the Internet. It specifies the command to use to connect to the server. The command string extends to the end of the line, and is executed with the user’s shell. In the command string, %h will be substituted by the host name to connect and %p by the port. The command can be basically anything, and should read from its standard input and write to its standard output. It should eventually connect an sshd server running on some machine, or execute sshd -i somewhere. Host key management will be done using the HostName of the host being connected (defaulting to the name typed by the user). Setting the command to none disables this option entirely.

You need to use this directive in conjunction with nc and its proxy support. For example, the following directive would connect via an HTTP proxy at at port 3128:

ProxyCommand /usr/bin/nc -X connect -x %h %p

Open $HOME/.ssh/config:
$ vi $HOME/.ssh/config
Modify / add configuration as follows:

Host internal
        Hostname somelan.example.com
        HostKeyAlias proxy
        User vivek
        # ProxyCommand ssh gw.nixcraft.in nc %h %p 2> /dev/null
        ProxyCommand ssh gateway.example.com "/usr/bin/nc internal 22"

Save and close the file.

  • Host internal – Restricts the following declarations (up to the next Host keyword) to be only for those hosts that match one of the patterns given after the keyword.
  • ProxyCommand – Used nc command to Proxy your SSH session to internal system through gateway.
  • User – Specifies the user to log in as. In our example login as vivek.
  • HostKeyAlias – Specifies an alias that should be used instead of the real host name when looking up or saving the host key in the host key database files. This line can be commented out.

Now, user can login and run X apps:
$ ssh -X user@gateway.example.com
$ ssh -X user@somelan.example.com
$ xeyes &

See ssh_config man page for further details.

🐧 Get the latest tutorials on Linux, Open Source & DevOps via RSS feed or Weekly email newsletter.

🐧 5 comments so far... add one

CategoryList of Unix and Linux commands
Disk space analyzersdf duf ncdu pydf
File Managementcat cp mkdir tree
FirewallAlpine Awall CentOS 8 OpenSUSE RHEL 8 Ubuntu 16.04 Ubuntu 18.04 Ubuntu 20.04
Modern utilitiesbat exa
Network UtilitiesNetHogs dig host ip nmap
OpenVPNCentOS 7 CentOS 8 Debian 10 Debian 8/9 Ubuntu 18.04 Ubuntu 20.04
Package Managerapk apt
Processes Managementbg chroot cron disown fg glances gtop jobs killall kill pidof pstree pwdx time vtop
Searchingag grep whereis which
User Informationgroups id lastcomm last lid/libuser-lid logname members users whoami who w
WireGuard VPNAlpine CentOS 8 Debian 10 Firewall Ubuntu 20.04
5 comments… add one
  • Scott Carlson May 8, 2009 @ 3:13

    Sorry, I think your final commands are incorrect.
    I think they should be
    $ ssh -X user@internal
    $ xeyes &

    And if you add “ForwardX11 yes” to the config, you wouldn’t need the -X

  • Greg Wildman May 8, 2009 @ 11:57

    I do a similar thing to access my linux boxes behind a linux firewall at home. In this case ‘defender’ being the firewall and ‘digdug’ the server I want to ssh to, yes yes – 80’s arcade theme for server names. :)

    ssh -t defender ssh digdug
    xterm &

    I have used the ‘-t’ option to do this through 4 servers as well.

  • Ulver May 8, 2009 @ 14:02

    some occations using “ssh -X yadayada” i’d have some autentication troubles …overall with old version of x11 ..troubles are about mit cookies stuff …for this kind of case are very usefull use “ssh -Y yadayada”

  • David Mackintosh May 8, 2009 @ 16:45

    Alternatively, you could use your first SSH session to tunnel into the second machine. For example:

    $ ssh -fgNL 2202:somelan.example.com:22 user@gateway.example.com

    $ ssh -Xp 2202 user@localhost

  • Gene Mat May 15, 2009 @ 0:46

    What is /usr/bin/nc? What do all those nc options do???

Leave a Reply

Your email address will not be published.

Use HTML <pre>...</pre> for code samples. Still have questions? Post it on our forum