Services/yubikey

From popdata
Jump to: navigation, search

Introduction

Yubikeys will replace the SecurID tokens we currently use. They have the following advantages:

  • All software needed to use them is open source with no licensing fees
  • Clients built into newest version of debian (and ubuntu)
  • Tokens are $15/each and don't expire (SecurID are about $60 + licensing and good for 3 years)
  • No need to read and type 6 digit code, just press the button
  • No more PIN, it is just your regular password.
  • Integrates with LDAP
  • Can be administered via PDS
  • Smaller form factor
  • We can (and do) write our own secret key into them. (SecurID's secret key is known by the company RSA, and they have had a security breach in the past)

Disadvantages:

  • requires a USB slot (therefore doesn't work on an iPad/iPhone or machines with no available USB slot)

Good article: http://www.linuxjournal.com/magazine/yubikey-one-time-password-authentication

  === Initial Setup ===

There are a few parameters:

  • serial number (written on the key in decimal)
  • public identity (first 12 digits of OTP)
  • private identity
  • secret key

The private identity, a sequence counter, timestamp are encrypted with the secret key, and output with the public identity as the one time password. It looks something like:

linkccbrbtrllibnthbbhihfnrkteenvjhlhjhvkbvgn

In this cas the public identity is: li nk cc br bt rl. The first 2 bytes li nk is our code (link as in linkage :) ), cc is fixed, and the last 3 bytes form the serial number. (all of these are encoded in modhex, a variation on hexadecimal)

So the configuration of yubikey-personalization-gui is:

  • Settings tab
  • Use and enforce customer prefx: Modhex: link (a7b9 hex)
  • Use fast triggering if only slot 1 is programmed
  • Yubico OTP mode tab
  • Advanced
  • Configuration Slot 1
  • Program Multiple Key
  • Automatically program Yubikeys when inserted
  • Identity from serial; Randomize Secrets
  • YubiKey(s) unprotected - Enable protection (access code: change it to 19 69 04 17 12 00)
  • Write configuration to start
  • prompted for log file (you need this to feed to authentication server)

Client Configuration

We use PAM to handle ssh authentication. Config for /etc/pam.d/sshd should be changed to:

# Standard Un*x authentication (Prompt: "Password: "; Remove for YubiKey)                                                                        
#not_with_yubi# @include common-auth                                                                                                             
 
# 4 lines for yubikey: pam_yubico pam_unix pam_ldap pam_deny (and comment out common-auth above)                                                 
# Prompt: "Yubikey for `USERNAME': " (no echo; CTRL-U clears input)                                                                              
auth    required        pam_yubico.so   debug url=http://champlain.popdata.bc.ca:8000/wsapi/2.0/verify?id=%d&otp=%s id=1 key=TnFUVXdTdGliMENwTmdIQzRKYUs= ldap_uri=ldap://ldap.popdata.bc.ca/ ldapdn=ou=users,dc=popdata,dc=bc,dc=ca ldap_filter=(uid=%u) yubi_attr=yubiKeyId
auth    [success=done default=ignore]      pam_unix.so nullok_secure use_first_pass debug
auth    [success=done default=ignore]      pam_ldap.so use_first_pass debug
auth    required        pam_deny.so
Note: RedZone pam.d/sshd uses url=10.180.20.20 [Mackenzie]
Note: filter=(uid=%u) became required in 2019.
  • Also change /etc/ssh/sshd_config to allow challenge-response, to block all keys except for pulse,
    #AuthorizedKeysFile  %h/.ssh/authorized_keys
    AuthorizedKeysFile /etc/ssh/authorized_keys/%u/authorized_keys
    ChallengeResponseAuthentication yes
    PasswordAuthentication no
  • From /etc/ssh , mkdir -p authorized_keys/pulse && cp -i /home/pulse/.ssh/authorized_keys authorized_keys/pulse/.
  • Restart sshd: /etc/init.d/ssh reload . After this, ssh prompt will be "Enter YubiKey for ..." :
  • Also make sure that "dpkg -l libpam-yubico" shows version 2.23-1 or newer.

Basically pam_yubico does:

  • password is passed to pam_yubico module.
    • the module splits the user password from the OTP (OTP is fixed length)
    • the module checks that the public key (first 12 characters) is registered to that user in ldap (attr: yubikeyid)
    • the OTP is passed to the authentication server via a web call to champlain on port 8000
    • the authentication server verifies that the key is encrypted with the corrected key, etc.
  • if pam_yubico is successful it sets the password to just the user password
  • the pam_unix module trys that password. If it succeeds authentication is successful
  • if pam_unix fails, then pam_ldap is tried, if it succeeds authentication is successful
  • otherwise the pam_deny is called (which returns failure and the authentication fails)
  • 2019-07-02 /Denis implementing pam_yubikey as above, get error (IP is my desktop)
    error: PAM: Authentication service cannot retrieve authentication info for dlaplante from 10.90.10.241

RedZone setup

screensaver on Franklin

  • log of successful screensaver unlock with yubikey on Franklin /var/log/auth.log looks like:
    • xscreensaver: pam_unix(xscreensaver:auth): authentication failure; logname= uid=4086 euid=4086 tty=:0.0 ruser= rhost= user=dlaplante
  • log of failed screensaver unlock (wrong password, good yubikey)
    • xscreensaver: pam_unix(xscreensaver:auth): authentication failure; logname= uid=4086 euid=4086 tty=:0.0 ruser= rhost= user=dlaplante
    • xscreensaver: pam_ldap(xscreensaver:auth): authentication failure; user=dlaplante

Server Setup

  • Currently we are running: [1]
  • runs on champlain
  • in /usr/local/yubico-yubiserve
  • python yubiserve.py
  • database is managed with: ./dbconf.py
  • List all keys: ./dbconf.py -yl
  • Add a new key: ./dbconf.py -ya linkccbrcncc linkccbrcncc 582f8e286f28 a2e5b477edead71ea37d0da2d43b9e9e
  • values come from the log file of yubikey-personalization-gui

LDAP Setup

  • added a schema for yubikeyid in champlain:/etc/ldap/schema/yubikey.schema
  • included the schema in /etc/ldap/slapd.conf
  • restarted slapd

Cisco Setup

  • create new AAA group
  • point to radius server on champlain
  • rest is the same is other AAA groups, and still uses DAP to verify users are allowed in tunnel group

FreeRadius on Champlain for authentication & authorization via PAM

  • champlain runs freeradius
  • config is in /etc/freeradius/radiusd.conf
  • configured to do authentication via PAM
  • pam config in /etc/pam.d/radiusd
  • logs in /var/log/freeradius
  • back-end /usr/local/yubico-yubiserve/.py listens on 8000/TCP ; status messages are discarded, unless daemon killed and process run from terminal
    • can capture on Champlain all interfaces (esp. loopback): tshark -i any -n -c 99 -w newcapture.pcap "port 8000" (capture till ^C or 99 packets into file newcpture.pcap)

FreeRadius trouble

  • Every 1000 logins, freeradius exceeds max files open (bug: re-opens /dev/urandom). See https://otrs.popdata.bc.ca/index.pl?Action=AgentTicketZoom;TicketID=2026#8610 "restarting freeradius on champlain".
    • DIAGNOSTIC: on Champlain: lsof /dev/urandom | wc
  • 2013-12-05 YubiKey authentications failed 07:58, OK after Denis restarted FreeRadius 09:26
    • No hint in logs; LDAP logs for logins that morining have hint:
    • 05:31 success; 6 matches for "SRCH attr=yubiKeyId"
    • 07:58 first failure: has matches for "rlipson" but none for "SRCH attr=yubiKeyId"
    • 09:23 last failure: has no matches for laplante !?!
  • 2013-11-07 YubiKey authentications failed 07:58, OK after Jim restarted FreeRadius 12:31
    • 09:11 nrazaz last success
    • 12:29 jim last failure
  • 2014-01-08 cron job every Sunday morning 03:01 : /etc/init.d/freeradius restart
  • 2017-12-19 freeradius now has zero instances of /dev/urandom open after 2.5 days. Fixed for freeradius v3 (champlain upgraded 2017-11-06). http://lists.freeradius.org/pipermail/freeradius-users/2016-August/084522.html Can remove cron job.

FreeRadius sample logs on Champlain

See below for success and failure on auth.log, radius.log, LDAP

Sample logs for unsuccessful Yubikey login by testuser1

  • RADIUS: Champlain : /var/log/freeradius/radius.log (same for wrong passphrase / yubikey; blank for success.
    Note that username is missing - must match exact time).
    Wed Dec 20 11:45:44 2017 : ERROR: (163) pam: ERROR: pam_authenticate failed: Authentication failure
    Wed Dec 20 11:46:07 2017 : ERROR: (164) pam: ERROR: pam_authenticate failed: Authentication failure
    Wed Dec 20 13:58:34 2017 : ERROR: (175) pam: ERROR: pam_authenticate failed: Authentication failure
  • PAM : Champlain : /var/log/auth.log
    NOTES: the first 2 are supposed to fail and try next method. The third is for yubikey, but says nothing about passphrase.
    [bad passphrase, wrong yubikey] Dec 20 11:45:42 [2017] champlain freeradius: pam_unix(radiusd:auth):
    pam_unix(radiusd:auth): authentication failure; logname= uid=0 euid=0 tty= ruser= rhost= user=testuser1
    pam_ldap(radiusd:auth): nslcd authentication; user=testuser1
    pam_ldap(radiusd:auth): Authentication failure; user=testuser1
    [bad passphrase, good yubikey] Dec 20 13:58:31 champlain freeradius:
    pam_unix(radiusd:auth): authentication failure; logname= uid=0 euid=0 tty= ruser= rhost= user=testuser1
    pam_ldap(radiusd:auth): nslcd authentication; user=testuser1
    pam_ldap(radiusd:auth): Authentication failure; user=testuser1
    [good passphrase, bad yubikey] Dec 20 11:46:05 champlain freeradius:
    pam_unix(radiusd:auth): authentication failure; logname= uid=0 euid=0 tty= ruser= rhost= user=testuser1
    pam_ldap(radiusd:auth): nslcd authentication; user=testuser1
    pam_ldap(radiusd:auth): authentication succeeded
    [good passphrase, good yubikey] Dec 20 11:46:35 champlain freeradius: pam_unix(radiusd:auth):
    authentication failure; logname= uid=0 euid=0 tty= ruser= rhost= user=testuser1
    pam_ldap(radiusd:auth): nslcd authentication; user=testuser1
    pam_ldap(radiusd:auth): authentication succeeded
  • LDAP : Champlain : /var/log/syslog (BIG)
    [bad passphrase, wrong yubikey]
    [2017] Dec 20 11:45:42 champlain slapd[1015]:
    conn=1006 op=14446 SRCH base="dc=popdata,dc=bc,dc=ca" scope=2 deref=0 filter="(&(objectClass=posixAccount)(uid=testuser1))"
    conn=1006 op=14446 SRCH attr=uidNumber cn gecos uid objectClass homeDirectory gidNumber loginShell
    conn=1006 op=14446 SEARCH RESULT tag=101 err=0 nentries=1 text=
    conn=1004 op=13607 SRCH base="dc=popdata,dc=bc,dc=ca" scope=2 deref=0 filter="(&(objectClass=shadowAccount)(uid=testuser1))"
    conn=1004 op=13607 SRCH attr=shadowFlag shadowMax shadowMin shadowLastChange uid shadowExpire shadowInactive shadowWarning
    conn=1004 op=13607 SEARCH RESULT tag=101 err=0 nentries=0 text=
    conn=632766 fd=81 ACCEPT from IP=10.80.20.80:55184 (IP=0.0.0.0:389)
    conn=632766 op=0 BIND dn="" method=128
    conn=632766 op=0 RESULT tag=97 err=0 text=
    conn=632766 op=1 SRCH base="ou=users,dc=popdata,dc=bc,dc=ca" scope=2 deref=0 filter="(uid=testuser1)"
    conn=632766 op=1 SRCH attr=yubiKeyId
    conn=632766 op=1 SEARCH RESULT tag=101 err=0 nentries=1 text=
    conn=632766 op=2 UNBIND
    conn=632766 fd=81 closed
    conn=1004 op=13608 SRCH base="dc=popdata,dc=bc,dc=ca" scope=2 deref=0 filter="(&(objectClass=posixAccount)(uid=testuser1))"
    conn=1004 op=13608 SRCH attr=uid uidNumber
    conn=1004 op=13608 SEARCH RESULT tag=101 err=0 nentries=1 text=
    conn=632767 fd=81 ACCEPT from IP=10.80.20.80:55186 (IP=0.0.0.0:389)
    conn=632767 op=0 BIND dn="uid=testuser1,ou=external,ou=users,dc=popdata,dc=bc,dc=ca" method=128
    slap_global_control: unrecognized control: 1.3.6.1.4.1.42.2.27.8.5.1
    conn=632767 op=0 RESULT tag=97 err=49 text=
    Dec 20 11:45:42 champlain nslcd[1213]:
    [f37044] <authc="testuser1"> uid=testuser1,ou=external,ou=users,dc=popdata,dc=bc,dc=ca: Invalid credentials
  • [good passphrase, bad yubikey] ???
    Dec 20 11:46:05 champlain slapd[1015]:
    conn=1004 op=13610 SRCH base="dc=popdata,dc=bc,dc=ca" scope=2 deref=0 filter="(&(objectClass=shadowAccount)(uid=testuser1))"
    conn=1004 op=13610 SRCH attr=shadowFlag shadowMax shadowMin shadowLastChange uid shadowExpire shadowInactive shadowWarning
    conn=1004 op=13610 SEARCH RESULT tag=101 err=0 nentries=0 text=
    [...]
    conn=632772 op=0 BIND dn="uid=testuser1,ou=external,ou=users,dc=popdata,dc=bc,dc=ca" method=128
    slap_global_control: unrecognized control: 1.3.6.1.4.1.42.2.27.8.5.1
    conn=632772 op=0 BIND dn="uid=testuser1,ou=external,ou=users,dc=popdata,dc=bc,dc=ca" mech=SIMPLE ssf=0
    conn=632772 op=0 RESULT tag=97 err=0 text=
    conn=632772 op=1 SRCH base="uid=testuser1,ou=external,ou=users,dc=popdata,dc=bc,dc=ca" scope=0 deref=0 filter="(objectClass=*)"
    conn=632772 op=1 SRCH attr=dn
    conn=632772 op=1 SEARCH RESULT tag=101 err=0 nentries=1 text=

Sample logs for successful Yubikey login

  • RADIUS: Champlain : /var/log/freeradius/radius.log
    [blank]
  • LDAP [good passphrase, good yubikey]
    Dec 20 11:46:35 champlain slapd[1015]:
    conn=1004 op=13613 SRCH base="dc=popdata,dc=bc,dc=ca" scope=2 deref=0 filter="(&(objectClass=shadowAccount)(uid=testuser1))"
    conn=1004 op=13613 SRCH attr=shadowFlag shadowMax shadowMin shadowLastChange uid shadowExpire shadowInactive shadowWarning
    [...]
    conn=632812 op=0 BIND dn="uid=testuser1,ou=external,ou=users,dc=popdata,dc=bc,dc=ca" method=128
    slap_global_control: unrecognized control: 1.3.6.1.4.1.42.2.27.8.5.1
    conn=632812 op=0 BIND dn="uid=testuser1,ou=external,ou=users,dc=popdata,dc=bc,dc=ca" mech=SIMPLE ssf=0
    conn=632812 op=0 RESULT tag=97 err=0 text=
    conn=632812 op=1 SRCH base="uid=testuser1,ou=external,ou=users,dc=popdata,dc=bc,dc=ca" scope=0 deref=0 filter="(objectClass=*)"
    conn=632812 op=1 SRCH attr=dn
    conn=632812 op=1 SEARCH RESULT tag=101 err=0 nentries=1 text=* LDAP: Champlain : /var/log/syslog
  • auth.log
    Dec 20 11:46:05 champlain freeradius:
    pam_unix(radiusd:auth): authentication failure; logname= uid=0 euid=0 tty= ruser= rhost= user=testuser1
    pam_ldap(radiusd:auth): nslcd authentication; user=testuser1
    pam_ldap(radiusd:auth): authentication succeeded

Procedure for issuing a Yubikey

  1. Issuer (someone from "department" S&S, RLU, Privacy ...) fills out current version of "Yubikey Form.doc" (3 pages titled "YubiKey Security Token Requisition Form") from \\gilbert\alfresco\Privacy\Administrative Items\FOB and Confidentiality Forms\SecurID Token Forms\
  2. User reads attached policy, signs and returns from to
    • Kaitlyn Gutteridge / Population Data BC / 201-2206 East Mall / Vancouver BC V6T 1Z3
  3. When signed form has been received, associate the Yubikey with the user's login using PDS.
    • In PDS View the primary user and click on [Change YubiKey].
    • Only one Yubikey can be associated with an account via PDS (but more via low-level LDAP utilities). You can type in the 8-digit serial number, or tap on the YubiKey. Any previous YubiKey(s) will gets dissociated from this account.
    • To dissociate a YubiKey from an account, delete the serial number in the [Change YubiKey] form.
  4. Delivery
    • Off Campus users: S&S staff would confirm current adress of user and send the key via courier or registered mail.
    • On Campus users will be asked to contact the RLU to arrange for in-person pickup.
  5. After user acknowledges receiving Yubikey, enable VPN with Yubikey.

YubiKey models

  • Our original model is very dark grey; the brass disk has a small hole in the middle; the serial# has 2 sets of 4 digits starting with 0; green LED shines steady green when ready.
  • Yubikey 4 Late 2016 purchase is black; the brass disk has a Y in the middle; serial# has 7 digits; green LED shines briefly when plugged in, and for 3 seconds after use. Probably as an indicator of communication activity, of which there is a flurry when first plugged into Windows.
  • Several of our Yubikeys are programmed to produce a different code depending on timing. The timing that works for Popdata is 1 second or less, about the time to sing "Mary had a".

testing a yubikey

List all yubikeys

  • List all YubiKey numbers (and linkcc string but not users) known to PopData
    • /usr/local/yubico-yubiserve/dbconf.py -yl
  • List all users with yubikey strings known to PDS
    • LDAP_BASE=dc=popdata,dc=bc,dc=ca; LDAP_HOST=champlain.popdata.bc.ca; LDAP_LOGIN="uid=dlaplante,ou=popdata,ou=users,dc=popdata,dc=bc,dc=ca"
    • ldapsearch -b $LDAP_BASE -h $LDAP_HOST -D $LDAP_LOGIN -W -x yubiKeyId='*' uid yubiKeyId | sed -e '/^#/d' -e '/dn:/d'
  • Champlain:/usr/local/bin/list-yubikeys.pl combines the above 2 sources.