1st Factor aside from password?


its been a while… As we dive in into this service, which is nowadays hot as pancake (or maybe not) we encounter some insights/thoughts about how to implement or adjust this system to our needs. We are currently testing Privacyidea as our 2FA System to cater the need for higher authentication standards, reduce security risk as well as not to divert and/or make much changes to the current infrastructure. In short, integrate this to our current systems/workflow.

I was wondering if this case is already or would be possible (by extending a little help through subscription)? Currently, the only first factor with a challenge-response using PI is the password (correct me if im wrong). Be it a ldap password or password in the db. Is there a posibility to have other first factor such as kerberos tickets or ssh-key instead of passwords? The second factor will be demanded after the first is successful. I was testing combinations of pam modules to address this problem but to no success.

Does anyone have the same or at least encountered such scenario?

  • user can login with krb5 (probably difficult because ssh uses gssapi?) or ssh-key
  • if correct, then maybe a pam module can forward the successful result of the first module to the PI module which will already suffice the 1st Factor to get the challenge for the 2nd factor
  • then inputs the response to authenticate completely

anyway, any ideas?



In my company I was responsible person for deploy of 2FA with privacyID3A on our linux hosts.
I was able to set up configuration where first factor was SSH-KEY (also secured with password) and after that console ask for OTP code.
If you want I can post needed PAM and SSH configuration lines.


Hi Michal,

that would be great! Then i would not be taking too much time to figure out a logical flow for this. It would definitely help me and others who will find this relevant.


As @lewandowskim pointed out in case of SSH this is rather simple stacking the auth modules with required.

There is also a blog post about it.

OTP tokens (push butont), Yubikeys, Smartphone Apps (Google Auth) would work right out of the box.
Well, if you want to use a challenge response token like SMS or Email, there is the REST API /validate/triggerchallenge, which can trigger the challenge without a user input. But this would have to be added to the privacyIDEA PAM code.

Kind regards

My example is base on SLES implementation of privacyID3A.

First you need to install needed dependencies:
zypper in gcc python-devel pam_radius sqlite-devel

Next install of phyton pip and privacyideaadm which is needed to fetch RSA key:
wget http://peak.telecommunity.com/dist/ez_setup.py; chmod +x ez_setup.py; python ez_setup.py; rm -v ez_setup.py; easy_install pip; pip install https://pypi.python.org/packages/12/f5/913b861ae921eab7a9fbe12e4b7915baf6a751a6698c09789be149274144/privacyideaadm-2.15.tar.gz

Now you need to create directory and put file in there:
mkdir /etc/privacyidea
vim /etc/privacyidea/authorizedkeyscommand
URL is address of you privacyID3A UI, you should also create second admin account with low privlidges and put login and password in this file. It should look similar to this
url = https://<address_of_PI_UI>
admin = <admin_login>
password = <strong_password>
nosslcheck = false

Next is configuration of radius:
vim /etc/raddb/server
<IP_of_PI_server> <radius_password> 5

PAM should be configured like this:
cp /etc/pam.d/common-auth /etc/pam.d/otp-auth
vim /etc/pam.d/otp-auth
auth required pam_env.so
auth sufficient pam_radius_auth.so
auth requisite pam_succeed_if.so
auth required pam_deny.so

And in vim /etc/pam.d/sshd change common-auth to otp-auth

And SSH:
vim /etc/ssh/sshd_config
AuthorizedKeysCommand /usr/bin/privacyidea-authorizedkeys
AuthorizedKeysCommandUser <username>
AuthenticationMethods publickey,keyboard-interactive
ChallengeResponseAuthentication yes
PasswordAuthentication no

If you got some additional questions please let me know.
I also use WinAuth to copy-paste OTP code to putty window and Putty Pageant to serve SSH key.



Thanks for your responses! Maybe an additional info regarding my system would be more helpful to clear up misunderstandings:

  • OS: Ubuntu xenial
  • Privacyidea: 2.19.1-1xenial
  • DB: mysql
  • Plug-in: privacyidea-pam
  • Privacyidea Policy:
    – authentication : { “reset_all_user_tokens”: true, “challenge_response”: “yubikey hotp sms totp”, “otppin”: “none” }

The pseudo- ssh login workflow would be this:
if user has krb5 ticket, then just require 2FA through privacyidea-pam
else, do require password authentication then require 2FA

Since we needed to do ssh authentication using kerberos and the additional authentication would be handled by the privacyidea-pam, I pushed through probing few configurations and it turns out that the only problem with the authentication workflow is how to determine if the user is already authenticated through ssh’s gssapi-with-mic. I did a dirty workaround and was able to do this through pam.

@cornelinux - Thanks! After reading your comment I remembered, indeed you had this topic already here where I got the idea how I could do a combination of the AuthenticationMethods + the dirty workaround.

@lewandowskim - Thanks for the input regarding ssh-key, although I am not using RADIUS there are things which i find interesting in your configurations. I would try it later on.

For reference, this is my common-auth-2fa

auth    requisite                       pam_succeed_if.so uid >= 1000 quiet_success
#check if user with krb5 gssapi partialy authenticated
auth    [success=1 default=ignore]      pam_exec.so quiet log=/var/log/ssh-2fa-log /usr/bin/check_krb5_auth.sh
auth    requisite                       pam_sss.so 
auth    [success=1 default=die]         pam_python.so /lib/security/privacyidea_pam.py url=https://privacyideaserver realm=ssh_realm nosslverify debug
auth    requisite                       pam_deny.so
auth    required                        pam_permit.so

However, i encountered something which puzzles me. Since i have otppin:none in my authentication policy, the pam-plugin only requires the OTP (one generated from tokens) and not any fixed password. Correct, but in this case only my HOTP/TOTP token proceeds and my Yubikey fails.

Using HOTP - succeeded

➜ ~ ssh -l user privacyideaserver
Authenticated with partial success.
Your OTP:
Welcome to Ubuntu 16.04.3 LTS (GNU/Linux 4.4.0-96-generic x86_64)

Using Yubikey - failed

➜ ~ ssh -l user privacyideaserver
Authenticated with partial success.
Your OTP:
Your OTP:
Your OTP:
Permission denied (keyboard-interactive).
➜ ~
#see [1] says that the pin is wrong, even though otppin is set to none.

if I just press ‘Enter/Return’ on the ‘Your OTP:’ prompt, a second prompt asks me for the otp. Using either HOTP/TOTP or Yubikey this time will lead to a successful authentication.

  • yubikey
    ➜ ~ ssh -l user privacyideaserver
    Authenticated with partial success.
    Your OTP:
    please enter otp: iiifjhniflkuhttgetnjheclundegcjthkbrlhlfhdit
    Welcome to Ubuntu 16.04.3 LTS (GNU/Linux 4.4.0-96-generic x86_64)
    #see [2] for log

  • HOTP
    ➜ ~ ssh -l user privacyideaserver
    Authenticated with partial success.
    Your OTP:
    please enter otp: 061962
    Welcome to Ubuntu 16.04.3 LTS (GNU/Linux 4.4.0-96-generic x86_64)

I would assume that the second one ‘please enter otp:’ is the triggered challenge prompt. Or am i wrong to assume that if otppin is set to none ‘otppin:none’, Authentication is only done via the OTP value from tokens (not PIN or Password from any source)?

Aside from what is mentioned above, the answer to the original question with regards to the 1st factor aside from password-- you already answered it, Thanks!

[1] /var/log/auth.log

Oct  5 13:48:04 privacyideaserver sshd: Authenticating user against https://privacyideaserver
Oct  5 13:48:05 privacyideaserver sshd: requests > 1.0
Oct  5 13:48:05 privacyideaserver sshd: privacyidea_pam: result: {u'status': True, u'value': False}
Oct  5 13:48:05 privacyideaserver sshd: privacyidea_pam: detail: {u'message': u'wrong otp pin', u'threadid': 139691911636736}
Oct  5 13:48:05 privacyideaserver sshd[11229]: error: PAM: Authentication failure for user from

[2] /var/log/auth.log

Oct  5 13:50:25 privacyideaserver sshd: Authenticating user against https://privacyideaserver
Oct  5 13:50:26 privacyideaserver sshd: requests > 1.0
Oct  5 13:50:26 privacyideaserver sshd: privacyidea_pam: result: {u'status': True, u'value': False}
Oct  5 13:50:26 privacyideaserver sshd: privacyidea_pam: detail: {u'multi_challenge': [{u'attributes': None, u'serial': u'UBAM000249AF', u'transaction_id': u'17359369666549863285'}, {u'attributes': None, u'serial': u'OATH0011B3E2', u'transaction_id': u'17359369666549863285'}], u'threadid': 139691911636736, u'attributes': None, u'message': u'please enter otp: ', u'serial': u'OATH0011B3E2', u'transaction_id': u'17359369666549863285'}
Oct  5 13:50:26 privacyideaserver sshd: Prompting for challenge response
Oct  5 13:50:49 privacyideaserver sshd: requests > 1.0
Oct  5 13:50:49 privacyideaserver sshd: privacyidea_pam: result: {u'status': True, u'value': True}
Oct  5 13:50:49 privacyideaserver sshd: privacyidea_pam: detail: {u'message': u'Found matching challenge', u'serial': u'UBAM000249AF', u'threadid': 139691911636736}
Oct  5 13:50:49 privacyideaserver sshd[11382]: Accepted keyboard-interactive/pam for user from port 45450 ssh2
Oct  5 13:50:49 privacyideaserver sshd[11382]: pam_unix(sshd:session): session opened for user user by (uid=0)
Oct  5 13:50:49 privacyideaserver systemd-logind[736]: New session 35 of user user.
Oct  5 13:50:49 privacyideaserver systemd: pam_unix(systemd-user:session): session opened for user user by (uid=0)

I’d suggest looking at sshd’s Authentications methods. There you can define two or
more “streams” for authentication. e.g. Using ( ssh-keys and OTP) or (krb5 and OTP)…
Here’s my config:

# For OTP users we require special authentication methods. There are
# two possible paths to authentication:
# - if the user has a GSSAPI/Kerberos ticket, we grant access
# - otherwise we require a ssh key and successful authentication
#   against PAM (where we require and OTP key)
# We might add keyboard-interactive:pam to allow only password access,
# but for that we use a fallback user right now
Match Group otpusers
    AuthenticationMethods gssapi-with-mic publickey,keyboard-interactive:pam

You’d probably use “gssapi-with-mic,keyboard-interactive:pam” with a suitable pam config.

Hi Jochen,

i already have this in my sshd_conf. Sorry i forgot to include this on my previous reply.

AuthenticationMethods gssapi-with-mic,keyboard-interactive:pam keyboard-interactive:pam

This will first check if the user can be authenticated with gssapi then proceed with pam or directly through pam if there is no krb5 ticket to be authenticated through gssapi. I have a checking script in /etc/pam.d/common-auth-2fa which will check if the user was already authenticated through gssapi therefore skiping the pam_sss.so and continue with privacyidea_pam.py. Since the option ‘otppin:none’ is set in my authentication policy for the realm, I would assume that only the triggered challenge will be prompted. I am a little confused as what the first response ‘Your OTP’ is. If I input a HOTP/TOTP token in this field, the authentication ens successfully but not the same case if i press the yubikey.

If i just press ‘Enter/Return’ (no input) on the ‘Your OTP:’ prompt, it proceeds with the challenge with the prompt ‘please enter otp:’. Here, i can use either of the tokens i have (HOTP, Yubikey) and get authenticated.

Note: The actual question to this topic is already answered by @cornelinux, should I open another Topic for this?

Thanks for helping and regards,

You are welcome to discuss some sshd optimized configs! This might be clearer and easier to find for others.