How to install sudo 1.9 and use the new policy tool

The sudo system is about to undergo some radical changes. Find out how to begin working with the new policy system, to make sudo even more powerful.

linuxadminhero.jpg

Image: Jack Wallen

The sudo system on Linux is an incredible way of controlling who can take on admin tasks and this tool has worked well for a very long time. However, as is, sudo has suffered under the weight of much criticism. One of the biggest issues is granular control. For example, if you give a user the right to use sudo on a system, they can always issue the command:

sudo rm -rf /

The above command will delete everything on your system. Every. Thing.

I've run this command on systems just to see what happens and it's a remarkable thing to behold--watching everything vanish on a computer.

Of course, in modern Linux distributions, running the above command will result in a warning, indicating the command is dangerous to operate recursively on /. However, it also instructs you how to get around the failsafe, by using the --no-preserve-root option.

So even with the warning, sudo will allow the wholesale destruction of a machine.

Until sudo 1.9.

With sudo 1.9, the system receives a number of improvements. One such improvement is the just in time command approval, which enables third-party plugins to help improve the security, by way of policies.

I want to demonstrate how to use the new policy system, which makes it pretty easy to control what commands users can run with sudo.

SEE: Security Awareness and Training policy (TechRepublic Premium)

What you'll need

I'll be demonstrating this on Ubuntu 18.04. At the moment, sudo 1.9 can install in Ubuntu 20.04, but the plugin system doesn't work. Because of that, we'll be sticking with the previous LTS release. 

Sudo 1.9 is installable on other distributions, but the only one I've tested this on is Ubuntu 18.04.

How to install sudo 1.9

The first thing you must do is install sudo 1.9. However, before you do that, I highly recommend you make sure you have access to the root account. If you don't do this, you could wind up with a broken sudo system. Chances are, you'll be doing this on a test environment, so giving the root user a password on Ubuntu should be okay. To do this, open a terminal window and issue the command:

sudo passwd root

You'll be prompted to enter and verify the new password.

Now, back at the terminal window, download the necessary .deb files with the following commands:

wget https://www.sudo.ws/sudo/dist/packages/1.9.0/sudo_1.9.0-1_ubu1804_amd64.deb
wget https://www.sudo.ws/sudo/dist/packages/1.9.0/sudo-ldap_1.9.0-1_ubu1804_amd64.deb
wget https://www.sudo.ws/sudo/dist/packages/1.9.0/sudo-logsrvd_1.9.0-1_ubu1804_amd64.deb
wget https://www.sudo.ws/sudo/dist/packages/1.9.0/sudo-python_1.9.0-1_ubu1804_amd64.deb

Install these packages with the command:

sudo dpkg -i *.deb

Once the installation is complete, you're ready for testing.

How to test the python plugin

What we're going to do is test the new python module that will prevent all (non root) users from running any command other than id. This is incredibly limiting, but it shows you the power of the new system.

To do this, first change to the root user with the command:

su

Create a new policy with the command:

nano /root/policy.py

In that file, paste the following:

import sudo
class SudoPolicyPlugin(sudo.Plugin):
    def check_policy(self, argv, env_add):
        cmd = argv[0]        # the first argument is the command name
        if cmd != "id":      # Example for a simple reject:
            sudo.log_error("You are not allowed to run this command!")
            return sudo.RC.REJECT
        command_info_out = ( # setup command to execute
            "command=/usr/bin/id",  # Absolute path of command
            "runas_uid=0",          # The user id
            "runas_gid=0")          # The group id
        return(sudo.RC.ACCEPT, command_info_out, argv, env_add)

Save and close the file.

The important part of the code above is:

if cmd != "id":      # Example for a simple reject:
sudo.log_error("You are not allowed to run this command!")
return sudo.RC.REJECT

That effectively says if a command is not id, print out the error "You are not allowed to run this command!" Finally, it uses the RC.REJECT to reject whatever command isn't id.

Now we need to enable this policy. Open the sudo configuration file with the command:

nano /etc/sudo.conf

In that file, locate this section:

Plugin sudoers_policy sudoers.so
Plugin sudoers_io sudoers.so

Comment out the first line and add the new line, so it will look like:

#Plugin sudoers_policy sudoers.so
Plugin sudoers_io sudoers.so
Plugin python_policy python_plugin.so ModulePath=/root/policy.py ClassName=SudoPolicyPlugin

Save and close the file.

How to test the new policy

You now need to either open a new terminal or SSH into the machine with a new instance. Once you've done that, issue the command:

sudo ls

You will then see that you are no longer allowed to run the command (Figure A).

Figure A

sudo19a.jpg

Running any command but id is forbidden with sudo 1.9.

However, if you issue the id command, you'll see that it works (Figure B).

Figure B

sudo19b.jpg

The id command still works.

The caveat to this (and why you had to give the root user a password), is that it's incredibly limiting. This policy is based on the example_policy_plugin.py, where you'll notice this line:

_allowed_commands = ("id", "whoami")

You could always employ the example_policy_plugin.py script and add any commands you'd like to allow in there (to make this less restrictive). If you do use the example_policy_plugin.py, make sure to change the policy entry in /etc/sudo.conf.

And that's how you make use of the new policy system in sudo 1.9. This change is coming to a sudo near you, so make sure you get up to speed on it, before it's unleashed on your Linux distribution of choice.

Also see