Setting up sudo for users with only certain delegated privileges
A basic tenet of IT security philosophy is to give network users enough privileges so that they can get their jobs done, but no privileges beyond that. So, you'll want as few people as possible to have full sudo privileges. (If you have the root user account enabled, you'll want even fewer people to know the root password.) You'll also want a way to delegate privileges to people according to what their specific jobs are. Backup admins will need to be able to perform backup tasks, help desk personnel will need to perform user management tasks, and so on. With sudo, you can delegate these privileges and disallow users from doing any other administrative jobs that don't fit their job description.
The best way to explain this is to have you open visudo on your CentOS virtual machine. So, go ahead and start the CentOS VM and enter the following command:
sudo visudo
Unlike Ubuntu, CentOS has a fully commented and well-documented sudoers file. I've already shown you the line that creates the ADMIN user alias, and you can create other user aliases for other purposes. You can, for example, create a BACKUPADMINS user alias for backup administrators, a WEBADMINS user alias for web server administrators, or whatever else you desire. So, you could add a line that looks something like this:
User_Alias SOFTWAREADMINS = vicky, cleopatra
That's good, except that Vicky and Cleopatra still can't do anything. You'll need to assign some duties to the user alias.
If you look at the example user alias mentioned later, you'll see a list of example Command Aliases. One of these examples just happens to be SOFTWARE, which contains the commands that an admin would need to either install or remove software or to update the system. It's commented out, as are all of the other example command aliases, so you'll need to remove the hash symbol from the beginning of the line before you can use it:
Cmnd_Alias SOFTWARE = /bin/rpm, /usr/bin/up2date, /usr/bin/yum
Now, it's just a simple matter of assigning the SOFTWARE command alias to the SOFTWAREADMINS user alias:
SOFTWAREADMINS ALL=(ALL) SOFTWARE
Vicky and Cleopatra, both members of the SOFTWAREADMINS user alias, can now run the rpm, up2date, and yum commands with root privileges.
All but one of these predefined command aliases are ready to use after you uncomment them and assign them to either a user, group, or user alias. The one exception is the SERVICES command alias:
Cmnd_Alias SERVICES = /sbin/service, /sbin/chkconfig, /usr/bin/systemctl start, /usr/bin/systemctl stop, /usr/bin/systemctl reload, /usr/bin/systemctl restart, /usr/bin/systemctl status, /usr/bin/systemctl enable, /usr/bin/systemctl disable
The problem with this SERVICES alias is that it also lists the different subcommands for the systemctl command. The way sudo works is that if a command is listed by itself, then the assigned user can use that command with any subcommands, options, or arguments. So, in the SOFTWARE example, members of the SOFTWARE user alias can run a command such as:
sudo yum upgrade
But, when a command is listed in the command alias with a subcommand, option, or argument, that's all anyone who's assigned to the command alias can run. With the SERVICES command alias in its current configuration, the systemctl commands just won't work. To see why, let's set Charlie and Lionel up in the SERVICESADMINS user alias and then uncomment the SERVICES command alias, as we've already done earlier:
User_Alias SERVICESADMINS = charlie, lionel
SERVICESADMINS ALL=(ALL) SERVICES
Now, watch what happens when Lionel tries to check the status of the Secure Shell service:
[lionel@centos-7 ~]$ sudo systemctl status sshd
[sudo] password for lionel:
Sorry, user lionel is not allowed to execute '/bin/systemctl status sshd' as root on centos-7.xyzwidgets.com.
[lionel@centos-7 ~]$
Okay, so Lionel can run sudo systemctl status, which is pretty much useless, but he can't do anything meaningful, like specifying the service that he wants to check. That's a bit of a problem. There are two ways to fix this, but there's only one way that you want to use. You could just eliminate all of the systemctl subcommands and make the SERVICES alias look like this:
Cmnd_Alias SERVICES = /sbin/service, /sbin/chkconfig, /usr/bin/systemctl
But, if you do that, Lionel and Charlie will also be able to shut down or reboot the system, edit the services files, or change the machine from one systemd target to another. That's probably not what you want. Because the systemctl command covers a lot of different functions, you have to be careful not to allow delegated users to access too many of those functions. A better solution would be to add a wildcard to each of the systemctl subcommands:
Cmnd_Alias SERVICES = /sbin/service, /sbin/chkconfig, /usr/bin/systemctl start *, /usr/bin/systemctl stop *, /usr/bin/systemctl reload *, /usr/bin/systemctl restart *, /usr/bin/systemctl status *, /usr/bin/systemctl enable *, /usr/bin/systemctl disable *
Now, Lionel and Charlie can perform any of the systemctl functions that are listed in this command alias, for any service:
[lionel@centos-7 ~]$ sudo systemctl status sshd
[sudo] password for lionel:
● sshd.service - OpenSSH server daemon
Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; vendor preset: enabled)
Active: active (running) since Sat 2017-09-30 18:11:22 EDT; 23min ago
Docs: man:sshd(8)
man:sshd_config(5)
Main PID: 13567 (sshd)
CGroup: /system.slice/sshd.service
└─13567 /usr/sbin/sshd -D
Sep 30 18:11:22 centos-7.xyzwidgets.com systemd[1]: Starting OpenSSH server daemon...
Sep 30 18:11:22 centos-7.xyzwidgets.com sshd[13567]: Server listening on 0.0.0.0 port 22.
Sep 30 18:11:22 centos-7.xyzwidgets.com sshd[13567]: Server listening on :: port 22.
Sep 30 18:11:22 centos-7.xyzwidgets.com systemd[1]: Started OpenSSH server daemon.
[lionel@centos-7 ~]$
Keep in mind that you're not limited to using user aliases and command aliases. You can also assign privileges to either a Linux group or to an inpidual user. You can also assign inpidual commands to a user alias, Linux group, or inpidual user. For example:
katelyn ALL=(ALL) STORAGE
gunther ALL=(ALL) /sbin/fdisk -l
%backup_admins ALL=(ALL) BACKUP
Katelyn can now do all of the commands in the STORAGE command alias, whereas Gunther can only use fdisk to look at the partition tables. The members of the backup_admins Linux group can do commands in the BACKUP command alias.
The last thing we'll look at for this topic is the host aliases examples that you see preceding the user alias example:
# Host_Alias FILESERVERS = fs1, fs2
# Host_Alias MAILSERVERS = smtp, smtp2
Each host alias consists of a list of server hostnames. This is what allows you to create one sudoers file on one machine, and deploy it across the network. For example, you could create a WEBSERVERS host alias, a WEBADMINS user alias, and a WEBCOMMANDS command alias with the appropriate commands.
Your configuration would look something like this:
Host_Alias WEBSERVERS = webserver1, webserver2
User_Alias WEBADMINS = junior, kayla
Cmnd_Alias WEBCOMMANDS = /usr/bin/systemctl status httpd, /usr/bin/systemctl start httpd, /usr/bin/systemctl stop httpd, /usr/bin/systemctl restart httpd
WEBADMINS WEBSERVERS=(ALL) WEBCOMMANDS
Now, when a user types a command into a server on the network, sudo will first look at the hostname of that server. If the user is authorized to perform that command on that server, then sudo allows it. Otherwise, sudo denies it. In a small to medium-sized business, it would probably work just fine to manually copy the master sudoers file to all the servers on the network. But, in a large enterprise, you'll want to streamline and automate the process. For this, you could use something like Puppet, Chef, or Ansible. (These three technologies are beyond the scope of this book, but you'll find plenty of books and video courses about all three of them at the Packt website.)
All of these techniques will work on your Ubuntu VM as well as on the CentOS VM. The only catch is, Ubuntu doesn't come with any predefined command aliases, so you'll have to type them in yourself.
Anyway, I know that you're tired of reading, so let's do some work.