Skip navigation
Documentation

Duo Unix - Two-Factor Authentication for SSH with PAM Support (pam_duo)

Last Updated: November 6th, 2024

Duo can be easily added to any Unix system to protect remote (SSH) or local logins with the addition of a simple pam_duo PAM module. It has been tested on Linux (RedHat, Fedora, CentOS, Debian, Ubuntu, Amazon Linux), BSD (FreeBSD, NetBSD, OpenBSD), Solaris, and AIX. The code is open-source and available on GitHub.

Duo Network Gateway provides SSH access to internal hosts without a VPN or jump host with trusted endpoint detection and session awareness. Learn more.

Overview

Duo Unix with Pluggable Authentication Modules (PAM) support provides a secure and customizable method for protecting Unix and Linux logins. We recommend deploying the pam_duo module in most scenarios, but if you are unable to use PAM see our login_duo instructions.

Connectivity Requirements

This application communicates with Duo's service on SSL TCP port 443.

Firewall configurations that restrict outbound access to Duo's service with rules using destination IP addresses or IP address ranges aren't recommended, since these may change over time to maintain our service's high availability. If your organization requires IP-based rules, please review Duo Knowledge Base article 1337.

Effective June 30, 2023, Duo no longer supports TLS 1.0 or 1.1 connections or insecure TLS/SSL cipher suites. See Duo Knowledge Base article 7546 for additional guidance.

FIPS Support

Duo Unix is FIPS-compliant as of version 1.10.4 when run on any machine that has an operating system-wide FIPS mode (like CentOS/RedHat 7, Ubuntu 16.04, etc.). No additional flags or options are required.

Walkthrough Video

 

First Steps

Before moving on to the deployment steps, it's a good idea to familiarize yourself with Duo administration concepts and features like options for applications, available methods for enrolling Duo users, and Duo policy settings and how to apply them. See all Duo Administrator documentation.

Then you'll need to:

  1. Sign up for a Duo account.
  2. Log in to the Duo Admin Panel and navigate to ApplicationsProtect an Application.
  3. Locate UNIX Application in the applications list. Click Protect to get your integration key, secret key, and API hostname. You'll need this information to complete your setup. See Protecting Applications for more information about protecting applications in Duo and additional application options.
  4. If you plan to build Duo Unix from source, download the latest version of the duo_unix tarball (view checksum). From the command line you can use curl or wget to download the file, like $ wget --content-disposition https://dl.duosecurity.com/duo_unix-latest.tar.gz.
Treat your secret key like a password

The security of your Duo application is tied to the security of your secret key (skey). Secure it as you would any sensitive credential. Don't share it with unauthorized individuals or email it to anyone under any circumstances!

Build and Install from Source

Install pam_duo Prerequisites

OpenSSL development headers and libraries are required for pam_duo, as well as libpam. When compiling on SUSE/SLES, the zlib package is also necessary.

Dependency Platform Installation
OpenSSL FreeBSD, NetBSD Installed by default
Debian, Ubuntu apt-get install libssl-dev
Red Hat, Fedora, CentOS, Amazon Linux yum install openssl-devel
SUSE/SLES zypper install libopenssl-devel
Solaris pkg install openssl
AIX 3rd party packages or source build
libpam FreeBSD, NetBSD, Solaris, AIX Installed by default
Debian, Ubuntu apt-get install libpam-dev
Red Hat, Fedora, CentOS Linux/Stream, Amazon Linux yum install pam-devel
SUSE/SLES zypper install pam-devel
selinux-policy-devel CentOS Linux 7-8, CentOS Stream 8-9, Red Hat 7-9 (if using SELinux) yum install selinux-policy-devel
bzip2 CentOS Linux 7-8, CentOS Stream 8-9, Red Hat 7-9 yum install bzip2
zlib SUSE/SLES zypper install zlib-devel

You also need a compiler like gcc installed on your system to build Duo Unix.

Install pam_duo

Once the required dependencies are built and installed, build and install duo_unix.

  1. Extract the downloaded tarball for duo_unix and change to the extracted directory (note your actual extracted directory name reflects the actual version downloaded; the example syntax below references version 2.0.4). View checksums for Duo downloads here.

    $ tar zxf duo_unix-latest.tar.gz
     $ cd duo_unix-2.0.4
  2. Build and install duo_unix with PAM support ( pam_duo).

    $ ./configure --with-pam --prefix=/usr && make && sudo make install

    For advanced build options, see the README file in the source tarball.

  3. Once installed, proceed to Duo configuration.

Install from Linux Packages

To more easily install and maintain Duo Unix deployments, we've built Linux packages for some popular Linux distributions. Duo tests these packages against the specific listed versions of their respective distributions.

Please test all packages thoroughly prior to deploying them into your environment to ensure a great experience. Note that we exclusively provide Duo Unix install packages at pkg.duosecurity.com and cannot guarantee packages obtained from other sources.

When installing Duo Unix from packages, there is no need to also install the build-from-source prerequisites on the target systems.

To download the packages, you'll need Duo's GPG key. The GPG key verifies the Duo Unix package for currently supported OS distributions and versions.

We updated the Duo GPG key for packages on supported distros on June 2, 2022. If you installed Duo Unix from packages before June 2022, be sure to update your previously imported GPG key using command for your distro the before the next time you install or upgrade Duo Unix.

The current Duo GPG key expires in May 2032.

OS distributions identified as no longer supported in the distro-specific packages sections use a previous GPG key. We won't replace or update the GPG key on these EOL versions when it expires, and urge you to update to a supported OS.

CentOS Stream

Tested against 9 64-bit

IMPORTANT:

  • CentOS Stream 8 reached end of life on May 31, 2024. Duo Unix 2.0.3 was the last release with CentOS Stream 8 support.

Create /etc/yum.repos.d/duosecurity.repo with the following contents:

[duosecurity]
name=Duo Security Repository
baseurl=https://pkg.duosecurity.com/CentOSStream/$releasever/$basearch
enabled=1
gpgcheck=1

Execute the following shell commands for CentOS Stream 8 and later:

# rpm --import https://duo.com/DUO-GPG-PUBLIC-KEY.asc
# yum install duo_unix

CentOS Linux

Consider migrating to CentOS Stream.

IMPORTANT:

  • CentOS 5 reached end of life on March 31, 2017. Duo Unix 1.10.5 was the last release with CentOS 5 support.

  • CentOS 6 reached end of life on November 30, 2020. Duo Unix 1.11.4 was the last release with CentOS 6 support.

  • CentOS 7 reached end of life on June 30, 2024. Duo Unix 2.0.3 was the last release with CentOS 7 support.

  • CentOS 8 reached end of life on December 31, 2021. Duo Unix 1.12.0 was the last release with CentOS 8 support.

Please review the Duo End of Sale, Last Date of Support, and End of Life Policy.

Create /etc/yum.repos.d/duosecurity.repo with the following contents:

[duosecurity]
name=Duo Security Repository
baseurl=https://pkg.duosecurity.com/CentOS/$releasever/$basearch
enabled=1
gpgcheck=1

Execute the following shell commands for CentOS 7 and later:

# rpm --import https://duo.com/DUO-GPG-PUBLIC-KEY.asc
# yum install duo_unix

Fedora

Tested against Fedora 39 and 40 64-bit

IMPORTANT:

  • Fedora 34 reached end of life on June 7, 2022. Duo Unix 2.0.2 was the last release with Fedora 34 support.

  • Fedora 37 reached end of life on November 14, 2023. Duo Unix 2.0.2 was the last release with Fedora 37 support.

  • Fedora 38 reached end of life on May 31, 2024. Duo Unix 2.0.3 was the last release with Fedora 38 support.

Please review the Duo End of Sale, Last Date of Support, and End of Life Policy.

Create /etc/yum.repos.d/duosecurity.repo with the following contents:

[duosecurity]
name=Duo Security Repository
baseurl=https://pkg.duosecurity.com/Fedora/$releasever/$basearch
enabled=1
gpgcheck=1

Execute the following shell commands for Fedora 34 and later:

# rpm --import https://duo.com/DUO-GPG-PUBLIC-KEY.asc
# yum install duo_unix

Ubuntu

Tested against 24.04 noble 64-bit, 22.04 jammy 64-bit, and 20.04 focal 64-bit

IMPORTANT:

  • Ubuntu 12.04 reached end of life in April 2017. Duo Unix 1.11.3 was the last release with Ubuntu 12.04 support.

  • Ubuntu 14.04 reached end of life in April 2019. Duo Unix 1.12.0 was the last release with Ubuntu 14.04 support.

  • Ubuntu 16.04 reached end of life in April 2021. Duo Unix 1.12.0 was the last release with Ubuntu 16.04 support.

  • Ubuntu 18.04 reached end of life in May 2023. Duo Unix 2.0.1 was the last release with Ubuntu 18.04 support.

Please review the Duo End of Sale, Last Date of Support, and End of Life Policy.

Create /etc/apt/sources.list.d/duosecurity.list with the following contents:

deb [arch=amd64] https://pkg.duosecurity.com/Ubuntu bionic main

or

deb [arch=amd64] https://pkg.duosecurity.com/Ubuntu focal main

or

deb [arch=amd64] https://pkg.duosecurity.com/Ubuntu jammy main

or

deb [arch=amd64] https://pkg.duosecurity.com/Ubuntu noble main

Execute the following shell commands for Ubuntu 18.04 and 20.04:

# curl -s https://duo.com/DUO-GPG-PUBLIC-KEY.asc | sudo apt-key add -
# apt-get update && apt-get install duo-unix

Execute the following shell commands for Ubuntu 22.04 and later:

# curl -s https://duo.com/DUO-GPG-PUBLIC-KEY.asc | sudo gpg --dearmor -o  /etc/apt/trusted.gpg.d/duo.gpg
# apt-get update && apt-get install duo-unix
Warning: Upgrading Ubuntu from 20.04 to 22.04 can break Duo Unix

Upgrading from 20.04 to 22.04 with do-release-upgrade requires use of the --allow-third-party flag. Without this flag do-release-upgrade disables third-party libraries, including those used by Duo Unix. This could prevent logins after upgrading.

Please see the Duo Knowledge Base article How do I upgrade Ubuntu from version 20.04 to 22.04 with Duo Unix installed? for more information, including recovery steps if you have already performed the upgrade without allowing third-party libraries.

Red Hat Enterprise Linux

Tested against 8.0 64-bit and 7.0 64-bit.

IMPORTANT:

  • Red Hat 5 reached full end of life on November 30, 2020. Duo Unix 1.10.5 was the last release with Red Hat 5 support.

  • Red Hat 6 entered extended life on November 30, 2020. Duo Unix 1.11.4 was the last release with Red Hat 6 support.

Please review the Duo End of Sale, Last Date of Support, and End of Life Policy.

Create /etc/yum.repos.d/duosecurity.repo with the following contents:

[duosecurity]
name=Duo Security Repository
baseurl=https://pkg.duosecurity.com/RedHat/$releasever/$basearch
enabled=1
gpgcheck=1

Execute the following shell commands for Red Hat 6 and later:

# rpm --import https://duo.com/DUO-GPG-PUBLIC-KEY.asc
# yum install duo_unix

Debian

Tested against 12.0 32/64-bit and 11.0 32/64-bit.

IMPORTANT:

  • Debian 6 reached end of life on May 31, 2015. Duo Unix 1.9.18 was the last release with Debian 6 support.

  • Debian 7 reached end of life on April 26, 2016. Duo Unix 1.11.1 was the last release with Debian 7 support.

  • Debian 8 reached end of life on June 30, 2020. Duo Unix 1.11.4 was the last release with Debian 8 support.

  • Debian 9 reached end of life on June 30, 2022. Duo Unix 2.0.1 was the last release with Debian 9 support.

  • Debian 10 reached end of life on June 30, 2024. Duo Unix 2.0.3 was the last release with Debian 10 support.

Please review the Duo End of Sale, Last Date of Support, and End of Life Policy.

Create /etc/apt/sources.list.d/duosecurity.list with the following contents:

deb https://pkg.duosecurity.com/Debian stretch main

or

deb https://pkg.duosecurity.com/Debian buster main

or

deb https://pkg.duosecurity.com/Debian bullseye main

or

deb https://pkg.duosecurity.com/Debian bookworm main

Execute the following shell commands for Debian 9 and later:

# curl -s https://duo.com/DUO-GPG-PUBLIC-KEY.asc | sudo apt-key add -
# apt-get update && apt-get install duo-unix

Amazon Linux

Tested against Amazon Linux 2023.

Create /etc/yum.repos.d/duosecurity.repo with the following contents:

[duosecurity]
name=Duo Security Repository
baseurl=https://pkg.duosecurity.com/AmazonLinux/$releasever/$basearch
enabled=1
gpgcheck=1

Execute the following shell commands for Amazon Linux:

# rpm --import https://duo.com/DUO-GPG-PUBLIC-KEY.asc
# yum install duo_unix

Once the Duo Unix package is installed, proceed to Duo configuration.

Duo Configuration

The pam_duo.conf configuration file uses the INI format.

Once duo_unix is installed, edit pam_duo.conf (in /etc/duo or /etc/security) to add the integration key, secret key, and API hostname from your Duo Unix application.

You may also add optional Duo configuration options to pam_duo.conf. See the table below for all available settings.

Example configuration file with additional options:

[duo]
; Duo integration key
ikey = INTEGRATION_KEY
; Duo secret key
skey = SECRET_KEY
; Duo API hostname
host = API_HOSTNAME
pushinfo=yes
autopush=yes

Duo Configuration Options

Key Required? Description
ikey Required Your integration key
skey Required Your secret key
host Required Your API hostname i.e. api-XXXXXXXX.duosecurity.com
groups Optional

If specified, Duo authentication is required only for users whose primary group or supplementary group list matches one of the space-separated pattern lists.

A pattern consists of zero or more non-whitespace characters, "*" (a wild card that matches zero or more characters), or "?" (a wildcard that matches exactly one character).

A pattern-list is a comma-separated list of patterns. A comma-separated list of patterns indicates AND, whereas a space-separated list of patterns indicates OR. Patterns within pattern-lists may be negated by preceding them with an exclamation mark ("!"). For example, to specify Duo authentication for all users (except those that are also admins), and for guests:

groups=staff,!wheel,!*admin guests

failmode Optional

On service or configuration errors that prevent Duo authentication, fail "safe" (allow access) or "secure" (deny access). The default is "safe".

pushinfo Optional

Include information such as the command to be executed in the Duo Push message. Either "yes" or "no". The default is "no".

http_proxy Optional

Use the specified HTTP proxy. If the HTTP proxy requires authentication, include the credentials in the proxy URL. Example format:

http_proxy=http://username:password@proxy.example.org:8080

autopush Optional

Either "yes" or "no". Default is "no".

If "no", the user will be prompted to choose an authentication method.

If "yes", Duo Unix will automatically send a push login request to the user's phone, falling back to a phone call if push is unavailable. Note that this effectively disables SMS, hardware token, or Duo Mobile passcode authentication as there is no opportunity for the user to enter a passcode. If you enable autopush and a user has not enrolled a device capable of automatic push or phone call, or if the effective policy prevents use of Duo Push or phone call authentication, the login attempt will fail with an error.

When configured with autopush = yes, we recommend setting prompts = 1.

motd Optional

Print the contents of /etc/motd to screen after a successful login. Either "yes" or "no". The default is "no".

This option is only available for login_duo.

prompts Optional

If a user fails to authenticate with a second factor, Duo Unix will prompt the user to authenticate again. This option sets the maximum number of prompts that Duo Unix will display before denying access. Must be 1, 2, or 3. Default is 3.

For example, when prompts = 1, the user will have to successfully authenticate on the first prompt, whereas if prompts = 2, if the user enters incorrect information at the initial prompt, he/she will be prompted to authenticate again.

When configured with autopush = yes, we recommend setting prompts = 1.

accept_env_factor Optional

Look for factor selection or passcode in the $DUO_PASSCODE environment variable before prompting the user for input. When $DUO_PASSCODE is non-empty, it will override autopush.

The SSH client will need SendEnv DUO_PASSCODE in its configuration, and the SSH server will similarly need AcceptEnv DUO_PASSCODE.

Default is "no".

This option is only available for login_duo.

fallback_local_ip Optional

Duo Unix reports the IP address of the authorizing user, for the purposes of authorization and network allow/deny. If Duo Unix cannot detect the IP address of the client, setting fallback_local_ip = yes will cause Duo Unix to send the IP address of the server it is running on.

If you are using Authorized Networks, enabling this option could cause unauthorized logins if the local IP is listed in the allow list.

https_timeout Optional

Set to the number of seconds to wait for HTTPS responses from Duo Security. If Duo Security takes longer than the configured number of seconds to respond to the preauth API call, the configured failmode is triggered. Other network operations such as DNS resolution, TCP connection establishment, and the SSL handshake have their own independent timeout and retry logic.

Default is 0, which disables the HTTPS timeout.

If you specify an https_timeout value for Duo Unix, be sure that you do not set a conflicting socket timeout.

send_gecos Optional

Sends the entire GECOS field as the Duo username.

Default is "no"; the GECOS field is not used or parsed.

If you specify gecos_username_pos and gecos_delim, this setting is ignored.

gecos_username_pos Optional

Specify this option to select what position from the GECOS field will be used as the username. Positions are separated by whatever you specify in gecos_delim or the default delimiter, a comma (,).

For example, if the /etc/passwd entry for a user is:

test_user:x:UID:GID:gecos1,gecos2,gecos3:/home/test_user:/bin/bash

Then setting gecos_username_pos=2 sends gecos2 as the Duo username.

If not configured, the GECOS field is not parsed for the username.

Overrides send_gecos, if set.

gecos_delim Optional

Specify this option to change the default value of the GECOS delimiter from a comma to another character. The new delimiter specified must be exactly one character, and must a valid punctuation character other than a colon (:).

For example, if the /etc/passwd entry for a user is:

test_user:x:UID:GID:gecos1/gecos2/gecos3:/home/test_user:/bin/bash

Then setting gecos_username_pos=3 and gecos_delim=/ sends gecos3 as the Duo username.

If not configured, the default comma (,) GECOS field delimiter is used.

For more information, see the man page for pam_duo.

System Configuration

We recommend leaving a root shell open while making any changes to your PAM or sshd configuration, in order to prevent accidentally locking yourself out. Additionally, always make sure your PAM configuration works locally before testing it with SSH logins.

Public Key Authentication

If you would like to use pam_duo with SSH public key authentication, make the following changes to your sshd_config file (usually in /etc or /etc/ssh).

This feature is only available with OpenSSH 6.2+, SSH protocol 2, and Duo Unix 1.9.15 or later.

PubkeyAuthentication yes
PasswordAuthentication no
AuthenticationMethods publickey,keyboard-interactive

PAM Configuration

You'll need to modify your system's PAM configuration to include a line like the following:

auth required pam_duo.so

Depending on your OS or architecture, the pam_duo.so module might be in /lib64/security instead of the default location /lib/security. If so, specify the full path to pam_duo.so in the PAM config file, such as /lib64/security/pam_duo.so.

The location of this line and the specified control flag (e.g. "required", "requisite", "sufficient") varies. For most common configurations, place pam_duo directly after pam_unix (frequently found in common-auth or system-auth on Linux), set pam_unix's control flag to "requisite", and set pam_duo's control flag to whatever pam_unix used to be.

If you want to use pam_duo with your installation of OpenSSH sshd, set both UsePAM and ChallengeResponseAuthentication to yes in your sshd_config file (usually in /etc or /etc/ssh). You should also set UseDNS to no so that PAM Duo is always passed the IP address of the connecting user, rather than the resolved hostname.

UsePAM yes
ChallengeResponseAuthentication yes
UseDNS no

On systems where KbdInteractiveAuthentication is present in sshd_config instead of ChallengeResponseAuthentication (such as Ubuntu 22.04), set that to yes instead:

UsePAM yes
KbdInteractiveAuthentication yes
UseDNS no

If both KbdInteractiveAuthentication and ChallengeResponseAuthentication are present, the first value set in the file takes effect. Set both to yes for consistency if you leave both lines in the file.

Be sure to restart the SSH service after making edits to sshd and sshd_config to apply the updated configuration with Duo.

Additional sshd Configuration for Fedora Derivatives

Additional sshd configuration may be needed when configuring Duo PAM on Fedora and its derivatives such as:

  • Fedora 33 and later
  • RHEL 9
  • CentOS Stream 9
  • Amazon Linux 2022

Edit the /etc/ssh/sshd_config.d/50-redhat.conf and comment out the following directive:

ChallengeResponseAuthentication no

If your SSH sessions are silently rejected from your server after that change, refer to the Duo knowledge base article Why are SSH sessions being denied when using keyboard-interactive authentication with Duo Unix on Fedora 33- and 34-based systems? for more information and additional troubleshooting steps.

PAM Examples

PAM configuration examples for common Linux systems:

Remember that you may need to specify the full path to pam_duo.so in the PAM config file, such as /lib64/security/pam_duo.so if the module is not in the default location /lib/security.

Note: Running authconfig after editing your PAM config files will overwrite your changes. Do not run authconfig once you edit your PAM files to add Duo.

If you must preserve your ability to run authconfig in the future, use the symbolic link method described in the "Keeping Custom Settings with authconfig" topic in section 4.1.2 of the Red Hat Security Guide.

CentOS Stream 9

System-wide Authentication

/etc/pam.d/system-auth

Before:

auth        required      pam_env.so
auth        sufficient    pam_unix.so try_first_pass nullok
auth        required      pam_deny.so

After:

auth        required        pam_env.so
#auth       sufficient      pam_unix.so try_first_pass nullok
auth        requisite       pam_unix.so try_first_pass nullok
auth        sufficient      pam_duo.so
auth        required        pam_deny.so

SSH Public Key Authentication

/etc/pam.d/sshd

Before:

auth       substack     password-auth
auth       include      postlogin

After:

auth       required       pam_sepermit.so
auth       required       pam_env.so
#auth      substack       password-auth
auth       sufficient     pam_duo.so
auth       required       pam_deny.so
auth       include        postlogin
SELinux

If SELinux is blocking pam_duo from contacting Duo's service then it will invoke the your configured failmode (either safe or secure) and not show a Duo prompt.

If you are running SELinux you must install the selinux-policy-devel and policycoreutils-python prerequisite packages and also update your policies to include authlogin_duo (run from the location where you built Duo Unix):

sudo make -C pam_duo semodule
sudo make -C pam_duo semodule-install

This allows sshd to make outgoing HTTP connections, which is required for Duo authentication to complete.

Verify that your SELinux configuration has been updated to include Duo:

$ semodule -l | grep duo

The semodule output should include:

authlogin_duo

There are two adjustable tunables:

pam_duo_permit_local_login allows local logins to use pam_duo (off by default)

pam_duo_permit_sshd allows sshd to use pam_duo (on by default)

To turn on and off the tunables:

sudo setsebool -P pam_duo_permit_sshd on/off
sudo setsebool -P pam_duo_permit_local_login on/off

The -P flag causes the boolean to persist through server restarts.

Note: If the nis_enabled tunable is on then regardless of the value of pam_duo_permit_sshd pam_duo will always be able to access Duo via ssh.

CentOS Stream 8

IMPORTANT: CentOS Stream 8 reached end of life on May 31, 2024. Duo Unix 2.0.3 was the last release with CentOS Stream 8 support. Please review the Duo End of Sale, Last Date of Support, and End of Life Policy.

System-wide Authentication

/etc/pam.d/system-auth

Before:

auth        required      pam_env.so
auth        sufficient    pam_unix.so try_first_pass nullok
auth        required      pam_deny.so

After:

auth        required        pam_env.so
#auth       sufficient      pam_unix.so try_first_pass nullok
auth        requisite       pam_unix.so try_first_pass nullok
auth        sufficient      pam_duo.so
auth        required        pam_deny.so

SSH Public Key Authentication

/etc/pam.d/sshd

Before:

auth       substack     password-auth
auth       include      postlogin

After:

auth       required       pam_sepermit.so
auth       required       pam_env.so
#auth      substack       password-auth
auth       sufficient     pam_duo.so
auth       required       pam_deny.so
auth       include        postlogin
SELinux

If SELinux is blocking pam_duo from contacting Duo's service then it will invoke the your configured failmode (either safe or secure) and not show a Duo prompt.

If you are running SELinux you must install the selinux-policy-devel and policycoreutils-python prerequisite packages and also update your policies to include authlogin_duo (run from the location where you built Duo Unix):

sudo make -C pam_duo semodule
sudo make -C pam_duo semodule-install

This allows sshd to make outgoing HTTP connections, which is required for Duo authentication to complete.

Verify that your SELinux configuration has been updated to include Duo:

$ semodule -l | grep duo

The semodule output should include:

authlogin_duo

There are two adjustable tunables:

pam_duo_permit_local_login allows local logins to use pam_duo (off by default)

pam_duo_permit_sshd allows sshd to use pam_duo (on by default)

To turn on and off the tunables:

sudo setsebool -P pam_duo_permit_sshd on/off
sudo setsebool -P pam_duo_permit_local_login on/off

The -P flag causes the boolean to persist through server restarts.

Note: If the nis_enabled tunable is on then regardless of the value of pam_duo_permit_sshd pam_duo will always be able to access Duo via ssh.

Consider migrating to CentOS Stream.

Note: Running authconfig after editing your PAM config files will overwrite your changes. Do not run authconfig once you edit your PAM files to add Duo.

If you must preserve your ability to run authconfig in the future, use the symbolic link method described in the "Keeping Custom Settings with authconfig" topic in section 4.1.2 of the Red Hat Security Guide.

CentOS 8

IMPORTANT: CentOS 8 reached end of life on December 31, 2021. Duo Unix 1.12.0 was the last release with CentOS 8 support. Please review the Duo End of Sale, Last Date of Support, and End of Life Policy.

System-wide Authentication

/etc/pam.d/system-auth

Before:

auth  required pam_env.so
auth  sufficient pam_unix.so nullok try_first_pass
auth  requisite	pam_succeed_if.so uid >= 500 quiet
auth  required pam_deny.so

After:

auth  required pam_env.so
# 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 >= 500 quiet
auth  required pam_deny.so

SSH Public Key Authentication

/etc/pam.d/sshd

Before:

#%PAM-1.0
auth  required pam_sepermit.so
auth  substack password-auth
auth  include postlogin

After:

#%PAM-1.0
auth  required pam_sepermit.so
#auth  substack password-auth
auth  required pam_env.so
auth  sufficient pam_duo.so
auth  required pam_deny.so
auth  include postlogin
SELinux
If SELinux is blocking pam_duo from contacting Duo's service then it will invoke the your configured failmode (either safe or secure) and not show a Duo prompt.

If you are running SELinux you must install the selinux-policy-devel and policycoreutils-python prerequisite packages and also update your policies to include authlogin_duo (run from the location where you built Duo Unix):

sudo make -C pam_duo semodule
sudo make -C pam_duo semodule-install

This allows sshd to make outgoing HTTP connections, which is required for Duo authentication to complete.

Verify that your SELinux configuration has been updated to include Duo:

$ semodule -l | grep duo

The semodule output should include:

authlogin_duo

There are two adjustable tunables:

pam_duo_permit_local_login allows local logins to use pam_duo (off by default)

pam_duo_permit_sshd allows sshd to use pam_duo (on by default)

To turn on and off the tunables:

sudo setsebool -P pam_duo_permit_sshd on/off
sudo setsebool -P pam_duo_permit_local_login on/off

The -P flag causes the boolean to persist through server restarts.

Note: If the nis_enabled tunable is on then regardless of the value of pam_duo_permit_sshd pam_duo will always be able to access Duo via ssh.

CentOS 7

IMPORTANT: CentOS 7 reached end of life on June 30, 2024. Duo Unix 2.0.3 was the last release with CentOS 7 support. Please review the Duo End of Sale, Last Date of Support, and End of Life Policy.

System-wide Authentication

/etc/pam.d/system-auth

Before:

auth  required pam_env.so
auth  sufficient pam_unix.so nullok try_first_pass
auth  requisite	pam_succeed_if.so uid >= 500 quiet
auth  required pam_deny.so

After:

auth  required pam_env.so
# 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 >= 500 quiet
auth  required pam_deny.so

SSH Public Key Authentication

/etc/pam.d/sshd

Before:

#%PAM-1.0
auth  required pam_sepermit.so
auth  substack password-auth
auth  include postlogin

After:

#%PAM-1.0
auth  required pam_sepermit.so
#auth  substack password-auth
auth  required pam_env.so
auth  sufficient pam_duo.so
auth  required pam_deny.so
auth  include postlogin
SELinux
If SELinux is blocking pam_duo from contacting Duo's service then it will invoke the your configured failmode (either safe or secure) and not show a Duo prompt.

If you are running SELinux you must install the selinux-policy-devel prerequisite package and also update your policies to include authlogin_duo (run from the location where you built Duo Unix):

sudo make -C pam_duo semodule
sudo make -C pam_duo semodule-install

This allows sshd to make outgoing HTTP connections, which is required for Duo authentication to complete.

Verify that your SELinux configuration has been updated to include Duo:

$ semodule -l | grep duo

The semodule output should include (depending on your specific v7 version):

authlogin_duo   2.1.0

or

authlogin_duo

There are two adjustable tunables:

pam_duo_permit_local_login allows local logins to use pam_duo (off by default)

pam_duo_permit_sshd allows sshd to use pam_duo (on by default)

To turn on and off the tunables:

sudo setsebool -P pam_duo_permit_sshd on/off
sudo setsebool -P pam_duo_permit_local_login on/off

The -P flag causes the boolean to persist through server restarts.

Note: If the nis_enabled tunable is on then regardless of the value of pam_duo_permit_sshd pam_duo will always be able to access Duo via ssh.

CentOS 6

IMPORTANT: CentOS 6 reached end of life on November 30, 2020. Duo Unix 1.11.4 was the last release with CentOS 6 support. Please review the Duo End of Sale, Last Date of Support, and End of Life Policy.

CentOS 5

IMPORTANT: CentOS 5 reached end of life on March 31, 2017. Duo Unix 1.10.5 was the last release with CentOS 5 support. Please review the Duo End of Sale, Last Date of Support, and End of Life Policy.

Fedora 40

System-wide Authentication

/etc/pam.d/system-auth

Before:

auth        required      pam_env.so
auth        sufficient    pam_unix.so try_first_pass nullok
auth        required      pam_deny.so

After:

auth        required        pam_env.so
#auth       sufficient      pam_unix.so try_first_pass nullok
auth        requisite       pam_unix.so try_first_pass nullok
auth        sufficient      /lib64/security/pam_duo.so
auth        required        pam_deny.so

SSH Public Key Authentication

/etc/pam.d/sshd

Before:

auth       substack     password-auth
auth       include      postlogin

After:

auth       required       pam_sepermit.so
auth       required       pam_env.so
#auth      substack       password-auth
auth       sufficient     pam_duo.so
auth       required       pam_deny.so
auth       include        postlogin
SELinux

If SELinux is blocking pam_duo from contacting Duo's service then it will invoke the your configured failmode (either safe or secure) and not show a Duo prompt.

If you are running SELinux you must install the selinux-policy-devel and policycoreutils-python prerequisite packages and also update your policies to include authlogin_duo (run from the location where you built Duo Unix):

sudo make -C pam_duo semodule
sudo make -C pam_duo semodule-install

This allows sshd to make outgoing HTTP connections, which is required for Duo authentication to complete.

Verify that your SELinux configuration has been updated to include Duo:

$ semodule -l | grep duo

The semodule output should include:

authlogin_duo

There are two adjustable tunables:

pam_duo_permit_local_login allows local logins to use pam_duo (off by default)

pam_duo_permit_sshd allows sshd to use pam_duo (on by default)

To turn on and off the tunables:

sudo setsebool -P pam_duo_permit_sshd on/off
sudo setsebool -P pam_duo_permit_local_login on/off

The -P flag causes the boolean to persist through server restarts.

Note: If the nis_enabled tunable is on then regardless of the value of pam_duo_permit_sshd pam_duo will always be able to access Duo via ssh.

Fedora 39

System-wide Authentication

/etc/pam.d/system-auth

Before:

auth        required      pam_env.so
auth        sufficient    pam_unix.so try_first_pass nullok
auth        required      pam_deny.so

After:

auth        required        pam_env.so
#auth       sufficient      pam_unix.so try_first_pass nullok
auth        requisite       pam_unix.so try_first_pass nullok
auth        sufficient      /lib64/security/pam_duo.so
auth        required        pam_deny.so

SSH Public Key Authentication

/etc/pam.d/sshd

Before:

auth       substack     password-auth
auth       include      postlogin

After:

auth       required       pam_sepermit.so
auth       required       pam_env.so
#auth      substack       password-auth
auth       sufficient     pam_duo.so
auth       required       pam_deny.so
auth       include        postlogin
SELinux

If SELinux is blocking pam_duo from contacting Duo's service then it will invoke the your configured failmode (either safe or secure) and not show a Duo prompt.

If you are running SELinux you must install the selinux-policy-devel and policycoreutils-python prerequisite packages and also update your policies to include authlogin_duo (run from the location where you built Duo Unix):

sudo make -C pam_duo semodule
sudo make -C pam_duo semodule-install

This allows sshd to make outgoing HTTP connections, which is required for Duo authentication to complete.

Verify that your SELinux configuration has been updated to include Duo:

$ semodule -l | grep duo

The semodule output should include:

authlogin_duo

There are two adjustable tunables:

pam_duo_permit_local_login allows local logins to use pam_duo (off by default)

pam_duo_permit_sshd allows sshd to use pam_duo (on by default)

To turn on and off the tunables:

sudo setsebool -P pam_duo_permit_sshd on/off
sudo setsebool -P pam_duo_permit_local_login on/off

The -P flag causes the boolean to persist through server restarts.

Note: If the nis_enabled tunable is on then regardless of the value of pam_duo_permit_sshd pam_duo will always be able to access Duo via ssh.

Fedora 38

IMPORTANT: Fedora 38 reached end of life on May 31, 2024. Duo Unix 2.0.3 was the last release with Fedora 38 support. Please review the Duo End of Sale, Last Date of Support, and End of Life Policy.

System-wide Authentication

/etc/pam.d/system-auth

Before:

auth        required      pam_env.so
auth        sufficient    pam_unix.so try_first_pass nullok
auth        required      pam_deny.so

After:

auth        required        pam_env.so
#auth       sufficient      pam_unix.so try_first_pass nullok
auth        requisite       pam_unix.so try_first_pass nullok
auth        sufficient      /lib64/security/pam_duo.so
auth        required        pam_deny.so

SSH Public Key Authentication

/etc/pam.d/sshd

Before:

auth       substack     password-auth
auth       include      postlogin

After:

auth       required       pam_sepermit.so
auth       required       pam_env.so
#auth      substack       password-auth
auth       sufficient     pam_duo.so
auth       required       pam_deny.so
auth       include        postlogin
SELinux

If SELinux is blocking pam_duo from contacting Duo's service then it will invoke the your configured failmode (either safe or secure) and not show a Duo prompt.

If you are running SELinux you must install the selinux-policy-devel and policycoreutils-python prerequisite packages and also update your policies to include authlogin_duo (run from the location where you built Duo Unix):

sudo make -C pam_duo semodule
sudo make -C pam_duo semodule-install

This allows sshd to make outgoing HTTP connections, which is required for Duo authentication to complete.

Verify that your SELinux configuration has been updated to include Duo:

$ semodule -l | grep duo

The semodule output should include:

authlogin_duo

There are two adjustable tunables:

pam_duo_permit_local_login allows local logins to use pam_duo (off by default)

pam_duo_permit_sshd allows sshd to use pam_duo (on by default)

To turn on and off the tunables:

sudo setsebool -P pam_duo_permit_sshd on/off
sudo setsebool -P pam_duo_permit_local_login on/off

The -P flag causes the boolean to persist through server restarts.

Note: If the nis_enabled tunable is on then regardless of the value of pam_duo_permit_sshd pam_duo will always be able to access Duo via ssh.

Fedora 37

IMPORTANT: Fedora 37 reached end of life on September 14, 2023. Duo Unix 2.0.2 was the last release with Fedora 37 support. Please review the Duo End of Sale, Last Date of Support, and End of Life Policy.

System-wide Authentication

/etc/pam.d/system-auth

Before:

auth        required      pam_env.so
auth        sufficient    pam_unix.so try_first_pass nullok
auth        required      pam_deny.so

After:

auth        required        pam_env.so
#auth       sufficient      pam_unix.so try_first_pass nullok
auth        requisite       pam_unix.so try_first_pass nullok
auth        sufficient      /lib64/security/pam_duo.so
auth        required        pam_deny.so

SSH Public Key Authentication

/etc/pam.d/sshd

Before:

auth       substack     password-auth
auth       include      postlogin

After:

auth       required       pam_sepermit.so
auth       required       pam_env.so
#auth      substack       password-auth
auth       sufficient     pam_duo.so
auth       required       pam_deny.so
auth       include        postlogin
SELinux

If SELinux is blocking pam_duo from contacting Duo's service then it will invoke the your configured failmode (either safe or secure) and not show a Duo prompt.

If you are running SELinux you must install the selinux-policy-devel and policycoreutils-python prerequisite packages and also update your policies to include authlogin_duo (run from the location where you built Duo Unix):

sudo make -C pam_duo semodule
sudo make -C pam_duo semodule-install

This allows sshd to make outgoing HTTP connections, which is required for Duo authentication to complete.

Verify that your SELinux configuration has been updated to include Duo:

$ semodule -l | grep duo

The semodule output should include:

authlogin_duo

There are two adjustable tunables:

pam_duo_permit_local_login allows local logins to use pam_duo (off by default)

pam_duo_permit_sshd allows sshd to use pam_duo (on by default)

To turn on and off the tunables:

sudo setsebool -P pam_duo_permit_sshd on/off
sudo setsebool -P pam_duo_permit_local_login on/off

The -P flag causes the boolean to persist through server restarts.

Note: If the nis_enabled tunable is on then regardless of the value of pam_duo_permit_sshd pam_duo will always be able to access Duo via ssh.

Fedora 34

IMPORTANT: Fedora 34 reached end of life on June 7, 2022. Duo Unix 2.0.2 was the last release with Fedora 34 support. Please review the Duo End of Sale, Last Date of Support, and End of Life Policy.

System-wide Authentication

/etc/pam.d/system-auth

Before:

auth        required      pam_env.so
auth        sufficient    pam_unix.so try_first_pass nullok
auth        required      pam_deny.so

After:

auth        required        pam_env.so
#auth       sufficient      pam_unix.so try_first_pass nullok
auth        requisite       pam_unix.so try_first_pass nullok
auth        sufficient      /lib64/security/pam_duo.so
auth        required        pam_deny.so

SSH Public Key Authentication

/etc/pam.d/sshd

Before:

auth       substack     password-auth
auth       include      postlogin

After:

auth       required       pam_sepermit.so
auth       required       pam_env.so
#auth      substack       password-auth
auth       sufficient     pam_duo.so
auth       required       pam_deny.so
auth       include        postlogin
SELinux

If SELinux is blocking pam_duo from contacting Duo's service then it will invoke the your configured failmode (either safe or secure) and not show a Duo prompt.

If you are running SELinux you must install the selinux-policy-devel and policycoreutils-python prerequisite packages and also update your policies to include authlogin_duo (run from the location where you built Duo Unix):

sudo make -C pam_duo semodule
sudo make -C pam_duo semodule-install

This allows sshd to make outgoing HTTP connections, which is required for Duo authentication to complete.

Verify that your SELinux configuration has been updated to include Duo:

$ semodule -l | grep duo

The semodule output should include:

authlogin_duo

There are two adjustable tunables:

pam_duo_permit_local_login allows local logins to use pam_duo (off by default)

pam_duo_permit_sshd allows sshd to use pam_duo (on by default)

To turn on and off the tunables:

sudo setsebool -P pam_duo_permit_sshd on/off
sudo setsebool -P pam_duo_permit_local_login on/off

The -P flag causes the boolean to persist through server restarts.

Note: If the nis_enabled tunable is on then regardless of the value of pam_duo_permit_sshd pam_duo will always be able to access Duo via ssh.

Ubuntu 24.04

System-wide Authentication

/etc/pam.d/common-auth

Before:

auth  [success=1 default=ignore]	pam_unix.so nullok_secure
auth  requisite pam_deny.so
auth  required pam_permit.so

After:

# auth  [success=1 default=ignore] pam_unix.so nullok_secure
auth  requisite pam_unix.so nullok_secure
auth  [success=1 default=ignore] pam_duo.so
auth  requisite pam_deny.so
auth  required pam_permit.so

SSH Public Key Authentication

/etc/pam.d/sshd

Before:

@include common-auth

After:

#@include common-auth
auth  [success=1 default=ignore] pam_duo.so
auth  requisite pam_deny.so
auth  required pam_permit.so

Ubuntu 22.04

System-wide Authentication

/etc/pam.d/common-auth

Before:

auth  [success=1 default=ignore]	pam_unix.so nullok_secure
auth  requisite pam_deny.so
auth  required pam_permit.so

After:

# auth  [success=1 default=ignore] pam_unix.so nullok_secure
auth  requisite pam_unix.so nullok_secure
auth  [success=1 default=ignore] pam_duo.so
auth  requisite pam_deny.so
auth  required pam_permit.so

SSH Public Key Authentication

/etc/pam.d/sshd

Before:

@include common-auth

After:

#@include common-auth
auth  [success=1 default=ignore] pam_duo.so
auth  requisite pam_deny.so
auth  required pam_permit.so

Ubuntu 20.04

System-wide Authentication

/etc/pam.d/common-auth

Before:

auth  [success=1 default=ignore]	pam_unix.so nullok_secure
auth  requisite pam_deny.so
auth  required pam_permit.so

After:

# auth  [success=1 default=ignore] pam_unix.so nullok_secure
auth  requisite pam_unix.so nullok_secure
auth  [success=1 default=ignore] pam_duo.so
auth  requisite pam_deny.so
auth  required pam_permit.so

SSH Public Key Authentication

/etc/pam.d/sshd

Before:

@include common-auth

After:

#@include common-auth
auth  [success=1 default=ignore] pam_duo.so
auth  requisite pam_deny.so
auth  required pam_permit.so

Ubuntu 18.04

IMPORTANT: Ubuntu 18.04 reached end of life in May 2023. Duo Unix 2.0.1 is the last release with Ubuntu 18.04 support. Please review the Duo End of Sale, Last Date of Support, and End of Life Policy.

System-wide Authentication

/etc/pam.d/common-auth

Before:

auth  [success=1 default=ignore]	pam_unix.so nullok_secure
auth  requisite pam_deny.so
auth  required pam_permit.so

After:

# auth  [success=1 default=ignore] pam_unix.so nullok_secure
auth  requisite pam_unix.so nullok_secure
auth  [success=1 default=ignore] pam_duo.so
auth  requisite pam_deny.so
auth  required pam_permit.so

SSH Public Key Authentication

/etc/pam.d/sshd

Before:

@include common-auth

After:

#@include common-auth
auth  [success=1 default=ignore] pam_duo.so
auth  requisite pam_deny.so
auth  required pam_permit.so

Ubuntu 16.04

IMPORTANT: Ubuntu 16.04 reached end of life in April 2021. Duo Unix 1.12.0 is the last release with Ubuntu 16.04 support. Please review the Duo End of Sale, Last Date of Support, and End of Life Policy.

System-wide Authentication

/etc/pam.d/common-auth

Before:

auth  [success=1 default=ignore]	pam_unix.so nullok_secure
auth  requisite pam_deny.so
auth  required pam_permit.so

After:

# auth  [success=1 default=ignore] pam_unix.so nullok_secure
auth  requisite pam_unix.so nullok_secure
auth  [success=1 default=ignore] pam_duo.so
auth  requisite pam_deny.so
auth  required pam_permit.so

SSH Public Key Authentication

/etc/pam.d/sshd

Before:

@include common-auth

After:

#@include common-auth
auth  [success=1 default=ignore] pam_duo.so
auth  requisite pam_deny.so
auth  required pam_permit.so

Ubuntu 14.04

IMPORTANT: Ubuntu 14.04 reached end of life in April 2019. Duo Unix 1.12.0 is the last release with Ubuntu 14.04 support. Please review the Duo End of Sale, Last Date of Support, and End of Life Policy.

System-wide Authentication

/etc/pam.d/common-auth

Before:

auth  [success=1 default=ignore]	pam_unix.so nullok_secure
auth  requisite pam_deny.so

After:

# auth  [success=1 default=ignore] pam_unix.so nullok_secure
auth  requisite pam_unix.so nullok_secure
auth  [success=1 default=ignore] pam_duo.so
auth  requisite pam_deny.so

SSH Public Key Authentication

/etc/pam.d/sshd

Before:

@include common-auth

After:

#@include common-auth
auth  [success=1 default=ignore] pam_duo.so
auth  requisite pam_deny.so
auth  required pam_permit.so
auth  optional pam_cap.so

Ubuntu 12.04

IMPORTANT: Ubuntu 12.04 reached end of life in April 2017. Duo Unix 1.11.3 was the last release with Ubuntu 12.04 support. Please review the Duo End of Sale, Last Date of Support, and End of Life Policy.

Red Hat Enterprise Linux

Red Hat Enterprise Linux 9

System-wide Authentication

/etc/pam.d/system-auth

Before:

auth        required      pam_env.so
auth        sufficient    pam_unix.so try_first_pass nullok
auth        required      pam_deny.so

After:

auth        required        pam_env.so
#auth       sufficient      pam_unix.so try_first_pass nullok
auth        requisite       pam_unix.so try_first_pass nullok
auth        sufficient      pam_duo.so
auth        required        pam_deny.so

SSH Public Key Authentication

/etc/pam.d/sshd

Before:

auth       substack     password-auth
auth       include      postlogin

After:

auth       required       pam_sepermit.so
auth       required       pam_env.so
#auth      substack       password-auth
auth       sufficient     pam_duo.so
auth       required       pam_deny.so
auth       include        postlogin
SELinux

If SELinux is blocking pam_duo from contacting Duo's service then it will invoke the your configured failmode (either safe or secure) and not show a Duo prompt.

If you are running SELinux you must install the selinux-policy-devel and policycoreutils-python prerequisite packages and also update your policies to include authlogin_duo (run from the location where you built Duo Unix):

sudo make -C pam_duo semodule
sudo make -C pam_duo semodule-install

This allows sshd to make outgoing HTTP connections, which is required for Duo authentication to complete.

Verify that your SELinux configuration has been updated to include Duo:

$ semodule -l | grep duo

The semodule output should include:

authlogin_duo

There are two adjustable tunables:

pam_duo_permit_local_login allows local logins to use pam_duo (off by default)

pam_duo_permit_sshd allows sshd to use pam_duo (on by default)

To turn on and off the tunables:

sudo setsebool -P pam_duo_permit_sshd on/off
sudo setsebool -P pam_duo_permit_local_login on/off

The -P flag causes the boolean to persist through server restarts.

Note: If the nis_enabled tunable is on then regardless of the value of pam_duo_permit_sshd pam_duo will always be able to access Duo via ssh.

Red Hat Enterprise Linux 8

System-wide Authentication

/etc/pam.d/system-auth

Before:

auth  required pam_env.so
auth  sufficient pam_unix.so nullok try_first_pass
auth  requisite pam_succeed_if.so uid >= 1000 quiet_success
auth  required pam_deny.so

After:

auth  required pam_env.so
# 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

SSH Public Key Authentication

/etc/pam.d/sshd

Before:

#%PAM-1.0
auth  required pam_sepermit.so
auth  substack password-auth
auth  include postlogin

After:

#%PAM-1.0
auth  required pam_sepermit.so
#auth  substack password-auth
auth  required pam_env.so
auth  sufficient pam_duo.so
auth  requisite pam_succeed_if.so uid >= 1000 quiet_success
auth  required pam_deny.so
auth  include postlogin
SELinux

If SELinux is blocking pam_duo from contacting Duo's service then it will invoke the your configured failmode (either safe or secure) and not show a Duo prompt.

If you are running SELinux you must install the selinux-policy-devel prerequisite package and also update your policies to include authlogin_duo (run from the location where you built Duo Unix):

sudo make -C pam_duo semodule
sudo make -C pam_duo semodule-install

This allows sshd to make outgoing HTTP connections, which is required for Duo authentication to complete.

Verify that your SELinux configuration has been updated to include Duo:

$ semodule -l | grep duo

The semodule output should include:

authlogin_duo

There are two adjustable tunables:

pam_duo_permit_local_login allows local logins to use pam_duo (off by default)

pam_duo_permit_sshd allows sshd to use pam_duo (on by default)

To turn on and off the tunables:

sudo setsebool -P pam_duo_permit_sshd on/off
sudo setsebool -P pam_duo_permit_local_login on/off

The -P flag causes the boolean to persist through server restarts.

Note: If the nis_enabled tunable is on then regardless of the value of pam_duo_permit_sshd pam_duo will always be able to access Duo via ssh.

Red Hat Enterprise Linux 7

System-wide Authentication

/etc/pam.d/system-auth

Before:

auth  required pam_env.so
auth  sufficient pam_unix.so nullok try_first_pass
auth  requisite pam_succeed_if.so uid >= 1000 quiet_success
auth  required pam_deny.so

After:

auth  required pam_env.so
# 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

SSH Public Key Authentication

/etc/pam.d/sshd

Before:

#%PAM-1.0
auth  required pam_sepermit.so
auth  substack password-auth
auth  include postlogin

After:

#%PAM-1.0
auth  required pam_sepermit.so
#auth  substack password-auth
auth  required pam_env.so
auth  sufficient pam_duo.so
auth  requisite pam_succeed_if.so uid >= 1000 quiet_success
auth  required pam_deny.so
auth  include postlogin
SELinux

If SELinux is blocking pam_duo from contacting Duo's service then it will invoke the your configured failmode (either safe or secure) and not show a Duo prompt.

If you are running SELinux you must install the selinux-policy-devel prerequisite package and also update your policies to include authlogin_duo (run from the location where you built Duo Unix):

sudo make -C pam_duo semodule
sudo make -C pam_duo semodule-install

This allows sshd to make outgoing HTTP connections, which is required for Duo authentication to complete.

Verify that your SELinux configuration has been updated to include Duo:

$ semodule -l | grep duo

The semodule output should include (depending on your specific v7 version):

authlogin_duo   2.1.0

or

authlogin_duo

There are two adjustable tunables:

pam_duo_permit_local_login allows local logins to use pam_duo (off by default)

pam_duo_permit_sshd allows sshd to use pam_duo (on by default)

To turn on and off the tunables:

sudo setsebool -P pam_duo_permit_sshd on/off
sudo setsebool -P pam_duo_permit_local_login on/off

The -P flag causes the boolean to persist through server restarts.

Note: If the nis_enabled tunable is on then regardless of the value of pam_duo_permit_sshd pam_duo will always be able to access Duo via ssh.

Red Hat Enterprise Linux 6

IMPORTANT: Red Hat 6 entered extended life on November 30, 2020. Duo Unix 1.11.4 was the last release with Red Hat 6 support.

System-wide Authentication

/etc/pam.d/system-auth

Before:

auth  required pam_env.so
auth  sufficient pam_unix.so nullok try_first_pass
auth  requisite pam_succeed_if.so uid >= 1000 quiet_success
auth  required pam_deny.so

After:

auth  required pam_env.so
# 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

SSH Public Key Authentication

/etc/pam.d/sshd

Before:

#%PAM-1.0
auth  required pam_sepermit.so
auth  include password-auth

After:

#%PAM-1.0
auth  required pam_sepermit.so
#auth  include password-auth
auth  required pam_env.so
auth  sufficient pam_duo.so
auth  required pam_deny.so
SELinux
If SELinux is blocking pam_duo from contacting Duo's service then it will invoke the your configured failmode (either safe or secure) and not show a Duo prompt.

If you are running SELinux you must also update your policies to include authlogin_duo (run from the location where you built Duo Unix):

sudo make -C pam_duo semodule
sudo make -C pam_duo semodule-install

This allows sshd to make outgoing HTTP connections, which is required for Duo authentication to complete.

Verify that your SELinux configuration has been updated to include Duo:

$ semodule -l | grep duo

The semodule output should include:

authlogin_duo   2.1.0

pam_duo_permit_local_login is a tunable that allows users to use pam_duo with local logins (off by default).

To turn on or off tunable:

sudo setsebool -P pam_duo_permit_local_login on/off

The -P flag causes the boolean to persist through server restarts.

The tunable pam_duo_permit_sshd has no effect. The default SELinux policy allows sshd to use tcp ports so turning this tunable off will not block pam_duo via ssh.

Red Hat Enterprise Linux 5

IMPORTANT: Red Hat 5 reached full end of life on November 30, 2020. Duo Unix 1.10.5 was the last release with Red Hat 5 support. Please review the Duo End of Sale, Last Date of Support, and End of Life Policy.

Debian 12

System-wide Authentication

/etc/pam.d/common-auth

Before:

auth  [success=1 default=ignore]	pam_unix.so nullok
auth  requisite pam_deny.so
auth  required pam_permit.so

After:

#auth  [success=1 default=ignore] pam_unix.so nullok
auth  requisite pam_unix.so nullok
auth  [success=1 default=ignore] pam_duo.so
auth  requisite pam_deny.so
auth  required pam_permit.so

SSH Public Key Authentication

/etc/pam.d/sshd

Before:

@include common-auth

After:

#@include common-auth
auth  [success=1 default=ignore] pam_duo.so
auth  requisite pam_deny.so
auth  required pam_permit.so

Debian 11

System-wide Authentication

/etc/pam.d/common-auth

Before:

auth  [success=1 default=ignore]	pam_unix.so nullok
auth  requisite pam_deny.so
auth  required pam_permit.so

After:

#auth  [success=1 default=ignore]  pam_unix.so nullok
auth  [success=2 default=ignore]  pam_unix.so nullok
auth  sufficient /lib64/security/pam_duo.so
auth  requisite pam_deny.so
auth  required pam_permit.so

SSH Public Key Authentication

/etc/pam.d/sshd

Before:

@include common-auth

After:

#@include common-auth
auth  [success=1 default=ignore] pam_duo.so
auth  requisite pam_deny.so
auth  required pam_permit.so

Debian 10

IMPORTANT: Debian 10 reached end of life on June 30, 2024. Duo Unix 2.0.3 was the last release with Debian 10 support. Please review the Duo End of Sale, Last Date of Support, and End of Life Policy.

System-wide Authentication

/etc/pam.d/common-auth

Before:

auth  [success=1 default=ignore]	pam_unix.so nullok_secure
auth  requisite pam_deny.so
auth  required pam_permit.so

After:

#auth  [success=1 default=ignore] pam_unix.so nullok_secure
auth  requisite pam_unix.so nullok_secure
auth  [success=1 default=ignore] pam_duo.so
auth  requisite pam_deny.so
auth  required pam_permit.so

SSH Public Key Authentication

/etc/pam.d/sshd

Before:

@include common-auth

After:

#@include common-auth
auth  [success=1 default=ignore] pam_duo.so
auth  requisite pam_deny.so
auth  required pam_permit.so

Debian 9

IMPORTANT: Debian 9 reached end of life on June 30, 2022. Duo Unix 2.0.1 was the last release with Debian 9 support. Please review the Duo End of Sale, Last Date of Support, and End of Life Policy.

System-wide Authentication

/etc/pam.d/common-auth

Before:

auth  [success=1 default=ignore]	pam_unix.so nullok_secure
auth  requisite pam_deny.so
auth  required pam_permit.so

After:

#auth  [success=1 default=ignore] pam_unix.so nullok_secure
auth  requisite pam_unix.so nullok_secure
auth  [success=1 default=ignore] pam_duo.so
auth  requisite pam_deny.so
auth  required pam_permit.so

SSH Public Key Authentication

/etc/pam.d/sshd

Before:

@include common-auth

After:

#@include common-auth
auth  [success=1 default=ignore] pam_duo.so
auth  requisite pam_deny.so
auth  required pam_permit.so

Debian 8

IMPORTANT: Debian 8 reached end of life on June 30, 2020. Duo Unix 1.11.4 was the last release with Debian 8 support. Please review the Duo End of Sale, Last Date of Support, and End of Life Policy.

Debian 7

IMPORTANT: Debian 7 reached end of life on April 26, 2016. Duo Unix 1.11.1 was the last release with Debian 7 support. Please review the Duo End of Sale, Last Date of Support, and End of Life Policy.

Debian 6

IMPORTANT: Debian 6 reached end of life on May 31, 2015. Duo Unix 1.9.18 was the last release with Debian 6 support. Please review the Duo End of Sale, Last Date of Support, and End of Life Policy.

Amazon Linux

Note: Running authconfig after editing your PAM config files will overwrite your changes. Do not run authconfig once you edit your PAM files to add Duo.

If you must preserve your ability to run authconfig in the future, use the symbolic link method described in the "Keeping Custom Settings with authconfig" topic in section 4.1.2 of the Red Hat Security Guide.

System-wide Authentication

/etc/pam.d/system-auth

Before:

auth  required pam_env.so
auth  sufficient pam_unix.so nullok try_first_pass
auth  requisite pam_succeed_if.so uid >= 500 quiet
auth  required pam_deny.so

After:

auth  required pam_env.so
# 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 >= 500 quiet
auth  required pam_deny.so

SSH Public Key Authentication

/etc/pam.d/sshd

Before:

auth  required pam_sepermit.so
auth  substack password-auth

After:

auth  required pam_sepermit.so
# auth  substack password-auth
auth  required pam_duo.so

FreeBSD

System-wide Authentication

/etc/pam.d/system

Before:

# auth
auth            sufficient      pam_opie.so             no_warn no_fake_prompts
auth            requisite       pam_opieaccess.so       no_warn allow_local
# auth           sufficient      pam_krb5.so             no_warn try_first_pass
# auth           sufficient      pam_ssh.so              no_warn try_first_pass
auth            required        pam_unix.so             no_warn try_first_pass nullok

After:

# auth
auth            sufficient      pam_opie.so             no_warn no_fake_prompts
auth            requisite       pam_opieaccess.so       no_warn allow_local
# auth           sufficient      pam_krb5.so             no_warn try_first_pass
# auth           sufficient      pam_ssh.so              no_warn try_first_pass
# auth           required        pam_unix.so             no_warn try_first_pass nullok
auth            requisite       pam_unix.so             no_warn try_first_pass nullok
auth            requisite       pam_duo.so

SSH Public Key Authentication

/etc/pam.d/sshd

Before:

# auth
auth            sufficient      pam_opie.so             no_warn no_fake_prompts
auth            requisite       pam_opieaccess.so       no_warn allow_local
# auth           sufficient      pam_krb5.so             no_warn try_first_pass
# auth           sufficient      pam_ssh.so              no_warn try_first_pass
auth            required        pam_unix.so             no_warn try_first_pass

After:

# auth
auth            sufficient      pam_opie.so             no_warn no_fake_prompts
auth            requisite       pam_opieaccess.so       no_warn allow_local
# auth           sufficient      pam_krb5.so             no_warn try_first_pass
# auth           sufficient      pam_ssh.so              no_warn try_first_pass
# auth           required        pam_unix.so             no_warn try_first_pass
auth            required        pam_duo.so

AIX 7

Edit /etc/security/login.cfg and change this line near the bottom of the file:

auth_type = STD_AUTH

to read:

auth_type = PAM_AUTH

/etc/pam.conf

Before:

# Authentication
#
authexec    auth    required        pam_aix
dtaction    auth    required        pam_aix
dtsession   auth    required        pam_aix
dtlogin     auth    required        pam_aix
ftp         auth    required        pam_aix
imap        auth    required        pam_aix
login       auth    required        pam_aix
rexec       auth    required        pam_aix
rlogin      auth    sufficient      pam_rhosts_auth
rlogin      auth    required        pam_aix
rsh         auth    required        pam_rhosts_auth
snapp       auth    required        pam_aix
su          auth    required        pam_aix
swrole      auth    required        pam_aix
telnet      auth    required        pam_aix
xdm         auth    required        pam_aix
sshd        auth    required        pam_aix
OTHER       auth    required        pam_prohibit

After (protecting both su and ssh with Duo):

# Authentication
#
authexec    auth    required        pam_aix
dtaction    auth    required        pam_aix
dtsession   auth    required        pam_aix
dtlogin     auth    required        pam_aix
ftp         auth    required        pam_aix
imap        auth    required        pam_aix
login       auth    required        pam_aix
rexec       auth    required        pam_aix
rlogin      auth    sufficient      pam_rhosts_auth
rlogin      auth    required        pam_aix
rsh         auth    required        pam_rhosts_auth
snapp       auth    required        pam_aix
su          auth    requisite       pam_aix
su          auth    required        /usr/lib/security/pam_duo.so
swrole      auth    required        pam_aix
telnet      auth    required        pam_aix
xdm         auth    required        pam_aix
sshd        auth    requisite       pam_aix
sshd        auth    required        /usr/lib/security/pam_duo.so
OTHER       auth    required        pam_prohibit

If sshd entries do not already exist in /etc/pam.conf then add them after all the other sections:

sshd    account     required    pam_aix
sshd    password    required    pam_aix
sshd    session     required    pam_aix

See additional advanced authentication and PAM examples in the following Duo Knowledge Base articles:

Test Your Setup

SSH into your system newly configured with pam_duo. If everything is set up correctly and your username doesn't exist in Duo, you'll be given an enrollment link:

Duo Unix Enrollment Prompt

Copy the enrollment link and paste it into a web browser to complete Duo's enrollment process.

After enrolling your authentication device with Duo (or if your test user was already enrolled in Duo) you'll receive the prompt for additional verification.

Duo Unix Authentication Prompt

Choose your authentication method and approve the request using your phone or other device.

Troubleshooting

Need some help? Take a look at the Duo UNIX Frequently Asked Questions (FAQ) page or try searching our Duo UNIX Knowledge Base articles or Community discussions. For further assistance, contact Support.

If you open a support case with Duo, be sure to use the Duo Unix Support Tool to create a tarball you can send to the support engineer to aid with troubleshooting.

Network Diagram

Unix Network Diagram
  1. SSH connection initiated
  2. Primary authentication
  3. Duo Unix connection established to Duo Security over TCP port 443
  4. Secondary authentication via Duo Security’s service
  5. Duo Unix receives authentication response
  6. SSH session logged in