Pages

May 5, 2017

U2F + sudo + Fedora 25

This article is for owners of U2F security keys (Universal 2nd Factor), which would like to harden their sudo command. We will setup Fedora 25 system, so every sudo command will require 2nd factor authentication via usage of U2F security token.


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

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)       ALL

Dont 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! 

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.