South Park is a hilarious show, and I think that Cartman is the best character.  One of Cartman’s classic lines is “YOU WILL RESPECT MY AUTHORITAH!#!”

So Cartman wasn’t a unix geek and wasn’t talking about X11 Forwarding / SSH, but maybe there is a moral to the story.

You have to execute some sort of GUI program on a remote host and it requires root access in order to execute (or you have to change to a different user to execute the GUI with correct permissions)… 

At first, when you logged into the machine for the first time without X11 forwarding enabled, your ~/.Xauthority file doesn’t exist…

cartman@locutus:~$ ls -l ~/.Xauthority
ls: /home/cartman/.Xauthority: No such file or directory

So you log back out, and when you ssh back into the remote machine, you remember to forward X11 by issuing..

$ ssh -X <user>@<remote box>

i.e.

$ ssh -X cartman@locutus
Linux locutus 2.6.22-14-generic #1 SMP Sun Oct 14 23:05:12 GMT 2007 i686
cartman@locutus:~$ xclock

Sure enough, you fire up /usr/bin/xclock (or /usr/openwin/bin/xclock) and verify that the GUI program displays back on your local desktop.  

cartman@locutus:~$ echo $DISPLAY
localhost:10.0

Sweet.  Next, when you change users..

cartman@locutus:~$ su -
Password

:
root@locutus:~# id
uid=0(root) gid=0(root) groups=0(root)


root@locutus:~# xclock
Error: Can’t open display:

 

you loose your X11 forwarding.  DOH!

So whats the solution here?  You can’t log in directly to the box as the root user (this should always be disabled.  Its really bad practice if it isn’t) — and you don’t really want to throw a SSH key into /root/.ssh/authorized_keys for obvious reasons — so what’s there to do?

When you SSH into a machine with X11 forwarding, it opens a TCP port, tunnels it through SSHD, and stores this information into a MIT cookie file in your home directory called ~/.Xauthority

All we have to do is “move” this information along with us when we change users.  We can use the xauth command to manipulate this for us.  First, lets display what the value of our cookie is.  Note the :10 matching up to our $DISPLAY variable…

cartman@locutus:~$ xauth list
locutus/unix:10  MIT-MAGIC-COOKIE-1  e2cba22d040f0e75dcbd203ee40736de

Now lets change users..

cartman@locutus:~$ su -
Password:

root@locutus:~# ls -l /root/.Xauthority
ls: /root/.Xauthority: No such file or directory

root@locutus:~# xauth list

So no MIT cookies currently exist… That makes sense because we didn’t X11 port forward into the root account.. Lets add one.  Don’t forget the “/unix” after the FQDN..
root@locutus:~# xauth add locutus/unix:10 MIT-MAGIC-COOKIE-1
d203ee40736de0e75dcb

xauth:  creating new authority file /root/.Xauthority

Exceeeelent….
root@locutus:~# xauth list
localhost/unix:10  MIT-MAGIC-COOKIE-1  e2cba22d040f0e75dcbd203ee40736de

We’re not done yet… The last thing we have to do is to set our $DISPLAY variable to the same display as above..  Right now it may be set to null…

root@locutus:~# echo $DISPLAY

root@locutus:~# xclock
Error: Can’t open display:

So lets set it to localhost:10.0

root@locutus:~# export DISPLAY=localhost:10
root@locutus:~# xclock

Sure enough, we get xclock to display.  We didn’t have to be the root user in this example.  Any local user could perform the same function.

Alternativly, xauth also has a “merge” function to where you can read an existing ~/<user/.Xauthority file to merge with another.  This really is only going to work for the root user (unless you chmod) because the permissions on this file is octal 600…

root@locutus:~# ls -l /home/cartman/.Xauthority
-rw——- 1 cartman cartman 53 2008-04-05 00:22 /home/cartman/.Xauthority

Lets remove the previous Xauthority we had in place…

root@locutus:~# xauth list
locutus/unix:10  MIT-MAGIC-COOKIE-1  e2cba22d040f0e75dcbd203ee40736de

root@locutus:~# xauth remove locutus/unix:10

 

And then we’ll use the merge function pointing at a specific .Xauthority file…
root@locutus:~# xauth merge /home/cartman/.Xauthority

Sure enough, it imported correctly..

root@locutus:~# xauth list
locutus/unix:10  MIT-MAGIC-COOKIE-1  e2cba22d040f0e75dcbd203ee40736de

Our DISPLAY variable matches the display above and xclock starts up without any errors.
root@locutus:~# echo $DISPLAY
localhost:10
root@locutus:~# xclock

 

When xauth is invoked without any options, it brings up a menu based configuration utility thats pretty neat… Here’s “xauth info” in action…

root@locutus:~# xauth
Using authority file /root/.Xauthority
xauth> help
    add dpyname protoname hexkey   add entry
    exit                           save changes and exit program
    extract filename dpyname…    extract entries into file
    help [topic]                   print help
    info                           print information about entries
    list [dpyname…]              list entries
    merge filename…              merge entries from files
    nextract filename dpyname…   numerically extract entries
    nlist [dpyname…]             numerically list entries
    nmerge filename…             numerically merge entries
    quit                           abort changes and exit program
    remove dpyname…              remove entries
    source filename                read commands from file
    ?                              list available commands
    generate dpyname protoname [options]  use server to generate entry
    options are:
      timeout n    authorization expiration time in seconds
      trusted      clients using this entry are trusted
      untrusted    clients using this entry are untrusted
      group n      clients using this entry belong to application group n
      data hexkey  auth protocol specific data needed to generate the entry

xauth> info
Authority file:       /root/.Xauthority
File new:             no
File locked:          no
Number of entries:    1
Changes honored:      yes
Changes made:         no
Current input:        (stdin):2

There are also all sorts of security implecations surrounding ~/.Xauthority where the root user or administrator could hijack X11 sessions.  This article is a great read and I suggest taking a look at it when you have a chance.  It also goes into better detail on the steps of how the X11 forward occurs and security hazards surrounding it.

 

Posted by mike, filed under OpenSSH. Date: April 5, 2008, 1:09 am | 4 Comments »

I just looked over the sshd 4.9 release notes, and came across this gem:

* Added chroot(2) support for sshd(8), controlled by a new option
   "ChrootDirectory". Please refer to sshd_config(5) for details, and
   please use this feature carefully. (bz#177 bz#1352)

This is awesome, and should negate the need to use pam_chroot! Nice!

Posted by matty, filed under OpenSSH. Date: March 31, 2008, 5:23 pm | No Comments »

Last week I set up several Linux and Solaris hosts to use key based authentication. For some reason two of the hosts continued to prompt me for a password, even though the server and client were configured correctly to used DSA keys (I was using the same config on all of the servers, so I knew it worked). When I traced the sshd daemon on one of the hosts that was misbehaving, I saw the following just before the password prompt was displayed:

$ strace -f -p `pgrep sshd`
<.....>
stat(”/home/matty/.ssh/authorized_keys”, {st_mode=S_IFREG|0664, st_size=1026, …}) = 0
open(”/home/matty/.ssh/authorized_keys”, O_RDONLY) = 4
lstat(”/home”, {st_mode=S_IFDIR|0755, st_size=4096, …}) = 0
lstat(”/home/matty”, {st_mode=S_IFDIR|0700, st_size=4096, …}) = 0
lstat(”/home/matty/.ssh”, {st_mode=S_IFDIR|0700, st_size=4096, …}) = 0
lstat(”/home/matty/.ssh/authorized_keys”, {st_mode=S_IFREG|0664, st_size=1026, …}) = 0
lstat(”/home”, {st_mode=S_IFDIR|0755, st_size=4096, …}) = 0
lstat(”/home/matty”, {st_mode=S_IFDIR|0700, st_size=4096, …}) = 0
fstat(4, {st_mode=S_IFREG|0664, st_size=1026, …}) = 0

The strace output made me realize that $HOME/.ssh might not be set to 0700, or the authorized_keys file might not be set to 0600. It turns out the permissions on both entries were set incorrectly, and after adjusting the permissions (which got borked by an incorrect umask entry in /etc/profile), everything worked as expected. As a side note, I am curious why the SSH daemon doesn’t log the permission errors when run with multiple debug flags. This would make a fantastic RFE! :)

Posted by matty, filed under OpenSSH. Date: April 12, 2007, 4:06 am | 2 Comments »

With the introduction of OpenSSH 4.3p2, Darren Tucker introduced the “Match” keyword. This super nifty keyword can be used to limit features to specific users, hosts and groups, and allows administrators to enforce granular feature access (e.g., key-based authentication can only be used from specific hosts or subnets). To use the Match feature, the Match directive needs to added to the sshd_config configuration file with a criteria to enforce, and a set of directives to allow or deny. The Criteria can be either “User,” “Group,” “Address,” or “Host,” and wildcards are supported when the Host criteria is used. The following example shows how the Match keyword can be used to limit TCP port forwarding and X11 port forwarding to the user stew:

AllowTcpForwarding no
X11Forwarding no

Match User stew
         AllowTcpForwarding yes
         X11Forwarding yes

The full list of directives that are supported inside a Match block are listed in OpenSSH bug #1180. This is an incredible feature, and something I have wanted for years. Thanks Darren for adding this!

Posted by matty, filed under OpenSSH. Date: September 5, 2006, 10:08 pm | No Comments »

If you use SSH to access remote servers, the ssh client will prompt you each time you connect to a new server, and ask you to accept the servers host key:

$ ssh mail.me.net

The authenticity of host 'mail.me.net (1.2.3.4)' can't be established.
RSA key fingerprint is 72:c6:5f:e7:85:c8:23:5f:c6:c9:99:88:dd:aa:bb:dd.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'mail.me.net,1.2.3.4' (RSA) to the list of known hosts.
matty@mail.me.net's password:

How do you determine if the fingerprint presented is valid? The easiest way to validate the key is to login to the server through the console and run the ssk-keygen utility with the “-l” (list fingerprint) and “-f” (file to check) options:

$ ssh-keygen -l -f /etc/ssh/ssh_host_rsa_key
2048 72:c6:5f:e7:85:c8:23:5f:c6:c9:99:88:dd:aa:bb:dd ssh_host_rsa_key.pub

If you can’t access the console, you can ask someone who already has access to read off the ssh-keygen output. While it’s a bit of a pain, it is a small step in the name of secure access.

Posted by matty, filed under OpenSSH. Date: July 15, 2006, 9:01 am | No Comments »

I have a small lab at home, and periodically need to gain console access to one or more of the machines. Since I don’t have a KVM switch or a monitor to devote to each machine, I will typically hook up a serial cable to port A on machine one, and serial port B on machine two. Once the connection is in place, I use minicom or tip to connect to node one once I establish an SSH session to node two. Since tip and SSH both default to using “~” as the escape character, issues will arise if you need to send a break remotely. To avoid this issue, I always use the ssh client’s “-e” (escape character to use) option to set an escape character that doesn’t conflict with tip:

$ ssh -C -e ^ host

This caused me some grief today, since the box I was SSH’ed into didn’t have my .profile installed (my default profile contains an ssh alias with “-e”). Tip is c-well!

Posted by matty, filed under OpenSSH. Date: March 21, 2006, 7:38 pm | 2 Comments »

I was reading through O’Reilley’s OnLamp today, and came across their interview with the OpenBSD developers. In the interview, Dave Miller discussed the new features in OpenSSH 4.X, and described the following awesome new feature:

Added the ability to store hostnames added to ~/.ssh/known_hosts in a hashed format. This is a privacy feature that prevents a local attacker from learning other hosts that a user has accounts on from their known_hosts file.

So instead of hostnames being stored in plain text like:

> yourhost.example.com ssh-rsa
AAAB3NzaC1yc2EAAAABIwAAAIEAp832eeMwYH…

They are hashed first, so they don’t reveal the hostname. E.g.:

> |1|bRGYyrC+bfKZGGd5GZH4wo1AnsI=|xcQ+54QNVwQ+fBCldn0= ssh-rsa
AAA…

We added at the request of some MIT researchers who found that a substantial number of user private keys on shared systems are not encrypted (a really dumb thing to do, BTW). This lack of user care, coupled with the information in the known_hosts files, allowed attackers to spread their attacks to multiple systems.

Right now this is disabled by default, but administrators of sites with lazy users can turn it on with the HashKnownHosts
config flag.

If you do this, you should probably also hash your existing known_hosts file (ssh-keygen -H).

I sometimes think I am the only person that uses ssh-agent to store private keys in memory, and strong complex passwords to protect keys on disk. While a competent attacker would use a packet analysis tool to find SSH destinations, this may protect admins in select situations.

Posted by matty, filed under OpenSSH. Date: October 13, 2005, 1:05 am | No Comments »

Ever wonder how you can tunnel web and AIM traffic securely from one location to another? This can be accomplished with ssh’s “-D” option. This allows traffic to be sent securely over a SSH session, and routed out through a remote endpoint. This looks like:

Firefox/GAIM < -- HTTP/AIM--> loopback:PORT < -- SSH --> REMOTE END < -- HTTP/AIM --> Internet

To create a local proxy on TCP port 8000, we can pass the value 8000 to the “-D” option:

$ ssh -C -D 8000 -p 443 ick@ick.net

Once the SSH connection is established, you need to configure your client (e.g., firefox, gaim) to proxy connections to the loopback interface on TCP port 8000. Once your clients are configured to use the localhost.8000 listener, all application traffic will be sent securely through your ssh session, and routed through the Internet connection on the remote end.

Since most web proxies tunnel secure connections, you can setup your remote endpoint to accept SSH connections on TCP port 443. This is amazingly useful for routing around corporate firewalls and proxies. You don’t want to get caught looking for jobs while your at work, right? ;)

Posted by matty, filed under OpenSSH. Date: February 18, 2005, 11:40 pm | No Comments »