Make X11 programs work in an ssh sudo session

Have you ever needed to run an X11 based program like emacs or firefox in a sudo session and received one of the following errors?

This blog describes how to fix the problem.

I needed to solve this problem because there are a number of hosts on my network that do not allow root logins for security reasons. As a result I have to log into these hosts as a non-root user and then create a sudo session to perform administrative functions. Furthermore, I often do this remotely via XRDP, VNC or FreeNX through an ssh tunnel (or VPN) so there can be multiple credentials set.

To run an X11 based tool, I need to set the proper X credentials in the sudo session. I used to do this manually by manually looking up the xauth list for the original login and then adding them using xauth add in the sudo session but I recently figured out how to make it work with a single command.

1 Steps

The basic steps are:

  1. Login into the remote host. Make sure that X11 forwarding is enabled. I tend to use trusted forwarding which is why you see -Y instead of -X.
    ssh -Y user@host
  2. Create the sudo session by logging in with
    sudo user -
  3. Grab the X credentials for the original user. There can be many of them which is why the next step filters out the one we want.
    su - user -c "xauth list"
  4. Filter out the credential that we want using grep by looking for matches based on the DISPLAY environment variable. The extracted string used in the grep pattern match will be something like :10.
    grep `echo $DISPLAY |\
         cut -d ':' -f 2 |\
         cut -d '.' -f 1 |\
         sed -e s/^/:/`
  5. Enable the credentials for this session using the xauth add command. The xargs command says to take the first 3 arguments and pass them to the xauth add command.
    xargs -n 3 xauth add

Another option suggested by “scott e” on 2013-10-28 is to use the command “xauth -f ~user/.Xauthority” command which simplifies things. Here are the steps based on the new idiom:

  1. Login into the remote host. Make sure that X11 forwarding is enabled. I tend to use trusted forwarding which is why you see -Y instead of -X.
    ssh -Y user@host
  2. Create the sudo session by logging in with
    sudo user -
  3. Enable the credentials for this session using the “xauth -f ~user/.Xauthority” command.

2 Example

Here is an example that shows how it works.

Note that I used compression level 7 because this example was taken from a remote session where I experimentally determined that it improved performance. Before setting a compression level, you should verify that it really does improve performance. Often it doesn’t help.

Enjoy!

21 thoughts on “Make X11 programs work in an ssh sudo session”

  1. I improved the command a bit to allow cut-and-paste without the need to adapt the user name by using the SUDO_USER environment variable:


    su - $SUDO_USER -c 'xauth list' |\
    grep
    echo $DISPLAY |\
    cut -d ':' -f 2 |\
    cut -d '.' -f 1 |\
    sed -e s/^/:/
    |\
    xargs -n 3 xauth add

    Tested on Debian/Ubuntu installations.

    1. This works if sudoing to “root” (the default), but it will definitely not work if using for example

      % sudo -u -E xeyes
      No protocol specified
      Error: Can't open display: :0

  2. Thank you Daniel, but you forgotten the sign; I correct it:

    su - $SUDO_USER -c 'xauth list' |\
    grep
    echo $DISPLAY |\
    cut -d ':' -f 2 |\
    cut -d '.' -f 1 |\
    sed -e s/^/:/
    |\
    xargs -n 3 xauth add

     

    Or if you like a single line command:

    su - $SUDO_USER -c 'xauth list' |grep echo $DISPLAY |cut -d ‘:’ -f 2 |cut -d ‘.’ -f 1 |sed -e s/^/:/` | xargs -n 3 xauth add

     

    Thank you all for the valuable help!

  3. Thank you Daniel, but you forgotten the sign:

    disappears if you do not enter it in a “code box”

    Here is the command again:

     

    Or if you like a single line command:

    Thank you all for the valuable help!

  4. $SUDO_USER is not present on my system. instead, I use:


    su -
    logname -c 'xauth list' |\
    grep echo $DISPLAY |\
    cut -d ':' -f 2 |\
    cut -d '.' -f 1 |\
    sed -e s/^/:/
    |\
    xargs -n 3 xauth add

  5. Put this in root’s .bash_functions, .bashrc, or .bash_profile:

    Then just use

  6. similar to scott e’s solution i was hoping to just run a single sudo command rather than create a root shell.
    what i ran across in the xauth man page is that it uses an environment variable XAUTHORITY to trump which authority file to use. tried out the following, and my app launched as root

     

  7. This page was great with all the ideas.  I was looking for something I could script for multiple users, and it seems with the combination of your ideas one could do this:

    export XAUTHORITY=$(eval echo ~$(logname)/.Xauthority)

    The only problem is it would only work if you sudo to root, unless you want to make your .Xauthority file readable by any user.

    Thanks everyone!

Leave a Reply

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