Switching user (sudo)

On any Linux system, there is only one account with all the super-administrator power, this is the root account, the account with ID 0.
It is not recommended to use directly this account, for different reasons, all linked to security and traceability:
  • If allowed to be used to log on, one half of the job is done for the hackers, they just need to find the password as the username is always the same to get super power on the system
  • If every person having the right to administer a Linux server connect using root, you will not be able to make a difference between person A and person B. If you want to know "who did this ?", you will see root. Maybe by finding the name of the terminal, the originating IP, you will be able to put a real name on the root user at this moment, but it is more simple to give all your administrators a personal account.
  • If you're logged as root and type rm -rf * when you are by inadvertence in the root (/) directory, if run as root, the damages will be far more destructive than if you did this as a normal, unprivileged user.
Then if you don't allow direct login with the root account, you can left this one without any valid password, so it is impossible to use it directly

Thus, if you log in as a non-root user, how can you still be able to perform actions that need the privilege of root or any other system account?
There are some possibilities:
  1. su [-c command] username
  2. sudo [-u username] <command>
  3. sudo -s [-u username]

su

The first one is to use the command su. Although that we don't recommend it, we will speak a bit about it.
The su command allows any user to switch completely is login to the one of another user. When executing su, you are prompted to enter the password of the user you are switching to. So if you switch to root, you need to enter the root password. Therefore, there is a risk to have this password guessed and mis-used.
We don't recommend it, because you need to define a password for each account you want to switch to. And to share this password too, so increasing the risk for a "leak".
Because you switch to a full shell under the other account, a valid shell must be defined for these users you want to have.
So, to be able to use this command, you must:
  1. Define a valid password for the user(s) you want to switch to
  2. Define a valid shell for these users in the /etc/passwd file
  3. Share this password with the users
Each one of these 3 point above are increasing the security risks.

Instead of opening a shell as the selected user, you can run a single command as another user and return to your own shell after execution.
su -c /etc/init.d/apache start root

Remark: specifying the user root is optional as this is this account that is used by default as the target user of the command if none specified.
Of course, you will be prompted to enter the password of the target user and this user should be defined with a valid shell in /etc/passwd.

sudo

To avoid the use of su but still allowing securely users to perform actions as root, sudo is a safer player.
First of all, the use of sudo is only permitted if your user is configured by the administrator to be part of the "sudoers".
Secondly, the configuration can be fine tuned in a way that only some commands are allowed to be performed as root, and not all.
Thirdly, to be able to perform a command as another user using sudo, you don't need the password of the target user, but you will be prompted to enter your own password.
Who can use the sudo command to do what from where is defined in the /etc/sudoers file. You edit securely this file with the visudo command:
admin@server1:~$ sudo visudo

%sudo ALL=(ALL:ALL) ALL
%admin ALL=(ALL) ALL

www-data ALL=(ALL) NOPASSWD:/usr/bin/ansible,/bin/ssh
ubuntu ALL=(ALL) NOPASSWD:ALL

In the rules, we have 3 or 4 positions:

  • First position: the user or group of users (when preceeded by %) to which this rules applies
  • Second group
    • Left side of the equal sign: on which machines (host) this rule applies. Interesting if you want to export the same file to different hosts and want to have different permissions on different hosts. ALL means any host.
    • Right side of the equal sign: which user and / or group can be impersonated. The form ALL allows to become any user. The form ALL:ALL allows to become any user and any group.
  • The third group is the commands that are allowed to be executed. ALL for any commands or a comma-separated list of commands with their full path. When the keyword NOPASSWD: is used to preceed the command list, it means that no password will be requested to be entered to execute the command(s) matching that rule.
The configuration file allows you also to define aliases of commands. Like ADMIN_CMD=/usr/bin/ansible,/bin/ssh to represent these 2 commands in different rules. This is just an help to reduce the information to be typed, to avoid having to change a lot of line if some command need to be added, deleted or modified.

To use sudo, just do sudo [-u username] <command>
If you omit the -u username, it will execute the command as root by default.

sudo -s

To replace su in more controlled way, you can use sudo -s [-u username]. Like su, it will start a shell as username (root by default if you don't specify a user).
There are some advantages over su:
  • Usage is subject to the rules defined in sudoers, so if the user if not in the allowed users, it is not possible
  • No need to know the password of the target user (the user you are switching to). In fact this user doesn't need to have a password defined.
  • No need for the user to be defined with a valid Linux shell. In fact, even if the /etc/passwd line for this user uses /bin/false or /sbin/nologin, you can open the shell for this user.
Therefore, it is more secure to use sudo -s than su as the users you want to switch to doesn't need to be configured for a direct login (with password and shell).
Thus you must protect the accounts of your administrators and operators, and the system accounts can stay locked as after a default installation.