The major difference between sudo
and su
is the mechanism used to authenticate. With su
the user must know the root
password (which should be a closely guarded secret), while with sudo
the user uses his/her own password. In order to stop all users causing mayhem, the priviliges discharged by the sudo
command can, fortunately, be configured using the /etc/sudoers
file.
Both commands run a command as another user, quite often root
.
sudo su -
works in the example you gave because the user (or a group where the user is a member) is configured in the /etc/sudoers
file. That is, they are allowed to use sudo
. Armed with this, they use the sudo
to temporarily gain root
privileges (which is default when no username is provided) and as root
start another shell (su -
). They now have root
access without knowing root
's password.
Conversely, if you don't allow the user to use sudo
then they won't be able to sudo su -
.
Distros generally have a group (often called wheel
) whose members are allowed to use sudo
to run all commands. Removing them from this group will mean that they cannot use sudo
at all by default.
The line in /etc/sudoers
that does this is:
## Allows people in group wheel to run all commands
%wheel ALL=(ALL) ALL
While removing users from this group would make your system more secure, it would also result in you (or other system adminstrators) being required to carry out more administrative tasks on the system on behalf of your users.
A more sensible compromise would configure sudo
to give you more fine grained control of who is allowed to use sudo
and who isn't, along with which commands they are allowed to use (instead of the default of all commands). For example,
## Allows members of the users group to mount and unmount the
## cdrom as root
%users ALL=/sbin/mount /mnt/cdrom, /sbin/umount /mnt/cdrom
(only useful with the previous %wheel line commented out, or no users in the wheel
group).
Presumably, distros don't come with this finer grained configuration as standard as it's impossible to forecast what the admin's requirements are for his/her users and system.
Bottom line is - learn the details of sudo
and you can stop sudo su -
while allowing other commands that don't give the user root
shell access or access to commands that can change other users' files. You should give serious consideration to who you allow to use sudo
and to what level.
WARNING: Always use the visudo
command to edit the sudoers
file as it checks your edits for you and tries to save you from the embarrassing situation where a misconfigured file (due to a syntax error) stops you from using sudo
to edit any errors. This is especially true on Debian/Ubuntu and variants where the root
account is disabled by default.
Root is user 0
The key thing is the user ID 0. There are many places in the kernel that check the user ID of the calling process and grant permission to do something only if the user ID is 0.
The user name is irrelevant; the kernel doesn't even know about user names.
Android's permission mechanism is identical at the kernel level but completely different at the application level. Android has a root user (UID 0), just like any other system based on a Linux kernel. Android doesn't have user accounts though, and on most setups doesn't allow the user (as in the human operating and owning the device) to perform actions as the root user. A “rooted” Android is a setup that does allow the device owner/user to perform actions as root.
How setuid works
A setuid executable runs as the user who owns the executable. For example, su
is setuid and owned by root, so when any user runs it, the process running su
runs as the root user. The job of su
is to verify that the user that calls it is allowed to use the root account, to run the specified command (or a shell if no command is specified) if this verification succeeds, and to exit if this verification fails. For example, su
might ask the user to prove that they know the root password.
In more detail, a process has three user IDs: the effective UID, which is used for security checks; the real UID, which is used in a few privilege checks but is mainly useful as a backup of the original user ID, and the saved user ID which allows a process to temporarily switch its effective UID to the real user ID and then go back to the former effective UID (this is useful e.g. when a setuid program needs to access a file as the original user). Running a setuid executable sets the effective UID to the owner of executable and retains the real UID.
Running a setuid executable (and similar mechanisms, e.g. setgid) is the only way to elevate the privileges of a process. Pretty much everything else can only decrease the privileges of a process.
Beyond traditional Unix
Until now I described traditional Unix systems. All of this is true on a modern Linux system, but Linux brings several additional complications.
Linux has a capability system. Remember how I said that the kernel has many checks where only processes running as user ID 0 are allowed? In fact, each check gets its own capability (well, not quite, some checks use the same capability). For example, there's a capability for accessing raw network sockets, and another capability for rebooting the system. Each process has a set of capabilities along side its users and groups. The process passes the check if it is running as user 0 or if it has the capability that corresponds to the check. A process that requires a specific privilege can run as a non-root user but with the requisite capability; this limits the impact if the process has a security hole. An executable can be setcap to one or more capabilities: this is similar to setuid, but works on the process's capability set instead of the process's user ID. For example, ping only needs raw network sockets, so it can be setcap CAP_NET_RAW
instead of setuid root.
Linux has several security modules, the best known being SELinux. Security modules introduce additional security checks, which can apply even to processes running as root. For example, it's possible (not easy!) to set up SELinux so as to run a process as user ID 0 but with so many restrictions that it can't actually do anything.
Linux has user namespaces. Inside the kernel, a user is in fact not just a user ID, but a pair consisting of a user ID and a namespace. Namespaces form a hierarchy: a child namespace refines permissions within its parent. The all-powerful user is user 0 in the root namespace. User 0 in a namespace has powers only inside that namespace. For example, user 0 in a user namespace can impersonate any user of that namespace; but from the outside all the processes in that namespace run as the same user.
Best Answer
Use
sudo -E
to preserve your environment:That will preserve
$HOME
and any other environment variables you had, so the same configuration files you started with will be accessed by the programs running as root.You can update
sudoers
to disable theenv_reset
setting, which clears out all environment variables and is generally enabled by default. You may have to enable the ability to usesudo -E
at all in there as well. There are a few othersudoers
settings that might be relevant:env_keep
, which lets you specify specific variables to keep by default, andenv_remove
, which declares variables to delete always. You can usesudo sudo -V
to see which variables are/are not preserved.An alternative, if you can't modify
sudoers
, is to provide your environment explicitly:You can make a shell alias to do that automatically so you don't have to type it in.
Note that doing this (either way) can have potentially unwanted side effects: if the program you run tries to make files in your home directory, for example, those files will be created as root and your ordinary user won't be able to write to them.
For the specific case of
vim
, you could also put your.vimrc
as the system-wide/etc/vimrc
if you're the only user of this system.