Heavy lifting for implementing pam-u2f protocol was done by Yubico, you can see details on webpage https://developers.yubico.com/pam-u2f/
Fortunately for us, major linux distributions are including necessary libraries already, we will show setup on Fedora 25.
WARNING: during setup, be sure to have opened also terminal with root privileges, otherwise you can lock yourself out
WARNING: during setup, be sure to have opened also terminal with root privileges, otherwise you can lock yourself out
1. Instalation of packages
# dnf install pamu2fcfg pam-u2f
2. Setup of /etc/u2f_mappings
We will use mapping between u2f tokens and users configured in file /etc/u2f_mappings
Login as user under which should you use your token
$ pamu2fcfg -u `whoami` -opam://`hostname` -ipam://`hostname` user:kiVO09_6EBL02yl9G49jWvSDd0tFztiYm8Zd5SDtXXb7jVgCwdl6J3MnWRfikn3tuUc09_hExyKF18TEQsciMw,040bf66f859a707cd98fcd11db63b7f35c7dd05cc6b1f1e85aff22bf198687a2f091b8cf9bb10bc350881ee450bafef4c8f43611642c4ce05a6d6bbbd1e466fe89
Repeat of every U2F token you own. You will be combining these lines into one line in next step.
Now in separate window login as root and create file /etc/u2f_mappings with this format
username1:keyhandle1,key1:keyhandle2:key2:...
username2:keyhandle1,key1:keyhandle2:key2:...
Example for username "user" with two U2F keys:
# cat /etc/u2f_mappings user:kiVO09_6EBL02yl9G49jWvSDd0tFztiYm8Zd5SDtXXb7jVgCwdl6J3MnWRfikn3tuUc09_hExyKF18TEQsciMw,040bf66f859a707cd98fcd11db63b7f35c7dd05cc6b1f1e85aff22bf198687a2f091b8cf9bb10bc350881ee450bafef4c8f43611642c4ce05a6d6bbbd1e466fe89:piV_Zds60NmPnvNVstleTpCVfQ_sMYFANzCGBe_QrPw3XndNRmtOXkYxVQe71bugqU7fieenZ78QKckiRI3QEQ,0482f11f3e1ebedd059c8e3972b5f7b53942d1f54956770d7e08c889a37a6f24a8462a01eca6ccec6f1ccbd059acdbc377eed62a8c7024a9cdf6b948b1c2a1988f
Make no mistake, for one username everything should be on ONE line
3. Setup /etc/sudoers
Important thing here is to set "timestamp_timeout=0" as default, so each subsequent sudo command still asks for authentication. You should edit this file via "visudo" command.
# egrep -v '^#|^$' /etc/sudoers Defaults !visiblepw Defaults env_reset,timestamp_timeout=0 Defaults env_keep = "COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR LS_COLORS" Defaults env_keep += "MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE" Defaults env_keep += "LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES" Defaults env_keep += "LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE" Defaults env_keep += "LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_C HARSET XAUTHORITY" Defaults secure_path = /sbin:/bin:/usr/sbin:/usr/bin root ALL=(ALL) ALL %wheel ALL=(ALL) ALLDont forget to setup desired user as part of "wheel" system group (in /etc/group or via command usermod).
4. Setup /etc/pam.d/sudo
In configs below replace $HOSTNAME with output of command `hostname`
We will setup system, so each sudo command will require U2F authentication (for example via touch method).
WARNING! WARNING! WARNING!
WARNING! WARNING! WARNING!
If you setup pam_u2f module only as "sufficient" for authentication, you will be still able to execute sudo commands with user password only! I dont recommend this as you will have same situation as without U2F security token, for example if somebody will obtain your password (phising?), he can remotely execute commands as root via sudo.
Much better is to force every sudo command to require U2F authentication (via touch for example).
Entering sudo password could be optional, because you are already logged in as user (which uses same password as sudo command).
So here are 2 scenarios for finishing your work:
4.a) If you WANT to have U2F confirmation AND also want to enter SUDO password, then
# setup these auth lines in /etc/pam.d/sudo auth required pam_u2f.so origin=pam://$HOSTNAME appid=pam://$HOSTNAME authfile=/etc/u2f_mappings cue auth include system-auth
This is recommended method and true two factor authentication.
Result will looks like this:
[host ~]$ sudo -i Please touch the device. [sudo] password for user: [host ~]#
4.b) If you WANT to have only U2F confirmation before executing sudo command, then
# setup these auth lines in /etc/pam.d/sudo auth [success=done new_authtok_reqd=done default=die] pam_u2f.so origin=pam://$HOSTNAME appid=pam://$HOSTNAME authfile=/etc/u2f_mappings cue auth include system-auth
This method is weaker than first one (=not true 2nd factor, as you only input user password during login) but still safe from attacks on root with phished user password. It all depends on your threat model. One could argue that user data are more important than root data, but that is only true on workstation with one user. In multi-user environment, this could be damage-limiting lifesaver, as it prevents malware/attacker running random root commands via sudo.
Result will looks like this:
[host ~]$ sudo -i Please touch the device. [host ~]#
PS: if you have strange problems with pam auth, add "debug" parameter after pam_u2f.so in /etc/pam.d/sudo, it will help you identifying cause.