19-SEP-2012: Derived Root Passwords

One Password to Rule Them All

As someone who manages a large number of UNIX systems as a part of a large team of UNIX administrators one problem we have to address is the secure distribution and storage of the "root" password for every system.

One way to accomplish this is to set the "root" password for every system to the same value and then you only ever have to worry about that one password. This has the obvious drawback that if you ever need to share that system's root password with someone you have also given them the root password to every other system. In my environment we occasionally have to share the root password to systems, but we do not want the person we share it with to be able to leverage that to gain access to other systems.

Another options is to set a different random root password for every system. This removes the problem with sharing the root password for a system leading to the person you have shared with being able to gain elevated privileges on other systems (directly, anyway). However, now you have to keep track of N different root passwords and be able to keep that information in sync with everyone who needs it.

So a solution to this problem would be to have a common password from which all your actual root passwords are derived from. You should, of course, use a derivation scheme that does not allow a person who knows the scheme and one or more derived passwords to derive additional passwords.

A simple system for doing this would be to use the SHA1 hash of the concatenation of your common password and the normalized name of the system (i.e., all lower-case and either short-name only, or fully-qualified name only -- it doesn't matter as long as you are consistent). We also convert that to base64 to reduce its length.

The final function looks like:

For example, if we decided our common password was "Secret" we would have the following derived passwords:

Hostname Derived Password
WWW1 hwLm+r6dkV3lxQsNaoyb24kqc+c=
WWW2 O7IYE/kdSu1wits9pAVBBz1nuAE=
WWW3 1P1EiFDDh0VaTMSWFNKQtBLl3TQ=
MAIL1 TvUkKa96QhujzqWR+L5zhsrtFz4=
MAIL2 yJgLKCpvM5BIy05k+u+SS6oTBKc=

I have a simple javascript powered page which performs the needed computations.

It can also be easily computed using OpenSSL:

  $ echo -n '<hostname><password_common>' | openssl sha1 -binary | openssl base64

The downside to this approach is that if you need to change your root password on one system for whatever reason you either have to maintain errata to the system that must be synchronized or change the root password on all systems. Fortunately, for us this is an acceptable trade off.

Hooray.