How to store sudoers in AD on RHEL 8 with sudoRoles

Ditch complex sudoers files in favour of a simpler and more powerful approach using AD and sssd

Part 1: Linux configuration

You need the OS to know to go to sss to get sudoers info. Make sure nsswitch.conf has the below line:

sudoers: files sss
passwd:     files sss systemd
group:      files sss systemd
netgroup:   sss files
automount:  sss files
services:   sss files
/etc/nsswitch.conf

Now, sssd needs to be enabled for sudo. Specify this in the services key under [sssd], in sssd.conf:

[sssd]
domains = core.example.net
config_file_version = 2
services = nss, pam, sudo

[domain/core.example.net]
ad_domain = core.example.net
krb5_realm = CORE.EXAMPLE.NET
realmd_tags = manages-system joined-with-adcli
cache_credentials = True
id_provider = ad
krb5_store_password_if_offline = True
default_shell = /bin/bash
ldap_id_mapping = True
use_fully_qualified_names = False
fallback_homedir = /home/%u@%d
access_provider = ad
/etc/sssd/sssd.conf

Obviously you need to be joined to the domain: realm join -U <domain admin username> ad.example.net. Above, I also want su <username> to work, so on line 15 I disable fully qualified names. Check things are good, for example id <username> should return all of <username>‘s groups.

Part 2: Active Directory configuration

ldifde -i -f schema.ActiveDirectory -c dc=X dc=CORE,dc=EXAMPLE,dc=NET

In dsa (Active Directory Users and Computers), make an OU for storing sudo roles:

Part 3: making your first sudoRole

Go to adsiedit into the Default naming context, and make a new sudoRole object in the OU you just made:

Call your rule something, e.g. helpdesk-sre which would be for SREs to do things like reboot servers, strace any process, etc.

You can skip More Attributes and close out ADSI Edit, and head back to AD Users and Computers.

Back in AD Users and Computers, turn on Advanced Features (under View)

Right click the helpdesk-sre sudoRole.

Head to Attribute Editor. You’re now presented with a bunch of sudo options you can set. Most should be self-explanatory.

  • sudoHost: ALL just means all hosts. You can specify groups or individual hostnames like in a sudoers file
  • sudoUser has abc which is my main user account
  • sudoCommand is a list of commands I’m allowed to run as root
  • sudoOption !authenticate basically means NOPASSWD

Part 4: test it

sudo -l will show you what you can do:

User abc may run the following commands on kube2-lon:
    (root) NOPASSWD: /usr/bin/strace, /opt/puppetlabs/bin/puppet, /usr/sbin/reboot, /usr/bin/yum, /usr/bin/journalctl, /usr/bin/systemctl
[abc@kube2-lon]/root%

and of course, let’s test using our sudo rights for journalctl by trying to view auditd logs, which is a sensitive thing. The left hand side shows running the command without sudo, whilst the right with sudo.

Part 5: warning on sudo jailbreaks

Be very careful which commands you grant access to. With my new strace rights, if I was a malicious ops agent, I could write a shell script and sudo strace myscript.sh to run that whole script as root. Anything that opens a shell or runs a command is a risk:

  • strace
  • watch
  • xargs
  • vim
  • any shell (sh, bash, zsh, …)