How to enable X11 Forwarding with SSH on Mac OS X Leopard

Apple Remote Desktop (ARD) or VNC is a wonderful invention if you want full control over a remote desktop, but what if you only want to access the user display of one single X11 program on a remote machine?

This is possible on Mac OS X with X11 Forwarding.

THIS ARTICLE HAS BEEN REWRITTEN (Manual set of the $DISPLAY variable is insecure!)

Prerequisites:

X11 environments on both the local and remote machine (see man X). Ensure network access for X11. In Mac OS X  on X11 Quartz check the authorization and client access options under Preferences in the Security pane.

Enable X11 Forwarding with the “X11Forwarding yes” option set in “/private/etc/sshd_config” for your SSH Daemon own local X11 host in order to recieve X11 client request back from  the remote machine through ‘ssh‘ with the -X option set.

Start or restart the Remote Login (SSH) Service  under System Preference / Sharing pane on Mac OS X. The SSH daemon should run on the remote machine as well!

See “man ssh”,  “man ssh_config” and “man sshd_config” for the complete explanation.

3 Simple Steps to X11 Forward on Mac OS X

1. Open  “Terminal” in Mac OS X Leopard.

2. ssh -X X11 Forward to your remote host (See “man ssh” for the use of the -X or -Y flag X11 forward):

ssh -X johndoe@123.456.789

3. Start your remote X11 program and view the user display on your local machine:

xeyes &

Voila it works! The X application will start up your X11 environment. Its quite easy to do X11 forwarding when you first get the hang of it.

Do elegant X11 stuff with ssh -X -f  like:

ssh -X -f user@remotehost xcalc -bg black -fg green

Caveat Notes:

Have the latest and updated versions of Mac OS X, Developer and X11.

3 Clues to successful X11 forwarding:

A. When you make changes to /etc/sshd_config remember to restart the Remote Login Service (SSH).

B. Remember to allow incoming access to X11 in the X11 preferences and through your firewall(s) and router!

C. And you have will of curse have to be accurate about your local and remote machine naming convention i.e. John-Does-iMac.local or privat.happycamper.com. Check with “echo $HOSTNAME”. On the remote machine you could also do a check with $REMOTEHOST (if set) to check your own machine name on the remote host.

NOT! Sometimes it is necessary to use xhost +remotehost and set the $DISPLAY environment variable manually on Mac OS X (something -X or -Y flag in ssh should normally do for you). Try “echo $DISPLAY” on the local machine and remote to get hints of the $DISPLAY status. You can always check your environment with “env” and “$”. On Mac OS X Leopard you use EXPORT with bash shell to set environment variables as opposed to tcsh that uses setenv. You should only set the $DISPLAY variable manually in a secure environment i.e. local network.

NEW! Do not set the DISPLAY variable on the client. You will most likely disable encryption. (X connections forwarded through Secure Shell use a special local display setting.)

If you have further problems try to use -v, -vv or even -vvv verbose flag with ssh to debug.

X11 Forwarding:
X11 Forwarding www.ssh.com
Configurering and running X11 Applications on Mac OS X developer.apple.com
X11 FAQ  – Technical Q&A QA1232 developer.apple.com
Technical Q&A QA1383 Enabling X11 Forwarding developer.apple.com
Forwarding X11 from a Remote Computer to the Mac oroborosx.sourceforge.net
ssh X forwarding debugging mac.com
Display Names xfree86.org

X11:
X Window System wikipedia.org
The X Window System freebsd.org (Introduktion from FreeBSD Handbook)
XQuartz project xquartz.macosforge.org (X11)

Command-Line Administration Version 10.5 Leopard (PDF) manuals.info.apple.com (Connecting to Remote Computers p. 31 – 37)
Introduction to Command-Line Administration Version 10.6 Snow Leopard (PDF) manuals.info.apple.com (Connecting to Remote Computers p. 27 – 33)

Connecting to Remote Computers p. 27 – 33
Introduction to Command-Line Administration Version 10.6 Snow Leopard (PDF) manuals.info.apple.com

Open Source X11 developer.apple.com
UNIX & Open Source downloads apple.com

By thomas

I am free and loving spirit roaming the world. Born in Copenhagen, Denmark. Entrepreneur, Idea maker, Creative Business Developer, IT specialist, Poet, Father, Martial Artist, Taoist wanderer and explorer. ILM from University of Copenhagen. Truth, harmony and compassion is the way.

34 comments

  1. A troubleshooting checklist to see if DISPLAY is set
    source: http://forums.macosxhints.com/showthread.php?t=80171&page=2

    Ben Byer posted at the X11-users mailing list a checklist to see if DISPLAY is set:

    SSH troubleshooting steps:

    This list shows the expected behavior of the system.
    local $ —–> refers to commands run on my local Mac running Leopard.
    remote $ –> refers to commands run on a remote Unix machine, of any type.

    [1] local $ echo $DISPLAY
    /tmp/launch-Bh0fLm/:0

    [2] local $ grep DISPLAY ~/.*rc ~/.login ~/.*profile ~/.MacOSX/ environment.plist 2>/dev/null

    [3] local $ grep -r DISPLAY /opt/local/etc /sw/etc /etc 2>/dev/null

    [4] local $ ssh -Y remote
    Warning: No xauth data; using fake authentication data for X11 forwarding.

    [5] remote $ echo $DISPLAY
    localhost:10.0

    [6]remote $ grep X11 /etc/ssh/sshd_config ~/.ssh/*
    X11Forwarding yes
    X11DisplayOffset 10

    Notes:
    If step 1 returns ‘:0’, ‘localhost:0’ or anything similar, you have a configuration file that is overriding the system’s DISPLAY variable.

    If step 2 outputs anything, it indicates that a configuration file in your home directory may be the culprit; try creating a new user and repeating the steps with that user.

    If step 3 outputs anything, it indicates that a system-wide change was made that is overriding your environment. If it begins with /opt/ local, it is MacPorts; if it begins with /sw, it is Fink. Otherwise, it is probably a commercial program that uses X11; contact your vendor for an updated version.

    The warning message in step 4 is harmless.

    If step 5 does not output anything, then step 6 will say “X11Forwarding no”. In this case, you must fix the configuration on the remote side.

    If step 6 outputs anything other than “localhost:xx.0”, then your remote configuration is overriding the DISPLAY variable set by sshd on the remote side.

  2. “Assuming you have not set DISPLAY anywhere, you should be able to connect using SSH tunnelling without any special steps. I.e.

    1) Open Terminal.app
    2) run “echo $DISPLAY” — verify the result is of the form “/tmp/ launchd-xxxxx/:0”
    3) run “ssh -Y user@host”
    4) after you log in, X11.app should start on your Mac
    5) run “echo $DISPLAY” (on the remote host) — verify result is of the form “localhost:10″
    6) run xterm & (on the remote host) — xterm should appear on your Mac.

    Note that some people have seen problems with step 4, where X11.app can hang while launching — I don’t yet know why this is the case.”

    —————————-

    If you get a message saying:
    “Warning: No xauth data; using fake authentication data for X11 forwarding.”

    It’s harmless, as long as windows actually show up.

    Reference: see the previous response from me

  3. The $DISPLAY issue seems persistent. It is not an option to set the DISPLAY variable beforehand in your BASH .profile. Somehow I think its related to a security issue with the way Mac OS X handles the X11 environment and ssh. Hmm…

  4. The method you list in your main post doesn’t actually use ssh forwarding at all. You opened up your X Server (the Mac) to incoming connections (using xhost), then you told the remote machine to make connections directly to your Mac (not tunneled through ssh). Totally unencrypted, so probably not recommended.

    The link you posted provides a better overview of what’s happening:
    http://oroborosx.sourceforge.net/remotex.html

  5. Display Names
    From the user’s perspective, every X server has a display name of the
    form:

    hostname:displaynumber.screennumber

    This information is used by the
    application to determine how it should connect to the server and which
    screen it should use by default (on displays with multiple monitors):

    hostname
    The hostname specifies the name of the machine to which the display is
    physically connected. If the hostname is not given, the most efficient
    way of communicating to a server on the same machine will be used.
    displaynumber
    The phrase “display” is usually used to refer to collection of monitors
    that share a common keyboard and pointer (mouse, tablet, etc.). Most workstations
    tend to only have one keyboard, and therefore, only one display. Larger,
    multi-user systems, however, frequently have several displays so that more
    than one person can be doing graphics work at once. To avoid confusion,
    each display on a machine is assigned a display number (beginning at 0)
    when the X server for that display is started. The display number must
    always be given in a display name.
    screennumber
    Some displays share a single
    keyboard and pointer among two or more monitors. Since each monitor has
    its own set of windows, each screen is assigned a screen number (beginning
    at 0) when the X server for that display is started. If the screen number
    is not given, screen 0 will be used.

    On POSIX systems, the default display
    name is stored in your DISPLAY environment variable. This variable is
    set automatically by the xterm terminal emulator. However, when you log
    into another machine on a network, you will need to set DISPLAY by hand
    to point to your display. For example,

        % setenv DISPLAY myws:0
        $ DISPLAY=myws:0; export DISPLAY
    

    The xon script can be used to start an X program on a remote machine; it
    automatically sets the DISPLAY variable correctly.

    Finally, most X programs
    accept a command line option of -display displayname to temporarily override
    the contents of DISPLAY. This is most commonly used to pop windows on another
    person’s screen or as part of a “remote shell” command to start an xterm
    pointing back to your display. For example,

        % xeyes -display joesws:0 -geometry 1000x1000+0+0
        % rsh big xterm -display myws:0 -ls </dev/null &
    

    X servers listen for connections on a variety of different communications
    channels (network byte streams, shared memory, etc.). Since there can be
    more than one way of contacting a given server, The hostname part of the
    display name is used to determine the type of channel (also called a transport
    layer) to be used. X servers generally support the following types of connections:

    local
    The hostname part of the display name should be the empty string. For example:
    :0, :1, and :0.1. The most efficient local transport will be chosen.
    TCP/IP
    The hostname part of the display name should be the server machine’s IP
    address name. Full Internet names, abbreviated names, and IP addresses
    are all allowed. For example: x.org:0, expo:0, 198.112.45.11:0, bigmachine:1,
    and hydra:0.1.
    DECnet
    The hostname part of the display name should be the server machine’s nodename,
    followed by two colons instead of one. For example: myws::0, big::1, and
    hydra::0.1.

    Reference: http://www.xfree86.org/current/X.7.html

  6. When I was looking for a way to enable MAC X as an X server over SSH I’ve come accross with your post here. I am very surprised you2ve both used ssh with -X switch and than setup your DISPLAY variable on the remote manually. So I agree with Walt Rice. What you do when you set DISPLAY manually is to route the X traffic over standard TCP/IP but not over the SSH. So in your example yo don’t need to use -X or -Y switch at all. Because what -X or -Y switch does is to create a tunnel over SSH and set the DISPLAY variable to something like localhost:15 this makes sure that the X traffic will be redirected to the remote connection over SSH. But when yous et DISPLAY manually you are obviously disrupting this.

    This is one way side the problem. Another is MAC X (I mean X not 10) does not listen to external X connections by default so you need to enable it to listen to the port 6015 (the default setting is localhost:15) So you have nothing for this too.

    Please check rigorously before posting such an article for it would mislead several users on the web.

    Cheers,
    K.

  7. The reason for this hybrid solution is simple – it works! And it was the only way I was able do X11 forwarding!!

    I cannot get ssh -X or Y to work and set $DISPLAY variable properly on the remote machine.

    Error: Can’t open display:

    And the DISPLAY debug approach above does not bring any solution to this issue!

    What to do?

    Thomas

  8. Its working now! The conventional and right way “ssh -X login@remotehost” Great.. things happen! I think I fucked up the sshd_config file somehow. What a relief.. puha! Especially when you do not know what to look for! Yeah

  9. Hi,

    I guess it will require you to edit your X config file and allow it to listen to the localhost too. Since you can connect to your X when you manually set DISPLAY over the remote system it means that it listens to TCP connections over your Ethernet adapter. But as you know ssh –Y and –X will set the remote display to localhost:10.0 and since you can not launch remote applications there it seems that your X does not listen localhost (127.0.0.1 interface)

    As I’ve told I am not familiar with MacOS. I am not sure where you will need to change. But I’ve found this link:

    http://www.macosxhints.com/article.php?story=20081208062918906

    I hope this helps. What I understand is to see that port 6000 is bound to * not the Ethernet address. (I mean “netstat –na” ouutput)

    Cheers,
    K.

  10. Hello again Kerem,

    Thank you for your valuable comments and suggestions. I have posted your suggestion to solve an eventual “nolisten” problem with Mac OS X Leopard running X11 Forwarding.

    Cheers, Thomas

  11. defaults read org.x.X11 | grep nolisten returned “nolisten_tcp” = 0; which is good – and really shows its working! (see “man defaults” for more info on how to access the Mac OS X user defaults system)

  12. Here is a nifty little hack for the Terminal. I would like the window title of the terminal to reflect the hostname of the current login machine. This shows $HOSTNAME plus the usual stuff by adding the following to your bash profile (~/.profile):

    export PROMPT_COMMAND='echo -ne "\033]0;${HOSTNAME}: ${PWD/$HOME/~}\007"'

  13. FIX!!

    simply type:

    export DISPLAY=mymachine:0

    change mymachine to the host name or ip address 🙂

  14. I have taken a brief look at the debug info you submitted. I believe you only have a setup problem. If possible try to let you Mac OS X computer login on a another clean account on your Linux box. What do the settings file for the sshd deamon look like on your Mac? What kind of password id do you use normally?

  15. Oh, god. All these people who recommend disabling nolisten flag and using ages-old xhost trickery are saboteurs. It is extremely unsafe.

    Just follow the troubleshooting guide in the very first comment (to make sure your DISPLAY variable isn’t overwritten by your scripts) and re-check sshd config on the remote machine. OsX Lion comes with X11 forwading disabled in /etc/sshd_config — so if you are trying to ssh *into it* your DISPLAY won’t be propagated correctly. Same applies to Linux machines — I believe most current distro come with X11 forwarding disabled in their sshd_config. Just re-enable it, restart sshd and it should work.

  16. Well, I’ve also run into a problem running the openSSH server under Mac OS X Mountain Lion. It looks like a problem with Apple’s sandbox – not allowing users to connect to the sshd deamon even thou they have the proper credentials!

    fatal: ssh_sandbox_child: sandbox_init: dlopen(/usr/lib/libsandbox.1.dylib, 261): image not found [preauth]

    If you have heard about this issue or have a solution to this problem please plz keep me posted! BTW: There is a ticket on Mac Ports addressing this issue: https://trac.macports.org/ticket/36291

  17. I have had luck simply disabling the "#UsePrivilegeSeparation sandbox" in the sshd "/opt/local/etc/ssh/sshd_config" config file for openSSH (Mac Port’s version) This works for me! 🙂

  18. Thank you very much, Thomas. I’ll look into it ASAP. I think XQuartz takes care of most of the problems on ML, but I’ll also take into account the tips you’ve provided.

  19. NB! “UsePrivilegeSeparation sandbox” now works! You would be better of to use this setting in sshd_config and restart the ssh service.

    UsePrivilegeSeparation
    Specifies whether sshd(8) separates privileges by creating an unprivileged child process to
    deal with incoming network traffic. After successful authentication, another process will be
    created that has the privilege of the authenticated user. The goal of privilege separation is
    to prevent privilege escalation by containing any corruption within the unprivileged processes.
    If UsePrivilegeSeparation is set to “sandbox” then the pre-authentication unprivileged
    process is subject to additional restrictions. The default is “sandbox”.
    Reference: https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man5/sshd_config.5.html

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

    When X11 forwarding is enabled, there may be additional exposure to the server and to client
    displays if the sshd(8) proxy display is configured to listen on the wildcard address (see
    X11UseLocalhost below), though this is not the default. Additionally, the authentication
    spoofing and authentication data verification and substitution occur on the client side. The
    security risk of using X11 forwarding is that the client’s X11 display server may be exposed to
    attack when the SSH client requests forwarding (see the warnings for ForwardX11 in
    ssh_config(5)). A system administrator may have a stance in which they want to protect clients
    that may expose themselves to attack by unwittingly requesting X11 forwarding, which can war-rant warrant
    rant a “no” setting.

    Note that disabling X11 forwarding does not prevent users from forwarding X11 traffic, as users
    can always install their own forwarders. X11 forwarding is automatically disabled if UseLogin
    is enabled.

    X11UseLocalhost
    Specifies whether sshd(8) should bind the X11 forwarding server to the loopback address or to
    the wildcard address. By default, sshd binds the forwarding server to the loopback address and
    sets the hostname part of the DISPLAY environment variable to “localhost”. This prevents
    remote hosts from connecting to the proxy display. However, some older X11 clients may not
    function with this configuration. X11UseLocalhost may be set to “no” to specify that the
    forwarding server should be bound to the wildcard address. The argument must be “yes” or
    “no”. The default is “yes”.
    Reference: https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man5/sshd_config.5.html

Let me hear what you have to say

This site uses Akismet to reduce spam. Learn how your comment data is processed.