Central Access Management for SSH |
Part 6 of Global Directory
The undebated cornerstone for secure access to remote shells and remote filesystems is SSH. This system is both used inside and accross security realms. In general, crossing boundaries implies changing operational control, which introduces a security management problem. When keys are accepted locally on various hosts but no central overview or management is available, access control tends to get sloppy and thus leaky. Recent additions to OpenSSH provide an interesting angle for mending that through the global directory.
This article is part of a series of articles about the global directory.
Starting with version 6.2, OpenSSH includes an AuthorizedKeysCommand configuration option, which causes the ssh daemon to not read the authorized_keys file from disk, but to run a command that produces such a list. The most requested approach here is to retrieve it from LDAP, which then usually is a locally maintained directory. This already solves the problem of central coordination of who may access what account on which server.
One further problem is not yet addressed this way. Remote consultants may be granted access, but never get it retracted. When the consultant's laptop is stolen, his key should be retracted too, but he generally lacks a careful administration of where which of his keys have gone. If however, his SSH keys are normally stored in his node on the global directory, then the in-house LDAP tools at the sites that he worked for can establish that he has retracted a key, and remove it from their internal list of trusted SSH keys.
How this works
The most general model for a global OpenSSH infrastructure is when a person ("consultant") under one operational domain (the "maintenance party") needs to access a server (the "target server") under another operational domain (the "client"). In this setup, trust has to cross the operational domains, and both will want to manage the keys centrally:
- The consultant uses a key that is published as reliable by the maintenance party; when the consultant leaves the business or his SSH key is compromised, his key would be retracted by the maintenance party, even if the key continued to be used; this would necessarily have to be done without knowing all the clients that rely on the key.
- The client configures access to individual host/account combinations in a central repository, and permits access to particular SSH keys. These keys refer to a public location at the maintenance party so they can be verified somewhat regularly.
Both the maintenance party and the client run an LDAP service containing SSH keys in the format of an authorized_keys line. The client may of course have added options that restrict access. Furthermore, the comment in the client's version refers to the directory location where the key can be verified in the LDAP service of the maintenance party. A regular check run by the client ensures that the consultant's SSH key is still welcome because it is still published by the maintenance party.
A slightly less general situation is when the "consultant" is actually an internal employee member. In those cases, it is still valid to follow this approach, but the "remote" LDAP service would actually be the local service, and the reference annotated in the SSH key is probably a personell record that published the key. Again, in case of key loss the SSH key could be removed from a single location only to (eventually) clean up all dependencies.
Protecting SSH Keys from Publication
Not everyone will appreciate publishing their SSH Keys to everyone in the World. This can easily be solved, because the locations of the keys are stored alongside the keys by the relying parties (or "clients"). The means that a hard-to-guess location (with a random RDN) can be used to publish the SSH Key. In addition, the attribute name of the RDN could be setup as only-visible-when-requested with the "razor" overlay.
For example, publish the SSH key at the following location,
uid=7035801d1042c56cc3cd9cd0ad1e4569,ou=Reliable SSH Keys,dc=orvelte,dc=nep
Then exclude the "uid" attribute from listing if not explicitly requested:
overlay razor razorAttributeFilter uid
If one wanted to keep the "uid" attribute public to facilitate other parts of the directory, one might use another attribute in the same fashion, for instance the "sshPublicKey" attribute itself; it has a well-known format anyway. This option does mean that this attribute should be explicitly requested; indeed, an LDAP Compare operation seems quite suitable.
TODO -- SPECIFICATION AHEAD --> it is going to be helpful to specify the exact formats to be used in the repository, and then to implement them in tooling.
TODO -- PROGRAMMING AHEAD
- a command to generate the authorized_keys format
- two-phase approach:
- read from local LDAP
- this is quick and has no external ties, so no DoS trouble
- it is intended to validate that the host welcomes a set of keys
- verify local LDAP against its DN-referenced origin
- the local LDAP specifies a DN in the key's comment field
- this field may point to the local repo, where a (remote) user is administered
- alternatively, the (remote) user may maintain their own SSH keys at that location
- every now and then, check if the locally mentioned key is still presented by the (remote) user
- keys should be automatically retracted from 1st phase LDAP when removed from the 2nd phase
RELATED WORK -- ssh-ldap-helper, openssh-lpk, sshark. The ssh-ldap-helper lacks lookup of the key or fingerprint with the originator, which sshark implements but it lacks central control on the relying side. LPK represents SSH keys but it does not state these or other semantics; also, it does not state that there can be a comment field, and that it should contain a DN for such lookups.