<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://wiki.alpinelinux.org/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Grimler</id>
	<title>Alpine Linux - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.alpinelinux.org/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Grimler"/>
	<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/wiki/Special:Contributions/Grimler"/>
	<updated>2026-05-10T02:38:11Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.40.0</generator>
	<entry>
		<id>https://wiki.alpinelinux.org/w/index.php?title=HOWTO_OpenSSH_2FA_with_password_and_Google_Authenticator&amp;diff=30210</id>
		<title>HOWTO OpenSSH 2FA with password and Google Authenticator</title>
		<link rel="alternate" type="text/html" href="https://wiki.alpinelinux.org/w/index.php?title=HOWTO_OpenSSH_2FA_with_password_and_Google_Authenticator&amp;diff=30210"/>
		<updated>2025-06-09T18:58:24Z</updated>

		<summary type="html">&lt;p&gt;Grimler: Add troubleshooting subsection for error &amp;#039;Unsupported option UsePAM&amp;#039;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{{TOC right}}&lt;br /&gt;
&lt;br /&gt;
The following will allow you to setup the OpenSSH ssh server to use two factor authentication consisting of the user&#039;s password and a Time-based One Time Password (TOTP).&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Required APKs==&lt;br /&gt;
&lt;br /&gt;
Main repository:&lt;br /&gt;
*{{pkg|openssh}}&lt;br /&gt;
*{{pkg|openssh-server-pam}}&lt;br /&gt;
&lt;br /&gt;
Community repository:&lt;br /&gt;
*{{pkg|google-authenticator}}&lt;br /&gt;
&lt;br /&gt;
Documentation (optional):&lt;br /&gt;
*{{pkg|openssh-doc}}&lt;br /&gt;
*{{pkg|google-authenticator-doc}} (community repo)&lt;br /&gt;
&lt;br /&gt;
To pull in all apks in one shot:&lt;br /&gt;
&lt;br /&gt;
{{cmd|# apk add openssh openssh-server-pam google-authenticator openssh-doc google-authenticator-doc}}&lt;br /&gt;
&lt;br /&gt;
==Configure the OpenSSH server==&lt;br /&gt;
&lt;br /&gt;
{{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}}&lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;PasswordAuthentication no&lt;br /&gt;
AuthenticationMethods keyboard-interactive&lt;br /&gt;
UsePAM yes&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Configure the &amp;lt;code&amp;gt;google-authenticator&amp;lt;/code&amp;gt; PAM module==&lt;br /&gt;
&lt;br /&gt;
As root, create the {{Path|/etc/pam.d/sshd}} file and create a link to it called {{Path|/etc/pam.d/sshd.pam}}:&lt;br /&gt;
{{cmd|# touch /etc/pam.d/sshd&lt;br /&gt;
&amp;amp;#35; ln /etc/pam.d/sshd /etc/pam.d/sshd.pam}} &lt;br /&gt;
&lt;br /&gt;
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:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;#%PAM-1.0                                                                                                                                                                                                                                       &lt;br /&gt;
auth            required        pam_env.so&lt;br /&gt;
auth            required        pam_nologin.so  successok&lt;br /&gt;
auth            required        pam_google_authenticator.so       echo_verification_code grace_period=57600 nullok&lt;br /&gt;
auth            required        pam_unix.so      sha512&lt;br /&gt;
account         include         base-account&lt;br /&gt;
password        include         base-password&lt;br /&gt;
session         include         base-session&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
In the example above, we are passing a few useful options to the google authenticator pam module:&lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| echo_verification_code || Allows the user to see their verification code as they type it, reducing the chance it is entered incorrectly.&lt;br /&gt;
|-&lt;br /&gt;
| 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.&lt;br /&gt;
|-&lt;br /&gt;
| 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.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
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].&lt;br /&gt;
&lt;br /&gt;
==Restart the SSH server==&lt;br /&gt;
&lt;br /&gt;
In order for the changes above to take effect, run as the root user: {{cmd|# service sshd restart}}&lt;br /&gt;
&lt;br /&gt;
{{Tip|If you are logged into your system remotely, restarting sshd will &#039;&#039;not&#039;&#039; kill your current connection.&amp;lt;br&amp;gt;&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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.}}&lt;br /&gt;
&lt;br /&gt;
==Setup google-authenticator per user==&lt;br /&gt;
&lt;br /&gt;
Instruct all users whom you wish to use the one time passes to login to their account and run the &amp;lt;code&amp;gt;google-authenticator&amp;lt;/code&amp;gt; command to setup their secrets.&lt;br /&gt;
&lt;br /&gt;
They will type the OTP secret generated into their authenticator app and hand write their 5 scratch codes to store in a secure location.&lt;br /&gt;
&lt;br /&gt;
The command output will look something like this:&lt;br /&gt;
&lt;br /&gt;
{{cmd|$ google-authenticator}}&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;Do you want authentication tokens to be time-based (y/n) y&lt;br /&gt;
Warning: pasting the following URL into your browser exposes the OTP secret to Google:&lt;br /&gt;
  A URL APPEARS HERE    &lt;br /&gt;
  A URL APPEARS HERE&lt;br /&gt;
Failed to use libqrencode to show QR code visually for scanning.&lt;br /&gt;
Consider typing the OTP secret into your app manually.&lt;br /&gt;
Your new secret key is: &lt;br /&gt;
Ender code from app (-1 to skip):&lt;br /&gt;
Your emergency scratch codes are:&lt;br /&gt;
  CODE1&lt;br /&gt;
  CODE2&lt;br /&gt;
  CODE3&lt;br /&gt;
  CODE4&lt;br /&gt;
  CODE5&lt;br /&gt;
&lt;br /&gt;
Do you want me to update your &amp;quot;/home/$USER/.google_authenticator&amp;quot; file? (y/n) y&lt;br /&gt;
&lt;br /&gt;
Do you want to disallow multiple uses of the same authentication&lt;br /&gt;
token? This restricts you to one login about every 30s, bit it increases&lt;br /&gt;
your chances to notice or even prevent man-in-the-middle attacks (y/n) y&lt;br /&gt;
&lt;br /&gt;
By default, a new token is generated every 30 seconds by the mobile app.&lt;br /&gt;
In order to compensate for possible time-skew between the client and the server,&lt;br /&gt;
we allow an extra token before and after the current time. This allows for a&lt;br /&gt;
time skew of up to 30 seconds between authentication server and client. If you&lt;br /&gt;
experience problems with poor time synchronization, you can increase the window&lt;br /&gt;
from its default size of 3 permitted codes (one previous code, the current&lt;br /&gt;
code, the next code) to 17 permitted codes (the 8 previous codes, the current&lt;br /&gt;
code, and the 8 next codes). This will permit for a time skew of up to 4 minutes&lt;br /&gt;
between client and server.&lt;br /&gt;
Do you want to do so? (y/n) n&lt;br /&gt;
&lt;br /&gt;
If the computer that you are logging into isn&#039;t hardened against brute-force&lt;br /&gt;
login attempts, you can enable rate-limiting for the authentication module.&lt;br /&gt;
By default, this limits attackers to no more than 3 login attempts every 30s.&lt;br /&gt;
Do you want to enable rate-limiting? (y/n) n&lt;br /&gt;
~$&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You will want to answer &#039;&#039;&#039;y&#039;&#039;&#039; to the first two questions.&lt;br /&gt;
&lt;br /&gt;
The remaining questions are personal preference, I typically answer &#039;&#039;&#039;y n n&#039;&#039;&#039;, my rationale for doing so:&lt;br /&gt;
&lt;br /&gt;
I disallow multiple uses of authentication tokens on boxes in which the grace_period option above is set above 60 seconds.&lt;br /&gt;
&lt;br /&gt;
I cannot think of any machines I deal with which are not NTP (clock sync) enabled, so I do not enable time-skew compensation.&lt;br /&gt;
&lt;br /&gt;
I do not enable rate-limiting as the sshd and firewall should take care of that.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Troubleshooting==&lt;br /&gt;
&lt;br /&gt;
===Unsupported option UsePAM===&lt;br /&gt;
&lt;br /&gt;
If you keep getting an error like &lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
rexec line 88: Unsupported option UsePAM&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
then ensure the dependencies in [[HOWTO OpenSSH 2FA with password and Google Authenticator#Required APKs|Required APKs]] are installed, and try running &amp;lt;code&amp;gt;/usr/sbin/sshd.pam&amp;lt;/code&amp;gt; as an sshd server instead of &amp;lt;code&amp;gt;/usr/sbin/sshd&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Category:Authentication]]&lt;br /&gt;
[[Category:Networking]]&lt;br /&gt;
[[Category:Server]]&lt;/div&gt;</summary>
		<author><name>Grimler</name></author>
	</entry>
</feed>