Sudoers policy

Summary of policy

  1. Full sudo access will not be granted.
  2. Sudo su (switch user) access will be granted to service accounts upon request.
  3. Sudo access to specific commands run as specific users is granted upon request.
  4. Sudo chmod is unnecessary because the owning user can already chmod files.
  5. Sudo chown will be granted when applied to specific directories.

Annotated policy

  1. Full sudo access will not be granted, with exceptions granted only by the Linux Engineering team.
    1. Full sudo is what is assumed when users ask for “sudo access” without any qualifiers. Users may not mean this; they might mean sudo su $SHAREDACCOUNT but this cannot be assumed. Requests should be explicit as to what user they should run as, and what commands to run.
    2. Exceptions will be granted for development/sandbox environments as approved by the Linux Engineering team.
  2. Sudo su (switch user) access will be granted to service accounts as requested through PARs and approved by the Linux Engineering team.
    1. Normal access to servers is through individual user accounts, who then switch user to a shared account to manage files and services. Some teams connect directly as a shared account which is not recommended but outside the scope of this policy.
    2. Usage of sudo to switch user, when using rules like the example below, include these commands:
      sudo su - apache
      sudo su apache
      sudo -i apache
      sudo -su apache
      
  3. Sudo access to specific commands run as specific users is granted as requested through PARs and approved by the Linux Engineering team.
    1. Perhaps not shells are needed, but just specific commands run as a different user. Switching users to an interactive shell is normal activity.
  4. Sudo chmod is unnecessary because the owning user can already chmod files.
    1. A user should not run chmod against files that are not his because this is an unacceptable escalation of privilege.
  5. Sudo chown will be granted when applied to specific directories.
    1. If sudo chown * were to be granted, the user could take over system files and is not permissible.
    2. Permissible options involve a specific directory name, with the recursive flag.
[appdeployer ~]$ sudo chown -R appdeployer.appdeployer /opt/appdeployer/v5

The entry in sudoers:

appdeployer hostname = (root) /bin/chown -R appdeployer.appdeployer /opt/appdeployer/v5, /usr/bin/chown -R appdeployer.appdeployer /opt/appdeployer/v5

Definitions

Term Meaning
Full sudo sudo su root or any other command that uses sudo to achieve a root shell
PAR Permission access request ticket

Example sudoers

DB example

This is an example sudoers file.

# file: /etc/sudoers.d/30_db_dbas_sudo
# managed by ansible
# last updated 2018-12-10 20:11Z

User_Alias DBUSERS = %db_dbas, !db
Host_Alias DBHOSTS = l*dbr*, l*dbr*.ad.example.com, l*dbr*.ipa.example.com
Host_Alias DBHOSTS_DEV = l2*dbr*, l2*dbr*.ad.example.com, l2*dbr*.ipa.example.com
Cmnd_Alias BECOME_CMNDS = /bin/su - db, /bin/su db
Cmnd_Alias DBCMNDS = /bin/ls, /bin/ps
Cmnd_Alias DBCMNDS_DEV = ALL

# Users may switch to shared local user
Defaults:DBUSERS !authenticate
DBUSERS DBHOSTS = (root) BECOME_CMNDS
DBUSERS DBHOSTS = (db) ALL

# Local user may run these commands
Defaults: db !authenticate
db DBHOSTS = (root) DBCMNDS
db DBHOSTS_DEV = (root) DBCMNDS_DEV

Webstats example

Another example

# file: /etc/sudoers.d/60_webstats
# managed by ansible
# last updated 2019-01-29T13:12Z
User_Alias WEBSTATSUSERS = %webstats_linux@EXAMPLE.COM
Host_Alias WEBSTATSHOSTS = webstats1*,webstats1*.example.com
Cmnd_Alias WEBSTATSCMNDS = /bin/su - htdocs, /bin/su htdocs, /usr/bin/top *
 
Cmnd_Alias NGINX_CMNDS = /bin/systemctl start nginx.service, /bin/systemctl restart nginx.service, /bin/systemctl stop nginx.service, /bin/systemctl reload nginx.service, /bin/systemctl status nginx.service, /bin/systemctl enable nginx.service, /bin/systemctl disable nginx.service, /bin/systemctl start nginx, /bin/systemctl restart nginx, /bin/systemctl stop nginx, /bin/systemctl reload nginx, /bin/systemctl status nginx, /bin/systemctl enable nginx, /bin/systemctl disable nginx
Cmnd_Alias PHP_CMNDS = /bin/systemctl start php56-php-fpm.service, /bin/systemctl stop php56-php-fpm.service, /bin/systemctl restart php56-php-fpm.service, /bin/systemctl status php56-php-fpm.service, /bin/systemctl enable php56-php-fpm.service, /bin/systemctl disable php56-php-fpm.service, /bin/systemctl start php56-php-fpm, /bin/systemctl stop php56-php-fpm, /bin/systemctl restart php56-php-fpm, /bin/systemctl reload php56-php-fpm, /bin/systemctl status php56-php-fpm, /bin/systemctl enable php56-php-fpm, /bin/systemctl disable php56-php-fpm
Cmnd_Alias EXTRA_CMNDS = /usr/bin/top *, /usr/local/bin/wsprodapp-permissions.sh, /bin/systemctl daemon-reload, /usr/bin/chown -R htdocs.htdocs /mnt/wsprodapp, /usr/bin/chmod -R u+rwX\,g+rwX /mnt/wsprodapp
Cmnd_Alias HTDOCSCMNDS = NGINX_CMNDS, PHP_CMNDS, EXTRA_CMNDS
 
# Users may switch to htdocs
WEBSTATSUSERS WEBSTATSHOSTS = (root) WEBSTATSCMNDS
WEBSTATSUSERS WEBSTATSHOSTS = (htdocs) ALL
 
# htdocs may run these commands
Defaults:htdocs !authenticate
htdocs WEBSTATSHOSTS = (root) HTDOCSCMNDS
User_Alias KUBUSERS = %container_sudoers@AD.EXAMPLE.COM, %containers
Runas_Alias KUBRUNAS = root, containers
Host_Alias KUBHOSTS = k8s*,k8s*.example.com
Cmnd_Alias KUBCMNDS = /usr/bin/docker *, /bin/systemctl start docker.service, /bin/systemctl start docker, /bin/systemctl stop docker.service, /bin/systemctl stop docker, /bin/systemctl restart docker.service, /bin/systemctl restart docker, /bin/systemctl reload docker.service, /bin/systemctl reload docker, /bin/systemctl enable docker.service, /bin/systemctl enable docker, /bin/systemctl disable docker.service, /bin/systemctl disable docker, /bin/systemctl status docker.service, /bin/systemctl status docker, /bin/systemctl daemon-reload, /bin/su containers, /bin/su - containers
KUBUSERS KUBHOSTS=(KUBRUNAS) NOPASSWD: KUBCMNDS

Full sudo

If the Linux Engineering team grants full sudo access, it can be done in this way.

# FS_RUNDECK_USERS is for Full Sudoers
User_Alias FS_RUNDECK_USERS = %appgroup1, %appgroup2
Host_Alias FS_RUNDECK_HOSTS = rundeck*, rundeck*.example.com
Cmnd_Alias FS_RUNDECK_CMNDS = /bin/su, /bin/su - root, /bin/su -
Runas_Alias FS_RUNDECK_RUNAS = root
 
FS_RUNDECK_USERS FS_RUNDECK_HOSTS = (root) FS_RUNDECK_CMNDS
FS_RUNDECK_USERS FS_RUNDECK_HOSTS = (FS_RUNDECK_RUNAS) ALL

Guidelines for sudoers.d/ filenames

Best practice for sudoers.d/ files is to have them sorted numerically.

The company uses number ranges between 00 and 99.

10_low_level_sudo
20_linux_admins_sudo
60_application_group_sudo

Audit sudo docker usage

tl;dr

grep -E "sudo:.*docker.*exec.*" /var/log/secure | grep -vE -- "(-u|--user)"
grep -E "sudo:.*docker.*exec.*" /var/log/secure | grep -E -- '(-u|--user)\s*root'

Explanation

One way to secure docker is to allow users to run it with sudo. Alternatively, you can add users to a group named “docker,” but this doesn’t provide the auditing that sudo has by default.

So you can whip up a nice, neat little sudoers.d file similar to:

User_Alias CONT_POC_USERS = %container_sudoers@ADDOMAIN
Runas_Alias CONT_POC_RUNAS = root
Host_Alias CONT_POC_HOSTS = cn-node-5*, cn-node-5*.example.com
Cmnd_Alias CONT_POC_CMNDS = /usr/bin/docker *
CONT_POC_USERS CONT_POC_HOSTS=(CONT_POC_RUNAS) CONT_POC_CMNDS

With a security posture where you will not allow anything to run in a container as root, you can audit compliance with a few regular expressions.

grep -E "sudo:.*docker.*exec.*" /var/log/secure | grep -vE -- "(-u|--user)"
grep -E "sudo:.*docker.*exec.*" /var/log/secure | grep -E -- '(-u|--user)\s*root'

I haven’t figured out how to have the negative and positive searches in one string, so any input there would be appreciated!

Also, I have not figured out how to actually enforce running the docker exec command only with a -u username flag, without writing a much more complicated whitelist of docker build *, docker commit *, docker container *, docker cp * et al statements which seems like a lot of work but might ultimately be necessary.

sudoers Match AD group

Using AD groups in sudoers

When you need to add an Active Directory group to the sudoers, you need to know a few things.
I learned from the sudoers man page that alias names can only be in capital letters, numbers, and underscores.
Also, when you use an AD group in a sudoers file (in my case, /etc/sudoers.d/70_web-dev_grp), you prepend the group name with a percent sign.

Also, I’m pretty sure you need to have the casing of the group name exactly correct, but I haven’t tested other casings and don’t plan to. If you know anything about this, comment and let me know!

User_Alias WEBDEVGRP = %Web-dev_grp
WEBDEVGRP ALL=(ALL) /sbin/apachectl

Reference

http://serverfault.com/questions/436037/sudoers-file-allow-sudo-on-specific-file-for-active-directory-group/444875#444875

Solve sudo sending useless emails “problem with defaults entries”

sudo problem with defaults entries

I ran into a problem on my Ubuntu 16.04 Server LTS instance.

Whenever a user (whether sssd-ad authenticated user, or local user, or root) uses sudo, it works. But it also sends the administrator a useless email:

host1.example.com : Jun  6 14:40:44 : root : problem with defaults entries ; TTY=pts/2 ; PWD=/root ;

I started removing the defaults entries in /etc/sudoers (using the visudo) command one by one, but after removing them all it still sent the annoying emails. Here are the defaults I was working from:

Defaults        env_reset
Defaults        mail_badpass
Defaults        secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

How do I make sudo stop sending me useless emails?

This problem is caused by sudo looking for directives in a place it cannot find them: sss.
Check the /etc/nsswitch.conf file and modify the sudoers entry.

sudoers:        files sss

The sss should not be there. The sssd-ad package adds itself there, but very few environments store sudoers directives in sss. It’s far more likely your directives are local, so you should have a /etc/nsswitch file entry like the following:

sudoers:        files

References

A user of RHEL6 had the same issue. https://bugzilla.redhat.com/show_bug.cgi?id=879633
The issue is solvable, including on Ubuntu 16.04 https://bugs.launchpad.net/ubuntu/+source/sssd/+bug/1249777