I’m a big fan of MFA, specifically Duo Security‘s product (I did a corporate blog post here). I’ve been using this product for some time and use it for an extra level of protection on my workstations, servers, and customer sites. I liked it so much so that my company (Digitally Accurate Inc.) became a partner and now resells the services.
Here’s a demo of DUO MFA being used with CentOS Linux:
Today I want to write about a couple issues I had when deploying the pam_duo module on CentOS Linux 7. The original duo guide can be found at https://duo.com/docs/duounix, however while it did work for the most part, I noticed there were some issues with the pam configuration files, especially if you are wanting to use Duo MFA with usernames and passwords, and not keys for authentication.
A symptom of the issue: I noticed that when following the instructions on the website for deployment, after entering the username, it would skip the password prompt, and go right for DUO authentication, completely bypassing the password all together. I’m assuming this is because the guide was written for key authentication, but I figured I’d do a quick crash-course post on the topic and create a simple guide. I also noticed that sometimes even if an incorrect password was typed in, it would allow authentication if DUO passed as successful.
Ultimately I decided to learn about PAM, understand what it was doing, and finally configure it properly. Using the guide below I can confirm the password and MFA authentication operate correctly.
To configure Duo MFA on CentOS 7 for use with usernames and passwords
First and foremost, you must log in to your Duo Account and go to applications, click “Protect an Application” and select “Unix Application”. Configure the application and document/log your ikey, secret key, and API hostname.
Now we want to create a yum repo where we can install, and keep the pam_duo module up to date. Create the file /etc/yum.repos.d/duosec.repo and then populate it with the following:
[duosecurity] name=Duo Security Repository baseurl=http://pkg.duosecurity.com/CentOS/$releasever/$basearch enabled=1 gpgcheck=1
We’ll need to install the signging key that the repo uses, and then install the duo_unix package. By using yum, we’ll be able to keep this package regularly up to date when we update the server. Run the following commands:
rpm --import https://duo.com/RPM-GPG-KEY-DUO yum install duo_unix
Configure the pam_duo module by editing the /etc/duo/pam_duo.conf file. You’ll need to populate the lines with your ikey, secret key, and API hostname that you documented above. We use “failmode=safe” so that in the event of an internet disconnection, we can still login to the server without duo. It’s safe to enable this fail-safe, as the purpose is to protect it against the internet. Please see below:
[duo] ; Duo integration key ikey = XXXXXXXXXXXXXXXXXXXX ; Duo secret key skey = XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ; Duo API host host = XXXXXXXXX.duosecurity.com ; Send command for Duo Push authentication pushinfo = yes ; failmode safe if no internet it works (secure locks it up) failmode = safe
Configure sshd to allow Challenge Response Authentication by editing /etc/ssh/sshd_config, then locate and change “ChallengeResponseAuthentication” to yes. Please note that the line should already be there, and you should simply have to move the comment symbol to comment the old line, and uncomment the below line as shown below:
And now it gets tricky… We need to edit the pam authentication files to incorporate the Duo MFA service in to it’s authentication process. I highly recommend that throughout this, you open (and leave open) an additional SSH session, so that if you make a change in error and lock yourself out, you can use the extra SSH session to revert any changes to the system to re-allow access. It’s always best to make a backup and copy of these files so you can easily revert if needed.
DISCLAIMER: I am not responsable if you lock yourself out of your system. Please make sure that you have an extra SSH session open so that you can revert changes. It is assumed you are aware of the seriousness of the changes you are making and that you are taking all precautions (including a backup) to protect yourself from any errors.
Essentially two files are used for authentication that we need to modify. One file is for SSH logins, and the other is for console logins. In my case, I wanted to protect both methods. You can do either, or both. If you are doing both, it may be a good idea to test with SSH, before making modifications to your console login, to make sure your settings are correct. Please see below for the modifications to enable pam_duo:
/etc/pam.d/password-auth (this file is used for SSH authentication)
#%PAM-1.0 # This file is auto-generated. # User changes will be destroyed the next time authconfig is run. auth required pam_env.so auth required pam_faildelay.so delay=2000000 #auth sufficient pam_unix.so nullok try_first_pass auth requisite pam_unix.so nullok try_first_pass auth sufficient pam_duo.so auth requisite pam_succeed_if.so uid >= 1000 quiet_success auth required pam_deny.so account required pam_unix.so account sufficient pam_localuser.so account sufficient pam_succeed_if.so uid < 1000 quiet account required pam_permit.so password requisite pam_pwquality.so try_first_pass local_users_only retry=3 authtok_type= password sufficient pam_unix.so sha512 shadow nullok try_first_pass use_authtok password required pam_deny.so session optional pam_keyinit.so revoke session required pam_limits.so -session optional pam_systemd.so session [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid session required pam_unix.so
/etc/pam.d/system-auth (this file is used for console authentication)
auth required pam_env.so auth sufficient pam_fprintd.so #auth sufficient pam_unix.so nullok try_first_pass # Next two lines are for DUO mod auth requisite pam_unix.so nullok try_first_pass auth sufficient pam_duo.so auth requisite pam_succeed_if.so uid >= 1000 quiet_success auth required pam_deny.so account required pam_unix.so account sufficient pam_localuser.so account sufficient pam_succeed_if.so uid < 1000 quiet account required pam_permit.so password requisite pam_pwquality.so try_first_pass local_users_only retry=3 authtok_type= ucredit=-1 lcredit=-1 dcredit=-1 ocredit=-1 password sufficient pam_unix.so sha512 shadow nullok try_first_pass use_authtok remember=5 password required pam_deny.so session optional pam_keyinit.so revoke session required pam_limits.so -session optional pam_systemd.so session [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid session required pam_unix.so
Now, we must restart sshd for the changes to take affect. Please make sure you have your extra SSH session open in the event you need to rollback your /etc/pam.d/ files. Restart the sshd service using the following command:
service sshd restart
Attempt to open a new SSH session to your server. It should now ask for a username, password, and then prompt for Duo authentication. And you’re done!
More information on Duo Multi Factor Authentication (MFA) can be found here.
Excellent guide. I was also struggling with DUOs guide because we don’t use SSH keys. This guide was awesome and help me set up duo within a few hours and I have absolutely 0 skils with duo!
It is worth noting that duo requires a local OS user. Authenticating Non-OS users (like a web application user) will not work.
Correction: Does not have to be a local OS user, but needs to be a user known to the OS
sorry, it din’t help me. I was able to login even without DUO after I’ve configured everything.
Where can I read the logs?
You’ll have to view the system, secure, and Pam log files. They might be in /var or you might need to find out where your logs are stored depending on your distribution.
I’d recommend you double check your configuration and try again.
I found this in the /var/log/secure
Aug 4 15:20:50 centos-duo1 sshd: Failsafe Duo login for ‘root’ from 192.168.168.168: Couldn’t connect to **********************: Failed to connect
what could be a reason? I even don’t see any network attempts registered on our main FireWall…
That means that the DUO agent was unable to connect to the DUO servers to authenticate the login, and the failsafe mode is configured and enabled.
Fail safe permits a login without MFA, in the event of a network connection drop or failure.
How to fix it? How to make it to connect? Looks like it even doesn’t try as I don’t see any logs on the FireWall
If it happened once, it may have been a temporary disruption.
If it happens all the time, you’ll need to configure your firewall rules to allow the traffic to permit the software to function.
I’ve just configured DUO on Debian – works perfectly. I’m checking CentOS again…
I found a reason which isn’t described in your article: SELinux. I’ve disabled it – it works.
I’m glad to hear you figured it out! That’s good to know!
it’s me again )))
I’ve configured the DUO on a production server, it works even with SELinux but now we have a small issue. After I typed a user name it doesn’t ask me for a password but offers DUO authentication. How can I configure to ask password and then DUO authentication?
If that specific issue is happening, then the Pam config files were modified incorrectly. I’d verify your config and try again. It happened to me once, and was due to the changes being made to the wrong lines.
yes, you are right. I found a reason. this line was commented:
auth substack password-auth
But one more question. If type password incorrectly it still offers the DUO, and only after the DUO confirmation it says “password incorrect”. Is it possible to change the order: to offer DUO authentication only if the password was correct?
I’ve also seen that happen as well, again it’s an issue with placement of the config strings. Once it’s correct it should not occur.
this is my config, what should I change here? or it is another configuration file?
auth required pam_sepermit.so
auth substack password-auth
auth required pam_env.so
auth sufficient /usr/lib64/security/pam_duo.so
auth required pam_deny.so
auth include postlogin
# Used with polkit to reauthorize users in remote sessions
-auth optional pam_reauthorize.so prepare
account required pam_nologin.so
account include password-auth
password include password-auth
# pam_selinux.so close should be the first session rule
session required pam_selinux.so close
session required pam_loginuid.so
# pam_selinux.so open should only be followed by sessions to be executed in the user context
session required pam_selinux.so open env_params
session required pam_namespace.so
session optional pam_keyinit.so force revoke
session include password-auth
session include postlogin
# Used with polkit to reauthorize users in remote sessions
-session optional pam_reauthorize.so prepare
You’re editing the sshd file, you should be modifying the “password-Auth” file for SSH logins.
Ok, I’ve changed it – it works. But one more question. It is said “User changes will be destroyed the next time authconfig is run”, which file should I edit then?
I think that’s specific to your distribution. On my system, I’ve never had to redo the config. I’m not sure what that is referring to.
I followed your configuration its working great for SSH access.
Wandering when do we use “Console authentication” ?
/etc/pam.d/system-auth (this file is used for console authentication)
Is this to access application running using Apache or any web services on this server, by using server credentials ??
Thank you for this excellent guide. I could make it work in RHEL7 very easily with this guide.
Right now I am trying to configure pam_duo and login_duo (duo_unix-1.11.4) in different RHEL platforms, where we already using CentrifyDC (CentrifyDC 5.1.1-831) to integrate with AD.
login_duo is working as expected but in pam_duo we are facing issues (not working at all) as /etc/pam.d/system-auth and /etc/pam.d/password-auth is already modified by Centrify.
Any idea on how can we make it work ? Thanks in advance.
I’m glad the post helped!
I’ve never used it with other software that modified the PAM files, but technically it should work if the entries are put in the list in the right spot and order of authentication process.
If you add these I would recommend playing around with a test environment beforehand just incase of the event you get locked out of the system.
Thank you for you time. I am conducting tests. Will update you if the issue resolves.
Hi, I am trying to implement this same scenario but in a Ubuntu environment. I’m kinda new to the Linux world. Any idea of how I should go about?
The instructions are similar for Ubuntu. If you don’t feel comfortable with the information provided, you should be able to find a guide on Duo’s website that has the instructions for other flavors of Linux.
It’s all handled through PAM. It’s just other distributions have other filenames.
This post is a godsend. I feel like I’m almost there, but am still having the problem of not getting a password prompt — just straight to Duo.
I’m on RHEL 7.9, using AD integration via Realm, SSSD, etc. All of that works perfectly, and is my baseline. In that config, I’m prompted as I should be for my AD password.
But when I add Duo following your instructions, I get:
login as: [email protected]
Using keyboard-interactive authentication.
But no password prompt. Instead straight to Duo
Duo two-factor login for [email protected]
Enter a passcode or select one of the following options:
1. Duo Push to XXX-XXX-3094
2. Phone call to XXX-XXX-3094
3. SMS passcodes to XXX-XXX-3094
Passcode or option (1-3):
Any insight on where to look?
I’m glad if the post is helping! 🙂
Usually, if any of the order is messed up (password after DUO instead of in front of DUO), it’s because of the order/config inside of the PAM configuration file.
I’m not familiar with how your AD SSO is enabled, but technically the DUO PAM entries should be after the AD password/authentication item instead of the config file.
Hope this helps!
Quick question: (and this may show my inexperience…lol) One of the file you indicate I should edit is system generated. Won’t the change get lost at the next reboot? (/etc/pam.d/password-auth)
Also, and this is purely a suggestion: it might make it easier for newbies like me if you highlighted what section of the file we are to edit. It’s not hard to figure out but I could easily see myself missing a change. Purely cosmetic stuff. 😉
Thank you for the guide, I will try it today and should I have questions, I’ll reach out.
Thanks for leaving a comment! 🙂
These files are auto-generated on the Linux install, and I think only ever once I saw them get re-generated (which means you just need to update the new files). This happened when an update came out for PAM.
Additionally, I’ve noticed that depending on what version gets installed, the format of the files is different. So unfortunately I couldn’t provide a screenshot since it might look different for different groups of people.
I hope the post helps though! Let me know as to your success!
I did the setup and it works with Duo but for some reason, after a Duo authentication, I don’t get prompted for a password. Any ideas as to what I might have missed? I’m sure it’s very simple but I’m not very knowledgeable with PAM.
It sounds like you’re close. Did you change “pam_unix” from sufficient to requisite?
I am getting below error in /var/log/secure file:
The gecos_parsed configuration item for Duo Unix is deprecated and no longer has any effect. Use gecos_delim and gecos_username_pos instead
Failsafe Duo login for ‘[email protected]’ from 126.96.36.199: Couldn’t connect to api-xxxxxxx.duosecurity.com: Failed to connect
Could you please help me on this issue?
I’ve tried the below solution but it didn’t help in my case.
– Disabling the SELinux
In this post, I don’t use any of the GECOS configuration fields. Is there a chance you used a different guide to configure DUO, or used the wrongs fields?
If you are using these, you need to use the updated configuration items.
HI Mr. Wagner,
I have managed to setup my Cent OS to use DUO. It seems to work ok. The last thing I’m trying to do is to setup this host as a jump host to get to another machine. When I do so, it seems to bypass DUO entirely for some reason. Have you ever encountered this before?Is there something that I might be overlooking?
When I get to the first host, I get prompted for a password (I setup DUO as a 2nd factor to the regular password). Then, it looks like it simply jumps to the second (and endpoint) host – the DUO stuff never comes up (I left DUO configured to prompt the user for what he wants to do, I’m not forcing autopush at this time)
When I do the process manually, the first host prompts for the password, with a correct password proceeds to the DUO authentication. The user chooses if he wants a push notification or if he wants an SMS text message. Once past that point, the login completes.
I’m kind of lost why it behaves differently. If you have any suggestions, that would be awesome.
Hi PRochetfort, when you say you’re using the system as a jumphost, how do you have that configured and how are you using it? Without knowing the technical specifics, I can’t really comment or advise.