content/blog/2022-03-26-ssh-mfa.org
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!