How to harden su with dpkg-statoverride?
The purpose is to prevent ordinary users from running the su command (su is similar to sudo, the difference being that sudo executes one command, su starts a new session as a new user, which lasts until that user runs exit)
The default mode of su is 4755 or rwsr-xr-x, the "s" means that the command is set-UID (which means that it always runs as the user who owns it, rather than the user who happens to execute it. In this case su is owned by root, so it always runs with root privileges)
su has its own security measures in place to ensure that the user who executes it has authority to become another user (typically by asking for the other user's password), but it's conceivable that there would be a security vulnerability in su that would allow an attacker to somehow convince it to do something else without authority.
By changing the mode to 4750, it prevents ordinary users (users other than root and those in the sudo group) from even reading or executing it in the first place, so an attacker would need to either change the ownership of that file, or change the mode of the file, or change their own effective UID/GID before they could even attempt to exploit this theoretical vulnerability in su.
The dpkg-statoverride command is useful in this instance because it directs the package manager to use those ownership/mode values for that file, even if it gets replaced by a newer version (i.e. via apt upgrade). In other words, it makes it more permanent than just a chown and chmod.
Here's a general-purpose tactic I recommend for this instance: Whenever I'm tweaking configuration of su/sudo or any authentication component on a Linux/UNIX machine, I'll open up another ssh/putty session to that server and log in as the root user, and just leave that session open in another window. That way if I do screw something up and lock myself out, I've already got a login session where I can fix anything I broke.
Depending on your users, that may be a good or bad idea.
The su
command can be used by ordinary users to log into any other account, not just the superuser's, provided they know the password of the account.
This is useful e.g. when two users are cooperating on a project, one of them (userA) is logged in and they need to read a file only accessible to the other user (userB). Simply running
su -c 'cat /home/userB/file' userB >file
can be used to copy the file to the logged in user's home directory, but that is only possible if userA is allowed to run the su
command.
On PostgreSQL database servers, it is usually possible for database administrators to switch to the postgres
user to perform some maintenance tasks that are not possible while the database server is live; for this to work, they need to be able to run su - postgres
.
The same considerations apply to the sudo
command (which is different and way more complex than su
-- it is only the default configuration that makes the command primarily useful for the sudoers
group, because that group is allowed to run any command as root
. However, if you add any custom rules, e.g. allowing any user to run updatedb
with no arguments, then users outside the sudoers
group need execute permission on sudo
.
Also, there is not only su
that is setuid -- there is also
sg
(allows temporarily joining a group if there is a group password set)passwd
(allows changing the password)chfn
(allows changing user information)chsh
(allows changing default shell)
and several others. These tools share lots of code with the su
command, so changing the mode of /bin/su
alone will not buy you much, and changing the mode of all of them will certainly annoy your users, especially in the case of passwd
.