content/blog/2022-03-26-ssh-mfa.org

0b2895a90c7751ce06e4b26d4db41005ea2f40a9
cleberg.net/content/blog/2022-03-26-ssh-mfa.org rendered · source · history · blame · raw

197 lines · 6748 bytes

  1#+date:        <2022-03-26 Sat 00:00:00>
  2#+title:       Implementation of Time-Based One-Time Password Multi-Factor Authentication for SSH Access
  3#+description: Step-by-step deployment guide for enabling TOTP multi-factor authentication on SSH services using Google Authenticator and Pluggable Authentication Module (PAM) integration.
  4#+slug:        ssh-mfa
  5#+filetags:    :ssh:mfa:security:
  6
  7* Why Do I Need MFA for SSH?
  8
  9If you are a sysadmin of a server anywhere (that includes at home!), you
 10may want an added layer of protection against intruders. This is not a
 11replacement for other security measures, such as:
 12
 13- Disable root SSH
 14- Disable SSH password authentication
 15- Allow only certain users to login via SSH
 16- Allow SSH only from certain IPs
 17
 18However, MFA can be added as an additional security measure to ensure
 19that your server is protected. This is especially important if you need
 20to allow password authentication for SSH.
 21
 22For more guidance on server security measures, see my other post:
 23[[../hardening-a-public-facing-home-server/][Hardening a Public-Facing
 24Home Server]].
 25
 26* Install MFA PAM Module
 27
 28PAM, which stands for Pluggable Authentication Module, is an
 29authentication infrastructure used on Linux systems to authenticate a
 30user. In order to use this technology, let's install the
 31=libpam-google-authenticator= package:
 32
 33#+begin_src sh
 34sudo apt-get update
 35#+end_src
 36
 37#+begin_src sh
 38sudo apt-get install libpam-google-authenticator
 39#+end_src
 40
 41* Initialize the PAM Module
 42
 43** Interactive Method
 44
 45Once the package is installed, initialize it and following the
 46interactive prompts to generate your OTP or TOTP:
 47
 48#+begin_src sh
 49google-authenticator
 50#+end_src
 51
 52If you are not sure how to answer, read the prompts carefully and think
 53about having to how each situation would affect your normal login
 54attempts. If you are still not sure, use my default responses below.
 55
 56#+begin_src txt
 57OUTPUT
 58
 59Do you want authentication tokens to be time-based (y/n) y
 60#+end_src
 61
 62At this point, use an authenticator app somewhere one of your devices to
 63scan the QR code. Any future login attempts after our upcoming
 64configuration changes will require that TOTP.
 65
 66#+begin_src txt
 67OUTPUT
 68
 69Do you want me to update your "/home/user/.google_authenticator" file? (y/n) y
 70#+end_src
 71
 72#+begin_src txt
 73OUTPUT
 74
 75Do you want to disallow multiple uses of the same authentication
 76token? This restricts you to one login about every 30s, but it increases
 77your chances to notice or even prevent man-in-the-middle attacks (y/n) y
 78#+end_src
 79
 80#+begin_src txt
 81OUTPUT
 82
 83By default, a new token is generated every 30 seconds by the mobile app.
 84In order to compensate for possible time-skew between the client and the server,
 85we allow an extra token before and after the current time. This allows for a
 86time skew of up to 30 seconds between authentication server and client. If you
 87experience problems with poor time synchronization, you can increase the window
 88from its default size of 3 permitted codes (one previous code, the current
 89code, the next code) to 17 permitted codes (the 8 previous codes, the current
 90code, and the 8 next codes). This will permit for a time skew of up to 4 minutes
 91between client and server.
 92Do you want to do so? (y/n) n
 93#+end_src
 94
 95#+begin_src txt
 96OUTPUT
 97
 98If the computer that you are logging into isn't hardened against brute-force
 99login attempts, you can enable rate-limiting for the authentication module.
100By default, this limits attackers to no more than 3 login attempts every 30s.
101Do you want to enable rate-limiting? (y/n) y
102#+end_src
103
104** Non-Interactive Method
105
106If you need to do this quickly, know your responses to the prompts, or
107are setting this up for numerous users, the non-interactive method can
108be much faster:
109
110#+begin_src sh
111google-authenticator -t -d -f -r 3 -R 30 -w 3
112#+end_src
113
114The options referenced above are as follows:
115
116#+begin_src txt
117google-authenticator [<options>]
118 -h, --help                     Print this message
119 -c, --counter-based            Set up counter-based (HOTP) verification
120 -t, --time-based               Set up time-based (TOTP) verification
121 -d, --disallow-reuse           Disallow reuse of previously used TOTP tokens
122 -D, --allow-reuse              Allow reuse of previously used TOTP tokens
123 -f, --force                    Write file without first confirming with user
124 -l, --label=<label>            Override the default label in "otpauth://" URL
125 -i, --issuer=<issuer>          Override the default issuer in "otpauth://" URL
126 -q, --quiet                    Quiet mode
127 -Q, --qr-mode={NONE,ANSI,UTF8} QRCode output mode
128 -r, --rate-limit=N             Limit logins to N per every M seconds
129 -R, --rate-time=M              Limit logins to N per every M seconds
130 -u, --no-rate-limit            Disable rate-limiting
131 -s, --secret=<file>            Specify a non-standard file location
132 -S, --step-size=S              Set interval between token refreshes
133 -w, --window-size=W            Set window of concurrently valid codes
134 -W, --minimal-window           Disable window of concurrently valid codes
135 -e, --emergency-codes=N        Number of emergency codes to generate
136#+end_src
137
138This fully configures the authenticator, saves it to a file, and then
139outputs the secret key, QR code, and recovery codes. (If you add the
140flag =-q=, then there won't be any output). If you use this command in
141an automated fashion, make sure your script captures the secret key
142and/or recovery codes and makes them available to the user.
143
144* PAM Configuration Settings
145
146Once you've enabled the T/OTP and have it saved to an MFA app on your
147phone or other device, open the PAM =sshd= file:
148
149#+begin_src sh
150sudo nano /etc/pam.d/sshd
151#+end_src
152
153You need to do two things in this file. First, add the following lines
154to the bottom of the file:
155
156#+begin_src config
157auth required pam_google_authenticator.so nullok
158auth required pam_permit.so
159#+end_src
160
161Second, comment-out the following line near the top of the file.
162
163If you leave this line uncommented, every SSH login attempt will ask for
164the following three authentication factors:
165
1661. Publickey
1672. Password
1683. T/OTP code
169
170#+begin_src config
171#@include common-auth
172#+end_src
173
174* SSH Configuration Settings
175
176Finally, edit the =sshd_config= file again:
177
178#+begin_src sh
179sudo nano /etc/ssh/sshd_config
180#+end_src
181
182You'll need to change =ChallengeResponseAuthentication= to yes and add
183the =AuthenticationMethods= line to the bottom of the file.
184
185#+begin_src config
186ChallengeResponseAuthentication yes
187AuthenticationMethods publickey,password publickey,keyboard-interactive
188#+end_src
189
190Finally, restart the =ssh= service:
191
192#+begin_src sh
193sudo systemctl restart sshd.service
194#+end_src
195
196The next time you log in, you should be greeted with a verification code
197request!