Secure Shell Logins and Mac OS X Part 1
By Damien Gallop

January 12th, 2002

During his first Macworld keynote of the year, Steve Jobs announced that as of that moment all new Macs would boot up OS X by default. That was a watershed moment for Apple. Beauty, power, security, and industry support are all there. Mac OS X is poised to be the greatest operating system ever.

You see, Mac OS X is a unix operating system at its core. Hence it can use all of the available unix tools out there, including the built-in secure shell tools. With the right configuration, OS X can login to other unix hosts seamlessly. Let's look at that today, then apply the principles to some real-world examples next week.

In this article I assume you have a comfortable facility around the unix command prompt. If you like, please feel free to browse my article The Mac OS X Shell, by way of introduction, and other sources you might have at hand.

Secure shell, SSH, is one application of the secure sockets layer, or SSL for short. "OpenSSL is a library that provides cryptographic functionality to applications such as secure web servers," whereas "OpenSSH is a free version of the SSH protocol suite of network connectivity tools that increasing numbers of people on the Internet are coming to rely on." When considering the two, keep in mind that "OpenSSH requires at least version 0.9.5a of the OpenSSL libraries (ibid.)." Available versions of both OpenSSL and OpenSSH for OS X are free downloads from OSXGNU if you choose to use these in lieu of the OS X native versions. It appears to be possible to connect over SSL with a Windows host also if you purchase the right software, such as Omni-NFS.

SSL and applications made with it are all about connecting between compatible hosts securely across an encrypted connection. The encryption is done at the client end, and decryption on the server. Just who is the client and who is the server at any given moment depends on the context. Never mind that right now. Encryption is done with public and private keys. Keys are a high-tech variation on the very old concept of passkeys. Each of the two parties holds a key, both of which are required for unlocking.


Case Study: Automated Secure Shell Logins

In this study, I will relate my own experience using secure shell, or ssh, in my workplace. I routinely connect between different unix hosts, and automating that experience saves a lot of fiddling. Here are sets of hosts between which I connect automatically. The details are mainly for future reference. My main point here is to demonstrate seamless secure connectivity between dissimilar hosts. They're all some variation of unix.

Local host: Mac OS X running OpenSSH v3.0p1
Remote host: Linux running OpenSSH v2.9p2
Generate keys on local machine with ssh-keygen -b 2048 -t dsa
Keys get placed into ~/.ssh/id_dsa & id_dsa.pub
Sftp to remote host, and put id_dsa.pub into ~/.ssh
Append id_dsa.pub to ~/.ssh/authorized_keys2 using cat id_dsa.pub >> authorized_keys2.

Local host: Mac OS X running OpenSSH v3.0p1
Remote host: Ultrix running OpenSSH v2.5.1p2
Generate keys on local machine with ssh-keygen -b 2048 -t dsa
Keys get placed into ~/.ssh/id_dsa & id_dsa.pub
Sftp to remote host, and put id_dsa.pub into ~/.ssh
Append id_dsa.pub to ~/.ssh/authorized_keys2 using cat id_dsa.pub >> authorized_keys2.

Local host: Ultrix running OpenSSH v2.5.1p2
Remote host: Linux running OpenSSH v2.9p2
Generate keys on local machine with ssh-keygen -b 2048 -t dsa
Keys get placed into ~/.ssh/id_dsa & id_dsa.pub
Sftp to remote host, and put id_dsa.pub into ~/.ssh
Append id_dsa.pub to ~/.ssh/authorized_keys2 using cat id_dsa.pub >> authorized_keys2.

Local host: Linux running OpenSSH v2.9p2
Remote host: Ultrix running OpenSSH v2.5.1p2
Generate keys on local machine with ssh-keygen -b 2048 -t dsa
Keys get placed into ~/.ssh/id_dsa & id_dsa.pub
Sftp to remote host, and put id_dsa.pub into ~/.ssh
Append id_dsa.pub to ~/.ssh/authorized_keys2 using cat id_dsa.pub >> authorized_keys2.

Now I can login securely from home to either of these Ultrix and Linux machines, or between the latter two in either direction, all without ever entering a password. What's more, not only is my login information encrypted, the entire session is also.


Command Details

If you have another OS X or other unix host to which you network frequently, I'll assume you too would like to implement seamless logins. First, get a pen and paper. You need to know a few details about each machine you're working with. On your local machine, presumably a Mac running OS X, open a Terminal and type ssh -V (capital v) to get its version. Make a note of it. If it's one of the flavors and versions above, you'll know what to expect. If not, that's fine. Now type man ssh to bring up the manual. Press the spacebar to page through. Look for references to SSH2, which is what you want. You should find file names and paths similar to the case study. Do the same for ssh-keygen. In all of this you want to be using ssh2, and all of the above hosts in my examples support it.

If you are using the default ssl collection on OS X, then there are two separate sets of programs for SSH1 and SSH2. Type ssh-keygen2 -b 2048 to generate a 2048-bit key pair in your ~/.ssh2 folder. If you are using an OpenSSH version, then enter ssh-keygen -b 2048 -t dsa to generate a key pair in ~/.ssh. In all cases, you will be prompted for a passphrase. Just press Enter. If you use a passphrase, you'll be queried for it at login time, which will defeat the purpose. Make a note of the key names. I like to rename my public key to something that identifies where it came from, e.g. id_dsa.home.pub.

Next, ssh to your remote host. Query it for its version of ssh and check the man pages. Make a note of where it expects to find public keys. In all likelihood, it will be one of the two folders, ~/.ssh or ~/.ssh2. You may have to create this folder if none of this has ever been done before. Use mkdir .ssh from your home directory, chmod 700 .ssh to lock down permissions, and cd .ssh to go there. The command cd ~ will take you home and exit will log you off when we're done shortly.

Now open a second Terminal or Xterm session, and cd .ssh into your local keys folder. Next, type sftp damien@remotehost to connect to the remote host. Type cd .ssh within your sftp session. Now you are in the keys folders on both machines. Type put id_dsa.pub or whatever, to put your public key onto your remote host. Type exit when done.

From the first session, already logged into the remote host, add your new public key to the keys file with cat id_dsa.pub >> authorized_keys if an OS X host, or cat id_dsa.pub >> authorized_keys2 if a Linux host running OpenSSH. Check the remote host's man pages on ssh for the exact file name in your situation. Remember, some versions of ssh may require using the ~/.ssh2 directory instead.

With a bit of luck, that's all you need to do, though with some versions of ssh you may have to add an entry to a pointer file such as ~/.ssh2/identification, documented in the man pages. Next time you ssh to that host from your local machine, it'll just connect. No fuss, no muss.


X Window Display Forwarding

The man pages for ssh tell me that X11 forwarding of X window displays is on by default. But I found I had to set it on explicitly. The global configuration file is /etc/ssh_config for OpenSSH, and /etc/ssh2/ssh2_config for the Mac OS X default version. The line you need to add is ForwardX11 yes, which you can do with echo ForwardX11 yes >> ssh_config, so long as its opposite does not appear earlier in the file. I used vi to edit the file, and made some other tweaks as well. You can use any text editor, though.

Previously I had recommended adding the line setenv DISPLAY :0.0 to your ~/.login file. I needed that little line because my ssh server was not forwarding X11 stuff. Now it does, and I no longer need the workaround. I simply changed the line X11Forwarding no to yes in the text file /etc/sshd_config, and removed the above line from .login. However, fixing this causes one other entirely logical side effect. You can't open X applications from Terminal if sshd starts before your X server (XDarwin) at boot time, which it always does. To fix this, add the following three "if then endif" lines to the text file /usr/share/init/tcsh/rc, which is the object of the shell configuration file, /etc/csh.cshrc, by the way. This file gets referenced each time you open a new Terminal window.

...stuff...
setenv HOST "${host}"
setenv USER "${user}"
if (! $?DISPLAY) then # added for sake of X11 displays in Terminal by DMG
setenv DISPLAY :0.0
endif
...more stuff...

The additional code checks for the existence of a value for the DISPLAY variable, and if none then assigns it the local display address. If DISPLAY already has a value by this point, then it was assigned to it by sshd as part of a remote login. I am certain that there are other ways to do this, particularly if you choose to use a different shell. Go for it. Keep in mind that, whatever you do, future OS X updates may overwrite the file.

Getting ssh up and running, then getting it to forward graphic displays properly are the principal ingredients. We can tweak a few things for effect, and we will. Meanwhile, you're up. If you have your X server running, then test your login's graphical wizardry with a simple application such as xeyes or xclock, available on every unix machine I've ever played with, and that's a few. Next time we'll put these automated logins to work. Ciao.