This document is intended to provide a brief overview of the function and common usage of LSH, references lsh-0.9.10, and assumes a working knowledge of rsh, the unencrypted equivalent of lsh.
If you're looking for a FreeBSD port of LSH, I've got an initial port that I'm working on.
LSH is an implementation of the SECSH protocol, which has the goal of secure, encrypted logins. This means that you should be able to log into remote machines, knowing that the machine you connect to is the machine you think it is, that that machine knows you are who you claim you are, and all communications are shielded from eavesdropping. Since SECSH does not require any encumbered encryption algorithms, LSH was able to be implemented as GPL code. This is an advantage over the SSH1 protocol, which is encumbered by the RSA patent, and SSH 2, which is a non-free SECSH implementation.
LSH has a minimal web site at http://www.net.lut.ac.uk/psst/ and is available by http at http://www.lysator.liu.se/~nisse/lsh/, and it is also available via ftp at ftp://ftp.lysator.liu.se/pub/security/lsh. The PSST mailing list is one source of support, and is archived at http://www.roads.lut.ac.uk/lists/psst/.
SECSH provides secure communication by a combination of encryption and authentication.
The SECSH homepage is at http://www.ietf.org/html.charters/secsh-charter.html, and is documented in draft-ietf-secsh-architecture-04, draft-ietf-secsh-transport-06 draft-ietf-secsh-userauth-06, draft-ietf-secsh-connect-06, and draft-ietf-secsh-auth-kbdinteract-00. (fix to not go through normos)
Much of the trust in SECSH (and pgp as well) is based on public key cryptography. The idea of public key cryptography is to use an algorithm where data can be encrypted by a key, and decrypted by a different key. It is important that data encrypted by one key cannot be decrypted by the same key.
Using this method, an identity (host or user) will have two keys, one public, and one private. In most encryption algorithms, the public key can be computed from the private key quite easily, but the private key would require large amounts of computational horsepower to be computed from the public key. Because of this, the public key can be freely given to anyone, but the private key must be protected to the extent indicated by the sensitivity of the data.
Data encrypted with the private key can be decrypted by anyone with the public key, so it would not be considered private communication. On the other hand, no one without the private key could create a message that the public key would decrypt, so having a message (or the checksum of a message) that decrypts is proof that the sender of the message has the private key. This is commonly referred to as "signing."
Data encrypted with the public key can only be decrypted by someone with the private key, so is considered private. However, since anyone could have the public key, there is no proof here of who sent the message.
Because of this, if you know that you have the correct public key for an entity, you can encrypt the message with their public key, and trust that the message will be useless to anyone that does not have the entity's private key, or you can decrypt a message encrypted with the private key, and trust that the message came from someone with the private key.
Normal public key cryptography consists of the trusted exchange of public keys, on the assumption that either communication will be impossible, or the signing will not verify. In the case of SECSH, signing is used to verify identity, but the actual encryption is done using symetrical encryption algorithms, with the keys determined by key echange algorithms. SECSH allows for multiple key exhcnage algorithms, but only Diffie-Hellman currently defined.
Because LSH is an implementation of SECSH, it provides the basic authentication and encryption functions of SECSH. It works well enough to inter-operate with SSH 2.0, for those functions that it has implemented. There may be a few last issues involved in the compression layer. Port forwarding is under development, so may not be stable at this time. (status of port forwarding)
LSH cannot make an untrusted client or server machine into a trusted one. This is not a limitation of the LSH implementation of SECSH, but rather a limitation of the nature of the problem. If you are using a machine that you do not trust as either the client or the server, it is possible that you could be monitored, and if you're using an untrusted client machine, it is possible that someone on your local machine could fake your identity to other machines. This problem is furthered by the fact that private keys are not pass phrase protected by LSH at this time.
At this time, LSH does not implement SPKI certificate chaining, so trust of a certificate cannot be established by following the certificate chain back to a trusted certificate.
LSH does not include the scp/sftp features of either version of SSH, as they are not documented standards.
Not always fully stable, but quite usable. lshd and lsh will occasionally die, so if you are depending on LSH, you should run lshd in such a way that it gets re-spawned if it does die.
LSH functions quite similar to rsh. The command lsh can be used to log into a server machine or to remotely execute commands on the server machine, and similar to rsh, can be configured so that for specific users to specific servers, this can be done without entering passwords.
Assuming that it has been set up on both the client machine and the server machine, including any necessary authorization, lsh can simply replace rsh on the command line, baring rsh command line options involving kerberos or other features lsh does not implement.
Typical LSH usage consists of setting up a number of users and servers, where each user knows the signature of each of the server's public keys, and each server knows the signature of each user identity that is to be trusted as a given user without password confirmation.
Normally, a user will have a separate identity for each machine that user works on. An identity is created by running the following command on that machine, as that user.
lsh_keygen -l 8 | lsh_writekey
This creates a cryptographic identity pair in ~/.lsh consisting of both the
public and private keys. Doing this more than once will overwrite the
existing identity, so it shouldn't be done unless you will not be using the
old identity any more.
As tempting as it may be to copy the identity files to every machine that you use LSH on, this is not good in practice. If any of the machines have a security violation, your only identity has been compromised. Furthermore, the act of moving the private key to another machine may risk exposure of the private key. If you absolutely must move the private key, do so only over a trusted, secure channel, such as a floppy disk hand carried to each machine.
All LSH servers must have a key generated. This is normally done with the command
lsh_keygen -l 8 | lsh_writekey NEW_KEY
which creates the file NEW_KEY and NEW_KEY.pub. The NEW_KEY file is the
private key, and should be protected as much as reasonable. The private key
can be used either by specifying it on the command line with the --host-key
option, or by copying it to the default location, /etc/lsh_host_key. As a
courtesy to LSH users, you can also run the command
sexp_conv <NEW_KEY.pub --once --hash sha1 --raw-hash
to get the fingerprint for the host key. How to distribute this fingerprint
to LSH users is entirely up to you.
The purpose of host authentication is to make sure that the machine you're connecting to is really the machine you think you're connecting to. While this may not seem like much of an issue, if you don't use host authentication, then any router between the two machines could be used for a man-in-the-middle attack. Now, suddenly instead of needing to trust two machines, you have to trust more machines, potentially dozens.
A man-in-the-middle attack is simple, if you control a machine that routes between the client and the server. By intercepting the communication at the very start, the attack machine can provide fake public keys to each end of the communication. By providing public keys that correspond to private keys known to the attack machine, the attack machine can monitor the communications by decrypting each message, examining it, then re-encrypting it with the corresponding private key.
Host authentication prevents this type of attack, by ensuring that the machine requesting the connection knows what the public key of the server machine looks like. This way, if an attack is attempted, the attack will be detected, because the public key will not look right.
Setting up host authentication consists of three steps.
lsh --sloppy-host-authentication hostname
This will
capture the server's public key to the file ~/.lsh/captured_keys. It will
also display the fingerprint of the server's public key, and prompt the user
if they trust the key with that fingerprint.
User authentication can be handled two ways. The first is by establishing a user identity, and authorizing that identity on the host that you are connecting to. This is similar to, but more secure than, adding an entry to the user's .rhosts file.
Public key authentication works by using both parts of the generated identity. When the connection is started, the client will transmit the public key portion of the identity to the server. The server will then create a checksum of the public key, check to see if that checksum has been authorized, and check that some data from the client program was signed by the matching private key. If everything looks right, the user is considered authorized without need of a password.
By creating a file with the name of the sha1 checksum of the public key of the identity, that identity is allowed to login in via lshd from any host. The file can be empty, though lsh-authorize places the canonical form of the public key within the file, so this may not always be the case. This can be most easily achieved with the command line:
lsh-authorize pub-key-file
The second method of user authentication is password entry. In this case, the user is prompted for their password. This can be done either by not creating an identity, not authorizing the identity, or by use of the --no-publickey option to lsh.
NOTE: At least under FreeBSD, and possibly other OS, a failed identity check can cause lsh to crash before password authorization is attempted. Use the --no-publickey option to lsh if this is a problem. This seems to have been fixed in 0.9.5, and broken again sometime between 0.9.5 and 0.9.10.
NOTE: Under some OS, including FreeBSD, password authentication can only be used if lshd is run as root.
NOTE: If you use public key authorization, then anyone that obtains your key pair can pass for you. This means that if someone breaks into root or your login on a machine, they can go anywhere without a password that you could go without a password.
NOTE: The FreeBSD /bin/sh has problems with lsh that seem to be caused by the fact that lsh leaves the tty in non-blocking mode. This is the only shell I've tested that has this problem, however.