Maintenance: GitLab GKE platform upgrade and software upgrade on Friday Oct. 22 at 9 p.m. Service may not be available between 9 p.m. and 9:20 p.m.

Commit d7ff5a35 authored by Karl Kornel's avatar Karl Kornel
Browse files

sudo: Update from Karl’s dev work

parent 07405157
This README file explains how to use base::sudo.
base::sudo can be used to enable and configure sudo for a system, with or
without Duo.
base::sudo is a parameterized class. If you include or require it without any
parameters, the only thing that happens is, the sudo package is installed. On
Debian systems, that means anyone in the local "sudo" group has sudo access. On
RHEL-family systems, that means anyone in the local "wheel" group has sudo
access. To set the sudo timeout (which defaults to 30 minutes), set the
$timeout parameter.
WARNING: Without any parameters, this configuration means that, when you use
sudo, you will be sending your password over the wire, and it will sit in
memory on that remote system (which may be swapped to disk).
base::sudo also supports using Duo two-factor as the authentication method,
instead of password. To enable this, set the "duo" parameter to true, and set
the "duo_sudoers" parameter to the list of people who will have this sudo
TIP: If you have a base::user class that defines your list of root users, you
could simply pass that list into base::sudo.
WARNING: To be clear, setting the "duo" parameter to true will completely
disable password-based authentication for sudo!
There are two additional Duo-related parameters that you should look at:
duo_fail_secure: If you set this to true, and the Duo service is
unavailable or blocked, the sudo will fail. Normally, the sudo would succeed.
This parameter does not apply if the Duo service is working: If you fail to
answer a Duo call/push, or you deny the Duo call/push, then your sudo would
still fail.
duo_gecos: If your local username on a system matches your username in Duo,
then set this to false. The default is to take your Duo username from the
GECOS field of the passwd file (Puppet calls this field the "comment" field).
......@@ -3,7 +3,17 @@
# $duo: enable pam_duo for sudo. Defaults to false.
# $duo_sudoers: A list of users that are allowed to call sudo.
# Defaults to the empty array.
# Defaults to the empty array. Only used when $duo is set to true.
# $duo_fail_secure: A boolean, normally false. If set to false, a Duo
# timeout will cause the Duo step to be skipped. If set to true, a Duo timeout
# will cause the Duo step to fail (which means sudo will be blocked). Only
# used when $duo is set to true.
# $duo_gecos: A boolean, normally true. If false, then Duo will will use the
# user's username. If true, then Duo will use the contents of the user's GECOS
# field as their username. This is important if you are using an alternate
# account.
# $timeout: how long (in minutes) between requiring a new Duo re-auth.
# Default: 30
......@@ -37,35 +47,85 @@
class base::sudo(
$duo = false,
$duo_sudoers = [],
$duo_fail_secure = false,
$duo_gecos = true,
$timeout = 30,
$debuild = false,
# Install the sudo package
package { 'sudo':
ensure => installed
# If duo is enabled, require base::duo and set up the
# sudoers file.
# Configure a default timeout
file_line { 'Set sudo timeout':
ensure => present,
path => '/etc/sudoers',
line => "Defaults timestamp_timeout = $timeout",
match => '^Defaults\ +timestamp_timeout',
# If duo is enabled, require base::duo and set up the sudoers file.
if ($duo) {
include base::duo
# Validate $duo_fail_secure and $duo_gecos
# base::duo::config does this too, but by doing it here it is clearer to
# clients where the problem is!
if !is_bool($duo_fail_secure) {
fail('base::sudo::duo_fail_secure must be true or false')
if !is_bool($duo_gecos) {
fail('base::sudo::duo_gecos must be true or false')
# Install the Duo config, passing the GECOS and fail-secure settings through
base::duo::config { '/etc/security/pam_duo_su.conf':
ensure => present,
use_gecos => $duo_gecos,
fail_secure => $duo_fail_secure,
# Install the pam.d configuration that requires Duo on sudo.
file {'/etc/pam.d/sudo':
ensure => present,
content => template('base/sudo/etc/pam.d/sudo.erb'),
require => Class['base::duo'],
require => Package['sudo'],
# Make sure that the sudoers.d directory exists, and is read
# This is done on alot of OSes already, but not all.
file { '/etc/sudoers.d':
ensure => directory,
owner => 'root',
group => 'root',
mode => '0750',
require => Package['sudo'],
file_line { 'Add sudoers.d includedir':
ensure => present,
path => '/etc/sudoers',
line => "#includedir /etc/sudoers.d",
require => File['/etc/sudoers.d'],
# Install the suoders file. This takes the array $duo_sudoers
# and puts it into /etc/sudoers.d/duo
if (downcase($::osfamily) =~ /^debian$/) {
file {'/etc/sudoers.d/duo':
ensure => present,
content => template('base/sudo/etc/sudoers.d/duo.erb'),
require => Package['sudo'],
require => File_line['Add sudoers.d includedir']
# If we're not using Duo, we still might need to update the sudoers file
else {
# Debian's config is fine, but we need to enable wheel in RHEL systems
if $::osfamily == 'RedHat' {
file_line { 'Enable wheel sudoers':
ensure => present,
path => '/etc/sudoers',
line => '%wheel ALL=(ALL) ALL',
match => '# %wheel ALL=(ALL) ALL',
} else {
fail("base::sudo with duo does not yet support ${::osfamily}.")
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment