1 See Wikipedia's article on the topic for a summary of whether it should be "GNU/Linux" or "Linux".
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
-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-authenticatorcreates secret files with
600permissions, so there's no need to run
chmodon 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: