Understanding the Differences Between Linux Commands ‘su’ and ‘sudo’
Previously, I was confused about the two commands su and sudo. Recently, I specifically searched for information on this topic and finally clarified the relationship and usage of both commands. This article aims to systematically summarize the findings.
1
Preparation
Since this blog involves user switching, I need to prepare several test users in advance for easy switching later.
The command to create a new user in Linux is useradd. Generally, the path for this command is included in the PATH environment variable. If entering useradd directly does not work, use the absolute path:
/usr/sbin/useradd.
The useradd command can only be executed by the root user. We will first switch from the normal user ubuntu to the root user (how to switch will be introduced later):
ubuntu@VM-0-14-ubuntu:~$ su -
Password: # Enter root user login password
root@VM-0-14-ubuntu:~# useradd -m test_user # Include -m parameter
root@VM-0-14-ubuntu:~# ls /home
test_user ubuntu # You can see that there are two users in the /home directory
Since we have not set a login password for the newly created user test_user, we cannot switch from the normal user ubuntu to test_user. Therefore, we need to set the login password for test_user using the root account. We will use the passwd command:
root@VM-0-14-ubuntu:~# passwd test_user
Enter new UNIX password: # Enter test_user's password
Retype new UNIX password:
passwd: password updated successfully
root@VM-0-14-ubuntu:~#
Next, we enter exit to log out from the root user back to the normal user ubuntu:
root@VM-0-14-ubuntu:~# exit
logout
ubuntu@VM-0-14-ubuntu:~$
As we can see, the command prompt has changed from root to ubuntu, indicating that we are now logged in as the ubuntu user.
2
Introduction to the ‘su’ Command and Its Main Usage
First, let’s explain what su stands for.
I used to think that su meant super user, but after researching, I found out it actually stands for switch user.
Now that we know what su stands for, its functionality becomes clear: it is used to switch users.
2.1 The ‘-‘ Parameter
The general usage of su is:
su <user_name>
or
su - <user_name>
The difference between these two methods is just one character, -, but it makes a significant difference:
- If the
-parameter is included, it is alogin-shellmethod, meaning that after switching to another user<user_name>, the current shell will load the environment variables and various settings corresponding to<user_name>; - If the
-parameter is not included, it is anon-login-shellmethod, meaning that while we have switched to<user_name>, the current shell still loads the environment variables and various settings of the previous user.
Explaining this can be abstract, so let’s look at an example for better understanding.
We will first switch from the ubuntu user to the root user using the non-login-shell method and compare the value of the PWD variable in the environment variables of both user states (the su command without any <user_name> defaults to switching to the root user):
ubuntu@VM-0-14-ubuntu:~$ env | grep ubuntu
USER=ubuntu
PWD=/home/ubuntu # It is /home/ubuntu
HOME=/home/ubuntu
# omitted......
ubuntu@VM-0-14-ubuntu:~$ su # non-login-shell method
Password: # Enter root user login password
root@VM-0-14-ubuntu:/home/ubuntu# env | grep ubuntu
PWD=/home/ubuntu # We can see it is still /home/ubuntu
root@VM-0-14-ubuntu:/home/ubuntu#
We have indeed switched to the root user, but the variables in the shell environment have not changed; they still use the previous ubuntu user’s environment variables.
Next, we will switch from the ubuntu user to the root user using the login-shell method and compare the value of the PWD variable in the environment variables of both user states:
ubuntu@VM-0-14-ubuntu:~$ env | grep ubuntu
USER=ubuntu
PWD=/home/ubuntu # It is /home/ubuntu
HOME=/home/ubuntu
# omitted.......
ubuntu@VM-0-14-ubuntu:~$ su - # login-shell method
Password:
root@VM-0-14-ubuntu:~# env | grep root
USER=root
PWD=/root # It has changed to /root
HOME=/root
MAIL=/var/mail/root
LOGNAME=root
root@VM-0-14-ubuntu:~#
We can see that when switching users using the login-shell method, the environment variables in the shell also change accordingly.
Summary: The specific method of switching users depends on personal needs:
- If you do not want to lose your current user settings when switching to another user, use the
non-login-shellmethod; - If you need to use the various environment variables of that user after switching (the environment variable settings for different users are generally different), then use the
login-shellmethod.
2.2 Switching to a Specified User
As mentioned earlier, if the su command is not followed by any <user_name>, it defaults to switching to the root user:
ubuntu@VM-0-14-ubuntu:~$ su -
Password: # root user password
root@VM-0-14-ubuntu:/home/ubuntu#
Since we have already created a test_user in the preparation section and we know the login password for test_user (set by the root user), we can switch from the ubuntu user to the test_user user:
ubuntu@VM-0-14-ubuntu:~$ su - test_user
Password: # test_user's password
$
2.3 The ‘-c’ Parameter
In the previous methods, we first switch to another user (root or test_user), execute commands in that user’s state, and finally enter exit to return to the current ubuntu user.
Another method is: you do not need to switch users first to execute commands; you can directly execute commands as another user from the current user, and return to the current user after execution. This requires the use of the -c parameter.
The specific usage is:
su - -c "command string" # Execute "command string" as root
Let’s look at an example:
ubuntu@VM-0-14-ubuntu:~$ cat /etc/shadow
cat: /etc/shadow: Permission denied # The ubuntu user cannot directly view the contents of /etc/shadow
ubuntu@VM-0-14-ubuntu:~$ su - -c "tail -n 4 /etc/shadow"
Password: # Enter root user password
ubuntu:$1$fZKcWEDI$uwZ64uFvVbwpHTbCSgim0/:18352:0:99999:7:::
ntp:*:17752:0:99999:7:::
mysql:!:18376:0:99999:7:::
test_user:$6$.ZY1lj4m$ii0x9CG8h.JHlh6zKbfBXRuolJmIDBHAd5eqhvW7lbUQXTRS//89jcuTzRilKqRkP8YbYW4VPxmTVHWRLYNGS/:18406:0:99999:7:::
ubuntu@VM-0-14-ubuntu:~$ # Immediately returns to the ubuntu user after execution
This execution method is very similar to the sudo command that will be introduced later; both temporarily request root user permissions. However, there are still differences, which we will explore next.
3
Introduction to the ‘sudo’ Command and Its Main Usage
First, let’s explain what the sudo command means.
The full name of sudo is super user do, which means executing commands as a superuser (root user). Here, sudo is different from su, which means switch user, and this distinction is important to avoid confusion.
We will first introduce what sudo can do, then explain how it can do these things.
Let’s begin.
3.1 Main Usage
In Linux, we often encounter Permission denied situations, such as trying to view the contents of /etc/shadow as the ubuntu user. This file can only be viewed by the root user.
So what can we do if we want to view it? In this case, we can use sudo:
ubuntu@VM-0-14-ubuntu:~$ tail -n 3 /etc/shadow
tail: cannot open '/etc/shadow' for reading: Permission denied # No permission
ubuntu@VM-0-14-ubuntu:~$ sudo !! # Repeat the last command
sudo tail -n 3 /etc/shadow
ntp:*:17752:0:99999:7:::
mysql:!:18376:0:99999:7:::
test_user:$6$.ZY1lj4m$ii0x9CG8h.JHlh6zKbfBXRuolJmIDBHAd5eqhvW7lbUQXTRS//89jcuTzRilKqRkP8YbYW4VPxmTVHWRLYNGS/:18406:0:99999:7:::
ubuntu@VM-0-14-ubuntu:~$
In this example, we used the sudo !! trick, which means to repeat the last command with sudo added at the front.
Since I have set sudo to not require a password, sudo !! can directly output the content. If it were not set, I would need to enter the current user’s password, which in this case would be the ubuntu user’s login password.
For two consecutive sudo operations, if the interval is within 5min, the second sudo does not require re-entering the password; if it exceeds 5min, then re-entering sudo will require entering the password again. Therefore, a convenient method is to set sudo operations to not require a password. I will explain how to set this up later.
sudo can also be used in several other ways, which I will briefly introduce here.
Switching to the root user:
sudo su -
This method can also switch to the root user in a login-shell manner, but it differs from the su - method:
- For the former, after entering
sudo su -, you need to provide the current user’s login password, which is theubuntuuser’s password; - For the latter, after entering
su -, you need to provide the root user’s login password.
There is also a command:
sudo -i
This command has the same effect as sudo su -, which is also to switch to the root user and requires providing the current user’s (the ubuntu user’s) login password.
Now, let’s switch to the test_user user and try to display the contents of the /etc/shadow file:
ubuntu@VM-0-14-ubuntu:~$ su - test_user
Password: # test_user's password
$ sudo cat /etc/shadow
[sudo] password for test_user: # test_user's password
test_user is not in the sudoers file. This incident will be reported.
$
We will see an error message in the second to last line indicating that we cannot view the contents of /etc/shadow. Why is that? Why can ubuntu use sudo but test_user cannot?
This involves the working principle of sudo.
3.2 The Working Principle of ‘sudo’
Whether a user can use the sudo command depends on the settings in the /etc/sudoers file.
From section 3.1, we have seen that the ubuntu user can use sudo normally, but the test_user cannot. This is because the /etc/sudoers file does not have a configuration for test_user.
/etc/sudoers is also a text file, but due to its specific syntax, we should not edit it directly with vim or vi; instead, we need to use the visudo command. After entering this command, we can directly edit the /etc/sudoers file.
It should be noted that only the root user has permission to use the visudo command.
Let’s first look at the content displayed after entering the visudo command.
Input (as root user):
root@VM-0-14-ubuntu:~# visudo
Output:
# User privilege specification
root ALL=(ALL:ALL) ALL
# Members of the admin group may gain root privileges
%admin ALL=(ALL) ALL
# Allow members of group sudo to execute any command
%sudo ALL=(ALL:ALL) ALL
# See sudoers(5) for more information on "#include" directives:
#includedir /etc/sudoers.d
ubuntu ALL=(ALL:ALL) NOPASSWD: ALL
Let’s explain the format of each line:
- The first line indicates the username, such as
root,ubuntu, etc.; - The
ALLon the left side of the equal sign indicates that the user can log in from any host; - The
ALLon the right side indicates that the user can switch to any other user in the system; - The
ALLat the end of the line indicates what commands the user can execute as the root user, whereALLmeans any command.
We also notice that the line corresponding to ubuntu has a NOPASSWD keyword, which indicates that the ubuntu user does not need to enter a password when requesting sudo. This explains the previous issue.
At the same time, we notice that there is no corresponding line for test_user in this file, which explains why test_user cannot use the sudo command.
Next, we will try to add test_user to the /etc/sudoers file so that test_user can also use the sudo command. We will add the following line at the end:
test_user ALL=(ALL:ALL) ALL # test_user needs to provide test_user's password to use sudo
Next, we will execute sudo under the test_user account:
ubuntu@VM-0-14-ubuntu:~$ su - test_user
Password:
$ tail -n 3 /etc/shadow
tail: cannot open '/etc/shadow' for reading: Permission denied
$ sudo tail -n 3 /etc/shadow # Add sudo
ntp:*:17752:0:99999:7:::
mysql:!:18376:0:99999:7:::
test_user:$6$.ZY1lj4m$ii0x9CG8h.JHlh6zKbfBXRuolJmIDBHAd5eqhvW7lbUQXTRS//89jcuTzRilKqRkP8YbYW4VPxmTVHWRLYNGS/:18406:0:99999:7:::
$
As we can see, sudo can now be used.
3.3 Considerations
We have seen that if a user is in the /etc/sudoers file, they have sudo permissions and can switch to the root user using commands like sudo su - or sudo -i. At this point, the user effectively becomes the root user, which poses a significant threat to the system.
This is indeed the case. Therefore, when editing the /etc/sudoers file to grant a user sudo permissions, it is crucial to ensure that the user is trusted and will not cause malicious damage to the system. Otherwise, granting all root permissions to that user can be very dangerous.
Of course, the root user can also edit the /etc/sudoers file to give users only partial permissions, allowing them to execute only a limited number of commands. Interested readers can refer to the second item in the Reference section; this article will not elaborate further.
4
Comparison of the Two Commands
We have seen:
- Using
su -, providing the root account password allows switching to the root user; - Using
sudo su -, providing the current user’s password also allows switching to the root user.
The differences between the two methods are also evident: if our Linux system has many users, the former requires all users to know the root user password, which is clearly very dangerous; the latter does not require exposing the root account password. Users only need to enter their own account password, and which users can switch to root is entirely controlled by root (achieved by setting /etc/sudoers), making the system much more secure.
