The traditional method of verifying the identity of a host with ssh is to use an ssh host key. In theory, you can get a copy of the host key from your system administrator via some secure method, such as in-person communications or perhaps via cryptographically signed email, before the first time you log into a host. In practice, it is often tempting to log into a host before the system administrator gets around to providing you a copy of the host key via a secure means.
I've found that it's extremely rare for sysadmins to bother to provide host keys; for example, I've mentioned on one group's mailing list that mailing out ssh style host keys or fingerprints in GPG signed email would be a good idea, yet I've only ever seen the fingerprint for one of the hosts mailed out in that way.
I've also seen system administrators be fairly casual about
changing host keys; this can lead to users developing an instinct that
the right thing to do when they see ssh's man in the middle attack
warning is to delete the relevant line of their
~/.ssh/known_hosts file, and try again, which sort of
defeats the point of the known_hosts mechanism.
Kerberos provides another option for verifying host keys, and it seems to work reasonably well. However, among other issues, many sites do not have Kerberos infrastructure deployed. For some, X.509 may also offer a convenient method to verify host keys. It's possible that X.509 certificate support for openssh may exist someday. However, many people find the cost and hassle of getting an X.509 certificate signed by a known certifying authority to be prohibitive, and having each organization or individual run their own CA seems to have issues with distributing the root certificates which are very similar to the issues with distributing ssh style host keys.
The theory here is that lots of people are using the OpenPGP standard to encrypt their email, and that it will be natural for them to also use it for managing host keys. Also, making the exchange of fingerprints useful for verifying ssh host keys might cause some to start encrypting their email.
If you want to use sxw's gssapi patches, get a virgin openssh tree, apply sxw's patches, and then use openssh-gpg-0.9-3.6.1p2-gssapi.patch after verifying the detatched signature openssh-gpg-0.9-3.6.1p2-gssapi.patch.asc
Otherwise, use openssh-gpg-0.9-3.6.1p2.patch after verifying the detached signature openssh-gpg-0.9-3.6.1p2.patch.asc
(There are also old versions that you don't want to use.)
After you apply the patch, you will need to run autoconf of a version sufficiently close to the version used by the openssh developers. If you're using the GSSAPI version, you'll also need to get config.h.in regenerated.
Because this version invokes gpg directly and doesn't depend on any libraries to be able to use gpg, you can compile openssh with gpg support without having to install any special software first, other than this patch. Indeed, gpg itself does not need to be installed at the time you compile openssh.
There is a
--with-gpg option to the
configure script, but it is enabled by default, so you
normally won't need to do anything special there.
On the server side, you need to generate and sign a host key. gpg --gen-key should work; if the server's name is foo.example.com, and if that machine is also known as bar.example.com, you will want to give it an email address of firstname.lastname@example.org, and then add another uid with the email address email@example.com. (You need to make a uid for each fully qualified hostname that ssh client users want to be able to use.) You'll need to supply a full name value of some sort, since otherwise gpg will refuse to generate the key, but it matters little what you put in that full name field, as the current version of the openssh client software ignores it. You need to generate this key without a passphrase, so that the sshd will be able to use it to sign things.
After you generate the key, you will probably want to sign it with at least one real person's primary signing key; make sure you sign all the uids. You should make sure that the copy of the keyring that the sshd will be using has all the sigs on it, since the sshd exports the key and sends it along to the client as part of the ssh protocol.
You'll need to put lines like the following in the config file for
sshd, to specify which key to use, where to find the GPG
binary, and what value of the HOME environment variable should be
passed to GPG:
DSAPGPKeyName firstname.lastname@example.org GPGAbsoluteFilename /usr/local/bin/gpg GPGHomedir /root
You should either use
RSAPGPKeyName, depending on which key type you told GnuPG
you wanted when you generated the key. This implementation will issue
a fatal error if the ssh layer has been incorrectly told about which
encryption algorithm your key uses, since allowing that to work would
appear to be a violation of the relevant RFCs.
The client will only use gpg if you explicitly tell it where to
find gpg. You want to put a line like this in its config file (for
which the per user config file is normally
~/.ssh/config, but you may want to put this in the
systemwide config file instead):
gpgabsolutefilename = /usr/local/bin/gpg
Once you do that, the client will use OpenPGP host keys in preference to traditional ssh host keys where the server offers an OpenPGP host key.
It is possible to specify what home directory to use with the
gpghomedir option, as in the following example; if you omit this, then
the value of the
HOME environment variable is used.
gpghomedir = /home/nemo
It is also possible to use a GPG key to authenticate yourself to the server. To do this, you need to use an RSAPGPKeyName or DSAPGPKeyName option in your client config file, like this:
Then, in the authorized_keys file on the server, use something like this:
pgp-sign-dss 87C36E60187451050A4F26B134824FC95C781A18 foo
87C36E60187451050A4F26B134824FC95C781A18 is the
key fingerprint, and
foo is an optional comment. As the
comment can be omitted, you could also write:
While this version will make sure that the signature is made by the same key that it gets in the import step, and fail otherwise, it does potentially add keys to your keyring every time you run the ssh client. You should be aware that should you hit a man in the middle, arbitrary keys can get added to your keyring. It's not clear, though, that this is actually a problem.
It's not clear that it's desirable to require the user to explicitly specify the path to gpg.
If the host you are connecting to is in the same domain as the
machine you are connecting from, the tcp layer can cope with an
unqualified hostname. However, the current version of the uid
checking code doesn't know how to determine which domain you're using,
so it will fail to allow any connections to unqualified hostnames.
search directive allowed in
makes it unclear that there is a good, secure solution to this problem.
While I'm not aware of security bugs in this code, having a couple of other knowledgeable people look this over for security bugs would be very helpful.
Also, the ssh.com implementation claims that it supports PGP user keys. Testing should be done to verify that this code interoperates with the ssh.com implementation.