-
Notifications
You must be signed in to change notification settings - Fork 0
/
README
403 lines (322 loc) · 13 KB
/
README
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
____________________
CUSTOM-2FA
U2F and TOTP/HOTP
Rolando Garza
____________________
2021-12-19
Table of Contents
_________________
1. What is this?
2. Why did you write this?
3. Installation
.. 1. WARNING!
4. Usage
5. About
.. 1. Linux-PAM configuration rules
.. 2. These custom-2fa rules
..... 1. What is accomplished?
..... 2. rule 1: request U2F key; press ENTER and detect key
..... 3. rule 2: if no key was inserted, ask for TOTP token
..... 4. rule 3: if U2F key was inserted, request touch
.. 3. Debugging & Troubleshooting
6. Why did I include so much info and not just a README?
7. Copyright notice
8. TODO:
9. References
1 What is this?
===============
These Linux Pluggable Authentication Modules (Linux-PAM) configuration
rules support using both "Universal 2nd Factor" (U2F) and "Time-based
One-time Password" (TOTP) or "HMAC-based One-time Password" (HOTP) for
"Two-Factor Authentication" (2FA) by using Google's
`pam_google_authenticator.so' library and Yubico's `pam_u2f.so'
library.
2 Why did you write this?
=========================
Because I wanted to have a similar log-in workflow in my computers to
the 2FA workflow that some online services provide:
- Validate the user's password (part of `common-auth').
- Prompt for a U2F key if the user registered at least one.
- If the user doesn't have their key or hasn't registered one,
fallback to a TOTP/HTOP code from a TOTP/HTOP authenticator app.
- If the user doesn't have both their key, nor the TOTP/HTOP app
fallback to a rescue code (from the authenticator app).
- Succeed if the user hasn't registered any 2FA methods.
This allows one to introduce other family members or co-workers to a
2FA workflow, and it helps system administrators to reduce the risk of
account takeover by malicious actors because of weak passwords.
3 Installation
==============
Please make sure you have already met these two prerequisites:
- having installed and configured [`pam_google_authenticator.so']
- having installed and configured [`pam_u2f.so']
Let's, for example, add the `custom-2fa' rules to `/etc/pam.d/sudo':
- copy `custom-2fa' file into `/etc/pam.d/':
- `sudo cp custom-2fa /etc/pam.d/'
- edit (and don't close until we verify it works) `/etc/pam.d/sudo':
- `sudo nano /etc/pam.d/sudo'
- include `@include custom-2fa' after `@include common-auth' line, and
save file without exiting the editor or closing the terminal
emulator (see example below with included comments)
- in another terminal emulator window or tab, verify installation:
- `sudo -k && sudo echo "Hello World!"'
- if you were able to successfully authenticate, you may close both
windows
- if there was an error, see the Debugging section
- worst case scenario, you can comment the `@include custom-2fa'
line to disable `custom-2fa' in the editor that still has root
privileges that you totally didn't close.
You may probably want to add `custom-2fa' to the following rule files:
- `/etc/pam.d/sudo'
- `/etc/pam.d/gdm-password'
- `/etc/pam.d/login'
Additionally, you may also want to place some comments, so you
remember how you configured your system. I use the following format:
,----
| # custom-2fa
| # - Prompts for FIDO2-capable U2F device
| # - If present, request touch of device
| # - Otherwise request a TOTP/HOTP validation code
| # - Allow for users without 2FA to authenticate with password
| # note: see /etc/pam.d/custom-2fa for implementation details
| @include custom-2fa
`----
[`pam_google_authenticator.so']
<https://github.com/google/google-authenticator-libpam/>
[`pam_u2f.so'] <https://github.com/Yubico/pam-u2f>
3.1 WARNING!
~~~~~~~~~~~~
Make sure you have several terminal emulators with root privileges
open so that you can undo changes that would leave you without
superuser access.
4 Usage
=======
,----
| user@computer:~$ sudo echo "Hello, World!"
`----
And the expected workflow in the terminal is:
,----
| [sudo] password for user:
| insert key and/or press ENTER:
| touch key:
| Hello, World!
`----
This can also be set as a prompt when logging in (see Installation):
<./gdm3-login-screenshot.png>
5 About
=======
5.1 Linux-PAM configuration rules
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The files are made of lists of rules. Each rule is a space separated
collection of tokens:
`service type control module-path module-arguments'
The files in `/etc/pam.d/' lack the "service" field. Some info
regarding each field:
service
usually carry the name of the service or name of a familiar
application, like "login" and "sudo".
type
the management group that the rule corresponds to
control
indicates behavior of PAM-API if module fails to authenticate.
Two types of syntax are used: simple key word, and
square-bracketed value=action pairs.
module-path
full filename (begins with "`/'") of the PAM to be used or
relative path-name from default location (which could be either
`/lib/security/', `/lib64/security/', or
`/lib/x86_64-linux-gnu/security/')
5.2 These custom-2fa rules
~~~~~~~~~~~~~~~~~~~~~~~~~~
These Linux-PAM configuration rules support using both U2F and
TOTP/HOTP for 2FA by using `pam_google_authenticator.so' and
`pam_u2f.so'.
5.2.1 What is accomplished?
---------------------------
- Prompt for a U2F device, and to then press ENTER.
- In case the U2F device is known, prompt the user to press the
tactile trigger.
- In case the U2F device is not known or present, prompt for code
for verification from TOTP/HOTP app (like Google Authenticator).
- Allow users that are not configured to use U2F or TOTP/HOTP to log
in.
5.2.2 rule 1: request U2F key; press ENTER and detect key
---------------------------------------------------------
- management group type
`auth'
module type that authenticates the user
- control values
`default=ignore'
the module's return status will not contribute to the return
code the application obtains
`ignore=ignore'
PAM module wants its result to be ignored
`new_authtok_reqd=ok'
new authentication token is required
`success=1'
Jump over the N modules in the stack on success
- module path
`pam_u2f.so'
use Yubico's `pam_u2f'
- module arguments
`authfile=/etc/2fa/u2f/u2f_mappings'
Sets the location of the file that holds the mappings of user
names to keyHandles and user keys; should have `0600'
permissions
`interactive'
Set to prompt a message and wait before testing the presence
of a FIDO device. Recommended if your device doesn't have a
tactile trigger
`nouserok'
Set to enable authentication attempts to succeed even if the
user trying to authenticate is not found inside authfile or if
authfile is missing/malformed
`[prompt=insert key and/or press ENTER: ]'
Specify the prompt to insert a U2F key and press ENTER; hint
at TOTP option
`userpresence=0'
If `1', request user presence during authentication. If `0',
do not request user presence during authentication.
Otherwise, fallback to the authenticator's default behavior.
,----
| auth \
| [success=1 new_authtok_reqd=ok ignore=ignore default=ignore] \
| pam_u2f.so \
| authfile=/etc/2fa/u2f/u2f_mappings \
| interactive \
| nouserok \
| [prompt=insert key and/or press ENTER: ] \
| userpresence=0
`----
5.2.3 rule 2: if no key was inserted, ask for TOTP token
--------------------------------------------------------
- management group type
`auth'
module type that authenticates the user
- control values
`default=bad'
should be thought of as indicative of the module failing
`ignore=ignore'
PAM module wants its result to be ignored
`new_authtok_reqd=ok'
new authentication token is required
`success=1'
Jump over the N modules in the stack on success
- module path
`pam_google_authenticator.so'
google-authenticator-libpam, by Google, will be used
- module arguments
`[authtok_prompt=Type in token: ]'
set token prompt
`nullok'
OK if user doesn't have TOTP/HOTP 2FA rolled out
`secret=/etc/2fa/totp/${USER}/.totp_secrets'
the nonstandard location for the file holding the secrets; it
should have `0600' permissions
,----
| auth \
| [success=1 new_authtok_reqd=ok ignore=ignore default=bad] \
| pam_google_authenticator.so \
| [authtok_prompt=type in token: ] \
| nullok \
| secret=/etc/2fa/totp/${USER}/.totp_secrets
`----
5.2.4 rule 3: if U2F key was inserted, request touch
----------------------------------------------------
- management group type
`auth'
module type that authenticates the user
- control values
`required'
failure of such a PAM will ultimately lead to the PAM-API
returning failure but only after the remaining stacked modules
(for this service and type) have been invoked. This is a
shorthand for the following values:
- `[success=ok new_authtok_reqd=ok ignore=ignore default=bad]'
- module path
`pam_u2f.so'
use Yubico's `pam_u2f'
- module arguments
`authfile=/etc/2fa/u2f/u2f_mappings'
Sets the location of the file that holds the mappings of user
names to keyHandles and user keys; should have `0600'
permissions
`cue'
Set to prompt a message to remind to touch the device
`[cue_prompt=Touch key: ]'
Specify prompt to touch key
`nouserok'
Set to enable authentication attempts to succeed even if the
user trying to authenticate is not found inside authfile or if
authfile is missing/malformed.
`userpresence=1'
If `1', request user presence during authentication. If `0',
do not request user presence during authentication.
Otherwise, fallback to the authenticator's default behavior.
,----
| auth \
| required \
| pam_u2f.so \
| authfile=/etc/2fa/u2f/u2f_mappings \
| cue \
| [cue_prompt=touch key: ] \
| nouserok \
| userpresence=1
`----
5.3 Debugging & Troubleshooting
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
First, it may be useful to identify which files use custom-2fa: `grep
-irlE "^#?@include custom-2fa" /etc/pam.d/ --exclude=custom'
After that, try to pinpoint if the problem is with `pam_u2f' (rules 1
and 3), or with `pam_google_authenticator' (rule 2). Then enable
debug logging, try authenticating again, and inspect the output.
Remember to escape previous line breaks with "`\'" when adding module
arguments to the PAM rules.
For `pam_u2f' (rules 1 and 3):
- Enable debug logging:
- `sudo touch /var/log/pam_u2f.log'
- add "`debug'" as an additional module argument
- optionally, also add "`debug_file=/var/log/pam_u2f.log'"
- Try authenticating again:
- `sudo -k && sudo echo "Hello World!"'
- Inspect debug logs:
- if `debug_file' was not specified, output will be on stderr
- if `debug_file' was specified:
- inspect it: `nano /var/log/pam_u2f.log'
- remove it: `sudo rm /var/log/pam_u2f.log'
For `pam_google_authenticator' (rule 2):
- Enable debug logging
- add "`debug'" as an additional module argument
- Begin monitoring syslog:
- open shell and monitor with: `tail -f /var/log/auth.log'
- Try authenticating again:
- in another shell: `sudo -k && sudo echo "Hello World!"'
6 Why did I include so much info and not just a README?
=======================================================
Well, ... why not both? Honestly, sometimes you don't want to be
scouring through the Internet to try to grok rules that you wrote
several months ago. So I decided to include most of this README in
the actual source as comments.
7 Copyright notice
==================
custom-2fa
Copyright 2021, Rolando Garza.
License GPLv3+: GNU GPL version 3 or later,
<https://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Written by Rolando Garza.
8 TODO:
=======
- [-] Ask Yubico's pam-u2f developers if they could expand `%u'
variable so that we could get something like:
`authfile=/etc/2fa/u2f/%u/u2f_mappings'
- [X] see: <https://github.com/Yubico/pam-u2f/issues/218>
- [ ] contribute?
9 References
============
- <http://www.linux-pam.org/Linux-PAM-html/sag-configuration.html>
- <https://github.com/google/google-authenticator-libpam/>
- <https://github.com/Yubico/pam-u2f>
- <https://refspecs.linuxfoundation.org/fhs.shtml>