Using sudo

251

Now that We have seen how to configure sudo, how do you use it? Sudo is very easy to use, as you will see. To determine what commands you have available to you via sudo, you can execute:

[ankit@black]$ sudo -l
Password:
User ankit may run the following commands on this host:
     (root) /etc/rc.d/init.d/httpd, /etc/rc.d/init.d/mysql
     (root) /bin/rpm, /bin/rm, /sbin/linuxconf
     (root) /usr/bin/swatch, /bin/touch
     (root) NOPASSWD: /bin/su
     (Jason) /home/Jason/bin/eggdrop, /home/Jason/bin/irc/ircd

This will show you exactly what commands you can run, and as what user. To use sudo to restart Apache, for example, you would use:

[ankit@black]$ sudo /etc/rc.d/init.d/httpd restart
Password:

After supplying his password, Apache will restart for Ankit. If he wanted to start eggdrop as Jason, however, he would have to approach it somewhat differently:

[ankit@black]$ sudo -u Jason /home/Jason/bin/eggdrop&
Password:

This will launch eggdrop in the background running as Jason’s uid. Because sudo will, by default, try to run something as root, you must supply the user’s username if it is a non-root user, as is the case here. Observe what happens if Ankit neglects to specify Jason’s username:

[ankit@black]$ sudo /home/Jason/bin/eggdrop
Sorry, user ankit is not allowed to execute '/home/Jason/bin/eggdrop' as root
on black.somehost.com.

As you can see, sudo is very flexible, and very willing to replace su. In fact, I would even go so far as to make su only available through sudo. In order for su to work for non-root users (ie. allow non-root users to become root or any other user), /bin/su must have the setuid bit enabled, so it can run as root. If you remove the setuid bit from /bin/su, then even if a user knows the root password, they cannot su to root or any other user. Stripping setuid from /bin/su and restricting root logins from the console and via SSH is a very effective means of locking down unauthorized root access on your system. To do this, simply give yourself sudo access to run su (as illustrated with Ankit previously), and strip the setuid bit from /bin/su by executing (as root):

[root@black]# chmod u-s /bin/su
[root@black]# ls -l /bin/su
-rwxr-xr-x      1 root     root      18172 June 4 05:29 /bin/su*

Now if you try to run the command su – as a non-root user, even if you type in the right password for root, you will not change to root. In order for someone to use su, they must exist in sudoers with the appropriate permissions, and must run su through sudo like this:

[ankit@black]$ sudo su -
[root@black]#

I find this a much better approach to restricting access to root. By having su as a setuid application, any user on the system can attempt to execute su; if they have the root password or can guess it, they can become root. By having su access restricted through sudo, and with the setuid bit removed, the chances of breaking into root are much more limited. Think of it this way. If someone can compromise your box and obtain shell access as the user “apache” or “nobody”, with su setuid, they can attempt to login as root, and if they find the password, there’s no stopping them. With su being stripped of the setuid bit, even if someone obtains shell access as the user “apache”, they are limited only to being able to do what the user “apache” has rights to. Even if they know your root password, they cannot su to root. They would need to guess Ankit’s password in order to become Ankit, who could then become root via sudo. But even then, they could not use su to become Ankit, they would have to log into the system as Ankit.

To take the illustration further, this would mean they would need local console access to login as Ankit (if they had his password), or via SSH (since Ankit knows better than to run telnet). But Ankit’s smart. He hasn’t gone through the trouble of setting up sudo to let something like this stop him. He’s also configured SSH to reject all password logins and only allow key-based authentication. Without Ankit’s private key, no one is logging into his account via SSH. So even if your Apache server, or sendmail server, or DNS server, allowed someone to obtain shell access to your system with an unprivileged account, the damage they could do would be minimal. Without su being available to them as an unprivileged user, without having local console access, and without being able to log in to a user’s account via SSH without having his private key, an attacker must resort to more difficult means of attacking your server to obtain root access. You can rest assured that you haven’t made his job any easier by taking a few simple steps to protect yourself.