I’ve been playing around with enabling multi-factor authentication (MFA) on web services and went with TOTP. It’s pretty simple to implement in Perl, and there are plenty of apps for it including Google Authenticator, 1Password and others.
I also wanted to use the same multi-factor auth for SSH logins. Happily, from Debian jessie onwards libpam-google-authenticator is packaged. To enable it for SSH you would just add the following:
auth required pam_google_authenticator.so
to /etc/pam.d/sshd (put it just after @include common-auth).
and ensure that:
is in /etc/ssh/sshd_config.
Not all my users will have MFA enabled though, so to skip prompting for these I use:
auth required pam_google_authenticator.so nullok
Finally, I only wanted users in a particular Unix group to be prompted for an MFA token so (assuming that group was totp) that would be:
auth [success=1 default=ignore] pam_succeed_if.so quiet user notingroup totp auth required pam_google_authenticator.so nullok
If the pam_succeed_if conditions are met then the next line is skipped, so that causes pam_google_authenticator to be skipped for users not in the group totp.
Each user will require a TOTP secret key generating and storing. If you’re only setting this up for SSH then you can use the google-authenticator binary from the libpam-google-authenticator package. This asks you some simple questions and then populates the file $HOME/.google_authenticator with the key and some configuration options. That looks like:
T6Z2KSDCG7CEWPD6EPA6BICBFD4KYKCSGO2JEQVII7ZJNCXECRZPJ4GJHD3CWC43FZIKQUSV5LR2LFFP " RATE_LIMIT 3 30 1462548404 " DISALLOW_REUSE 48751610 " TOTP_AUTH 11494760 25488108 33980423 43620625 84061586
The first line is the secret key; the five numbers are emergency codes that will always work (once each) if locked out.
If generating keys elsewhere then you can just populate this file yourself. If the file isn’t present then that’s when “nullok” applies; without “nullok” authentication would fail.
Note that despite the repeated mentions of “google” here, this is not a Google-specific service and no data is sent to Google. Google are the authors of the open source Google Authenticator mobile app and the libpam-google-authenticator PAM module, but (as evidenced by the Perl example) this is an open standard and client and server sides can be implemented in any language.
So that is how you can make a web service and an SSH service use the same TOTP multi-factor authentication.