HOWTO OpenSSH 2FA with password and Google Authenticator: Difference between revisions
m (→Configure the OpenSSH server: Removed ChallengeResponseAuthentication directive; as it is set to yes by default.) |
m (→Configure the google-authenticator PAM module: Fixed formatting.) |
||
(10 intermediate revisions by 4 users not shown) | |||
Line 1: | Line 1: | ||
{{TOC right}} | |||
The following will allow you to setup the OpenSSH ssh server to use two factor authentication consisting of the user's password and a Time-based One Time Password (TOTP). | The following will allow you to setup the OpenSSH ssh server to use two factor authentication consisting of the user's password and a Time-based One Time Password (TOTP). | ||
In order to facilitate this, you will need to add the required APKs, configure the OpenSSH server, configure the google-authenticator PAM module, restart the OpenSSH server, and setup google-authenticator per user. | In order to facilitate this, you will need to add the required APKs, configure the OpenSSH server, configure the google-authenticator PAM module, restart the OpenSSH server, and setup google-authenticator per user. | ||
=Required APKs= | |||
==Required APKs== | |||
Main repository: | Main repository: | ||
* | *{{pkg|openssh}} | ||
* | *{{pkg|openssh-server-pam}} | ||
Community repository: | Community repository: | ||
* | *{{pkg|google-authenticator}} | ||
Documentation (optional): | Documentation (optional): | ||
* | *{{pkg|openssh-doc}} | ||
* | *{{pkg|google-authenticator-doc}} (community repo) | ||
To pull in all apks in one shot: | To pull in all apks in one shot: | ||
{{cmd|# apk add openssh openssh-server-pam google-authenticator openssh-doc google-authenticator-doc}} | {{cmd|# apk add openssh openssh-server-pam google-authenticator openssh-doc google-authenticator-doc}} | ||
=Configure the OpenSSH server= | ==Configure the OpenSSH server== | ||
{{Note|This article assumes that you have already done basic setup of OpenSSH relying on username and password to login... Please see the article [[ | |||
{{Note|This article assumes that you have already done basic setup of OpenSSH relying on username and password to login... Please see the article [[Setting up a SSH server]] if you have not done so}} | |||
Use {{pkg|sudo}}, [https://busybox.net/BusyBox.html#su su], or [https://man.openbsd.org/doas doas] to elevate your preferred text editor to root privileges, and then edit the {{Path|/etc/ssh/sshd_config}} file. There are three directives which need to be altered or added if not present: | |||
<pre>PasswordAuthentication no | <pre>PasswordAuthentication no | ||
AuthenticationMethods keyboard-interactive | AuthenticationMethods keyboard-interactive | ||
Line 25: | Line 35: | ||
Please consult the [https://man.openbsd.org/sshd_config sshd_config manpage], particularly the AuthenticationMethods directive, if you would like to use public key authentication. | Please consult the [https://man.openbsd.org/sshd_config sshd_config manpage], particularly the AuthenticationMethods directive, if you would like to use public key authentication. | ||
=Configure the google-authenticator PAM module= | |||
As root create the {{Path|/etc/pam.d/sshd}} file and create a link to it called {{Path|/etc/pam.d/sshd.pam}}: | ==Configure the <code>google-authenticator</code> PAM module== | ||
{{cmd|# touch /etc/pam.d/sshd | |||
As root, create the {{Path|/etc/pam.d/sshd}} file and create a link to it called {{Path|/etc/pam.d/sshd.pam}}: | |||
{{cmd|# touch /etc/pam.d/sshd | |||
# ln /etc/pam.d/sshd /etc/pam.d/sshd.pam}} | |||
Elevate your preferred text editor to root and edit the {{Path|/etc/pam.d/sshd}} file, it will contain the following lines at a minimum: | Elevate your preferred text editor to root and edit the {{Path|/etc/pam.d/sshd}} file, it will contain the following lines at a minimum: | ||
auth required | <pre>#%PAM-1.0 | ||
auth required | auth required pam_env.so | ||
auth required | auth required pam_nologin.so successok | ||
auth required | auth required pam_google_authenticator.so echo_verification_code grace_period=57600 nullok | ||
auth required pam_unix.so sha512 | |||
account include base-account | |||
password include base-password | |||
session include base-session</pre> | |||
In the example above, we are passing a few useful options to the google authenticator pam module: | |||
{| | {| | ||
|- | |- | ||
| echo_verification_code || Allows the user to see their verification code as they type it, reducing the chance | | echo_verification_code || Allows the user to see their verification code as they type it, reducing the chance it is entered incorrectly. | ||
|- | |- | ||
| grace_period=57600 || | | grace_period=57600 || Defines a grace period in seconds during which a user login attempt from the same IP address will not be asked for the verification code. | ||
|- | |- | ||
| nullok || This option is recommended during the initial roll-out process of google authenticator on your server, it allows users who have not created a secret key to bypass the verification code prompt | | nullok || This option is recommended during the initial roll-out process of google authenticator on your server, it allows users who have not created a secret key to bypass the verification code prompt. It is recommended you remove this option after all of your users have created secret keys. | ||
|} | |} | ||
More options can be found in the [https://github.com/google/google-authenticator-libpam/blob/master/man/pam_google_authenticator.8.md google-authenticator manpage] or on [https://github.com/google/google-authenticator-libpam their github]. | More options can be found in the [https://github.com/google/google-authenticator-libpam/blob/master/man/pam_google_authenticator.8.md google-authenticator manpage] or on [https://github.com/google/google-authenticator-libpam their github]. | ||
==Restart the SSH server== | |||
In order for the changes above to take effect, run as the root user: {{cmd|# service sshd restart}} | |||
{{Tip|If you are logged into your system remotely, restarting sshd will ''not'' kill your current connection.<br> | |||
This is very useful because you can restart sshd and open an additional connection to test config changes, if you make a typo error, you can use the first connection to make corrections or revert changes to get sshd running again. | |||
Before proceeding further, take the time to ensure your sshd is allowing you to log in with your username/password without TOTP as usual and fix any issues.}} | |||
==Setup google-authenticator per user== | |||
Instruct all users whom you wish to use the one time passes to login to their account and run the <code>google-authenticator</code> command to setup their secrets. | |||
They will type the OTP secret generated into their authenticator app and hand write their 5 scratch codes to store in a secure location. | |||
The command output will look something like this: | |||
{{cmd|$ google-authenticator}} | {{cmd|$ google-authenticator}} | ||
<pre>Do you want authentication tokens to be time-based (y/n) y | <pre>Do you want authentication tokens to be time-based (y/n) y | ||
Warning: pasting the following URL into your browser exposes the OTP secret to Google: | Warning: pasting the following URL into your browser exposes the OTP secret to Google: | ||
Line 99: | Line 123: | ||
~$</pre> | ~$</pre> | ||
You will want to answer y to the first two questions. | You will want to answer '''y''' to the first two questions. | ||
The remaining questions are personal preference, I typically answer y n n, my rationale for doing so: | |||
I disallow multiple uses of authentication tokens on boxes in which the grace_period option above is set above 60 seconds. | The remaining questions are personal preference, I typically answer '''y n n''', my rationale for doing so: | ||
I cannot think of any machines I deal with which are not NTP (clock sync) enabled, so I do not enable time-skew compensation. | |||
I disallow multiple uses of authentication tokens on boxes in which the grace_period option above is set above 60 seconds. | |||
I cannot think of any machines I deal with which are not NTP (clock sync) enabled, so I do not enable time-skew compensation. | |||
I do not enable rate-limiting as the sshd and firewall should take care of that. | I do not enable rate-limiting as the sshd and firewall should take care of that. | ||
[[Category:Authentication]] | [[Category:Authentication]] | ||
[[Category:Networking]] | [[Category:Networking]] | ||
[[Category:Security]] | [[Category:Security]] | ||
[[Category:Server]] | [[Category:Server]] |
Latest revision as of 07:29, 4 September 2023
The following will allow you to setup the OpenSSH ssh server to use two factor authentication consisting of the user's password and a Time-based One Time Password (TOTP).
In order to facilitate this, you will need to add the required APKs, configure the OpenSSH server, configure the google-authenticator PAM module, restart the OpenSSH server, and setup google-authenticator per user.
Required APKs
Main repository:
Community repository:
Documentation (optional):
- openssh-doc
- google-authenticator-doc (community repo)
To pull in all apks in one shot:
# apk add openssh openssh-server-pam google-authenticator openssh-doc google-authenticator-doc
Configure the OpenSSH server
Use sudo, su, or doas to elevate your preferred text editor to root privileges, and then edit the /etc/ssh/sshd_config file. There are three directives which need to be altered or added if not present:
PasswordAuthentication no AuthenticationMethods keyboard-interactive UsePAM yes
Please consult the sshd_config manpage, particularly the AuthenticationMethods directive, if you would like to use public key authentication.
Configure the google-authenticator
PAM module
As root, create the /etc/pam.d/sshd file and create a link to it called /etc/pam.d/sshd.pam:
# touch /etc/pam.d/sshd # ln /etc/pam.d/sshd /etc/pam.d/sshd.pam
Elevate your preferred text editor to root and edit the /etc/pam.d/sshd file, it will contain the following lines at a minimum:
#%PAM-1.0 auth required pam_env.so auth required pam_nologin.so successok auth required pam_google_authenticator.so echo_verification_code grace_period=57600 nullok auth required pam_unix.so sha512 account include base-account password include base-password session include base-session
In the example above, we are passing a few useful options to the google authenticator pam module:
echo_verification_code | Allows the user to see their verification code as they type it, reducing the chance it is entered incorrectly. |
grace_period=57600 | Defines a grace period in seconds during which a user login attempt from the same IP address will not be asked for the verification code. |
nullok | This option is recommended during the initial roll-out process of google authenticator on your server, it allows users who have not created a secret key to bypass the verification code prompt. It is recommended you remove this option after all of your users have created secret keys. |
More options can be found in the google-authenticator manpage or on their github.
Restart the SSH server
In order for the changes above to take effect, run as the root user:
# service sshd restart
This is very useful because you can restart sshd and open an additional connection to test config changes, if you make a typo error, you can use the first connection to make corrections or revert changes to get sshd running again.
Before proceeding further, take the time to ensure your sshd is allowing you to log in with your username/password without TOTP as usual and fix any issues.Setup google-authenticator per user
Instruct all users whom you wish to use the one time passes to login to their account and run the google-authenticator
command to setup their secrets.
They will type the OTP secret generated into their authenticator app and hand write their 5 scratch codes to store in a secure location.
The command output will look something like this:
$ google-authenticator
Do you want authentication tokens to be time-based (y/n) y Warning: pasting the following URL into your browser exposes the OTP secret to Google: A URL APPEARS HERE A URL APPEARS HERE Failed to use libqrencode to show QR code visually for scanning. Consider typing the OTP secret into your app manually. Your new secret key is: Ender code from app (-1 to skip): Your emergency scratch codes are: CODE1 CODE2 CODE3 CODE4 CODE5 Do you want me to update your "/home/$USER/.google_authenticator" file? (y/n) y Do you want to disallow multiple uses of the same authentication token? This restricts you to one login about every 30s, bit it increases your chances to notice or even prevent man-in-the-middle attacks (y/n) y By default, a new token is generated every 30 seconds by the mobile app. In order to compensate for possible time-skew between the client and the server, we allow an extra token before and after the current time. This allows for a time skew of up to 30 seconds between authentication server and client. If you experience problems with poor time synchronization, you can increase the window from its default size of 3 permitted codes (one previous code, the current code, the next code) to 17 permitted codes (the 8 previous codes, the current code, and the 8 next codes). This will permit for a time skew of up to 4 minutes between client and server. Do you want to do so? (y/n) n If the computer that you are logging into isn't hardened against brute-force login attempts, you can enable rate-limiting for the authentication module. By default, this limits attackers to no more than 3 login attempts every 30s. Do you want to enable rate-limiting? (y/n) n ~$
You will want to answer y to the first two questions.
The remaining questions are personal preference, I typically answer y n n, my rationale for doing so:
I disallow multiple uses of authentication tokens on boxes in which the grace_period option above is set above 60 seconds.
I cannot think of any machines I deal with which are not NTP (clock sync) enabled, so I do not enable time-skew compensation.
I do not enable rate-limiting as the sshd and firewall should take care of that.