Secure sudo with Google Authenticator
A little while ago, I "secured" root access on my GNU/Linux1 systems by stopping using the root password and migrating to sudo. I also setup Google Authenticator for it.
1 See Wikipedia's article on the topic for a summary of whether it should be "GNU/Linux" or "Linux".
History
My original implementation simply used pam_google_authenticator.so
with default options, which meant that although sudo required a OTP (one-time passcode) the secret used to generate that (time-based) passcode was stored in a file called .google_authenticator
in each user's home. With this secret anyone can start generating codes from it, which meant that if a user account with sudo access was compromised it was trivial for a bad-actor to then get root access. Obviously this was not good.
Doing it properly
Fortunately the PAM module supports some options which allow overriding of the location of the secrets file and the user to use when processing the authentication (so the files can be secured from the user being authenticated without doing this as root).
My first step was to create a user to use to do the authentication:
Next I made a directory to store the credentials in and generated a secret. I need to create a file with a known name for each user:
The options to google-authenticator
are:
-t
: time based tokens-d
: do not allow passcode reuse-r 3
: rate limit to 3 attempts-R 30
: rate limit window set to 30s-w 3
: window size of 3 (allows 1 code either side the current one, so current time-based code +-1min)-s /var/lib/sudo-secrets/my_username.google_authenticator
: use this non-standard (the standard being~/.google_authenticator
) secret file location
google-authenticator
creates secret files with 600
permissions, so there's no need to run chmod
on that file after creation.
The final piece in this puzzle is tweaking the PAM configuration in /etc/pam.d/sudo
to look in the right (secure) location for the tokens and use a user that has read access to this location: