Local Authentication Using Challenge Response --------------------------------------------- The PAM module can utilize the HMAC-SHA1 Challenge-Response mode found in YubiKeys starting with version 2.2 for offline authentication. This mode is useful if you don't have a stable network connection to the YubiCloud. The ykpamcfg utility currently outputs the state information to a file in the current user's home directory (`$HOME/.yubico/challenge-123456` for a YubiKey with serial number API readout enabled, and `$HOME/.yubico/challenge` for one without). The PAM module supports a system-wide directory for these state files (in case the user's home directories are encrypted), but in a system-wide directory, the 'challenge' part should be replaced with the username. Example: `/var/yubico/alice-123456`. To use the system-wide mode, you currently have to move the generated state files manually and configure the PAM module accordingly. The following process is tested on Ubuntu 12.04. First install the package: ------ $ sudo apt-get install libpam-yubico ------ You will get a question about the PAM configuration line. Enter this line: ------ mode=challenge-response ------ The next question will be about which PAM modules to enable. Don't enable anything just yet, because you need to program your YubiKey first. If you have already installed the package or want to reconfigure it, you may use this command: ------ $ sudo dpkg-reconfigure libpam-yubico ------ The next step is to add a challenge-response slot to your YubiKey. If you have a normal YubiKey with OTP functionality on the first slot, you could add Challenge-Response on the second slot. You could have CR on the first slot, if you want. First, program a YubiKey for challenge response on Slot 2: ------ $ ykpersonalize -2 -ochal-resp -ochal-hmac -ohmac-lt64 -oserial-api-visible ... Commit? (y/n) [n]: y $ ------ Now, set the current user to require this YubiKey for logon: ------ $ mkdir $HOME/.yubico $ ykpamcfg -2 -v ... Stored initial challenge and expected response in '/home/alice/.yubico/challenge-123456'. $ ------ From security perspective, it is generally a good idea to move the challenge file in a system-wide path that is only read- and writable by root. To do this do as follow: ---- $ sudo mkdir /var/yubico $ sudo chown root.root /var/yubico $ sudo chmod 700 /var/yubico $ ykpamcfg -2 -v ... Stored initial challenge and expected response in '$HOME/.yubico/challenge-123456'. $ sudo mv ~/.yubico/challenge-123456 /var/yubico/alice-123456 $ sudo chown root.root /var/yubico/alice-123456 $ sudo chmod 600 /var/yubico/alice-123456 ---- It is important that the file is named with the name of the user that is going to be authenticated by this YubiKey. Finally we tell the pam module where to look for the challenge file $ emacs /etc/pam.d/common-auth and edit the following line as follow: auth required pam_yubico.so mode=challenge-response chalresp_path=/var/yubico Then back to the PAM configuration step, first make sure you have a root terminal available to be able to disable YubiKey login in case of issues. $ sudo -s Then run the "pam-auth-update" command and enable the Yubico PAM module. $ sudo pam-auth-update You should now be able to authenticate using YubiKey Challenge-Reseponse together with a password like this: ---- jas@latte:~$ sudo -s [sudo] password for jas: root@latte:~# ---- Now remove the YubiKey and try again (in a new terminal to avoid sudo caching), and you should not be able to login. For debugging, you can make the PAM configuration line: mode=challenge-response debug and then create a log file: ---- # touch /var/run/pam-debug.log # chmod go+w /var/run/pam-debug.log ---- and then tail the file. For successful logins it should print something like this: ---- [pam_yubico.c:parse_cfg(721)] called. [pam_yubico.c:parse_cfg(722)] flags 32768 argc 2 [pam_yubico.c:parse_cfg(724)] argv[0]=mode=challenge-response [pam_yubico.c:parse_cfg(724)] argv[1]=debug [pam_yubico.c:parse_cfg(725)] id=-1 [pam_yubico.c:parse_cfg(726)] key=(null) [pam_yubico.c:parse_cfg(727)] debug=1 [pam_yubico.c:parse_cfg(728)] alwaysok=0 [pam_yubico.c:parse_cfg(729)] verbose_otp=0 [pam_yubico.c:parse_cfg(730)] try_first_pass=0 [pam_yubico.c:parse_cfg(731)] use_first_pass=0 [pam_yubico.c:parse_cfg(732)] authfile=(null) [pam_yubico.c:parse_cfg(733)] ldapserver=(null) [pam_yubico.c:parse_cfg(734)] ldap_uri=(null) [pam_yubico.c:parse_cfg(735)] ldapdn=(null) [pam_yubico.c:parse_cfg(736)] user_attr=(null) [pam_yubico.c:parse_cfg(737)] yubi_attr=(null) [pam_yubico.c:parse_cfg(738)] yubi_attr_prefix=(null) [pam_yubico.c:parse_cfg(739)] url=(null) [pam_yubico.c:parse_cfg(740)] capath=(null) [pam_yubico.c:parse_cfg(741)] token_id_length=12 [pam_yubico.c:parse_cfg(742)] mode=chresp [pam_yubico.c:parse_cfg(743)] chalresp_path=(null) [pam_yubico.c:pam_sm_authenticate(775)] get user returned: jas [pam_yubico.c:do_challenge_response(493)] Loading challenge from file /home/jas/.yubico/challenge-1077187 [util.c:load_chalresp_state(269)] Challenge: 23001a190724abf46c8022b008ccb65673dd634ecb150613771ec87f37850284d80dd5f8c8e56affb6da2e952b16682160e7f3ac4f816b64126bd9556e5be1, response: 63d4a679ed15335ffd4253e7609963bcdb0834d4, slot: 2 [pam_yubico.c:do_challenge_response(566)] Got the expected response, generating new challenge (63 bytes). [pam_yubico.c:do_challenge_response(629)] Challenge-response success! ---- and if there is no YubiKey in the machine it will look like this: ---- [pam_yubico.c:parse_cfg(721)] called. [pam_yubico.c:parse_cfg(722)] flags 32768 argc 2 [pam_yubico.c:parse_cfg(724)] argv[0]=mode=challenge-response [pam_yubico.c:parse_cfg(724)] argv[1]=debug [pam_yubico.c:parse_cfg(725)] id=-1 [pam_yubico.c:parse_cfg(726)] key=(null) [pam_yubico.c:parse_cfg(727)] debug=1 [pam_yubico.c:parse_cfg(728)] alwaysok=0 [pam_yubico.c:parse_cfg(729)] verbose_otp=0 [pam_yubico.c:parse_cfg(730)] try_first_pass=0 [pam_yubico.c:parse_cfg(731)] use_first_pass=0 [pam_yubico.c:parse_cfg(732)] authfile=(null) [pam_yubico.c:parse_cfg(733)] ldapserver=(null) [pam_yubico.c:parse_cfg(734)] ldap_uri=(null) [pam_yubico.c:parse_cfg(735)] ldapdn=(null) [pam_yubico.c:parse_cfg(736)] user_attr=(null) [pam_yubico.c:parse_cfg(737)] yubi_attr=(null) [pam_yubico.c:parse_cfg(738)] yubi_attr_prefix=(null) [pam_yubico.c:parse_cfg(739)] url=(null) [pam_yubico.c:parse_cfg(740)] capath=(null) [pam_yubico.c:parse_cfg(741)] token_id_length=12 [pam_yubico.c:parse_cfg(742)] mode=chresp [pam_yubico.c:parse_cfg(743)] chalresp_path=(null) [pam_yubico.c:pam_sm_authenticate(775)] get user returned: jas [pam_yubico.c:do_challenge_response(478)] Failed initializing YubiKey [pam_yubico.c:do_challenge_response(640)] YubiKey core error: no YubiKey present ----