Baeldung Pro – Linux – NPI EA (cat = Baeldung on Linux)
announcement - icon

Learn through the super-clean Baeldung Pro experience:

>> Membership and Baeldung Pro.

No ads, dark-mode and 6 months free of IntelliJ Idea Ultimate to start with.

1. Overview

Privilege separation is a core security principle in Linux and Unix-like operating systems. By design, users are given limited privileges so their actions are confined to their environment, preventing impact on the entire system. The sudoers file determines which users and groups can execute commands with the sudo command.

To manage these permissions, the visudo command is utilized to edit the sudoers file safely. We should avoid editing the sudoers file directly with a regular text editor because it can lead to disastrous consequences, including locking ourselves out of sudo access. Instead, we should use the visudo command because it validates the file syntax before saving any changes.

In this tutorial, we’ll explore how the visudo command works and why it’s important. In addition, we’ll provide practical examples of how to use it effectively.

2. Understanding the sudoers File

The sudoers file is a system configuration file in the /etc/sudoers directory. It defines which users or groups can run commands as the superuser or other users. Furthermore, it sets the policies and access controls for the sudo command, allowing users to execute commands with elevated privileges.

2.1. Syntax

Let’s see an example of a typical entry in the sudoers file:

user host = (run_as_user : run_as_group) commands

Following is a breakdown of the directive above:

  • user specifies the username or group that gets the permission
  • host specifies from which host the user can execute the commands
  • run_as_user defines which user the command can be run as
  • run_as_group specifies which group the command should be run as, it’s usually optional
  • commands defines a single command or list of commands the user can run

As an illustration, let’s see a line that grants privileges to a specified user called johndoe:

johndoe ALL=(ALL:ALL) ALL

This line grants the user permission to run any command from any terminal as any other user, including root, after authenticating with their password.

2.2. Importance of Using visudo Over Manual Editing

Similar to how the vipw command safely edits the passwd file, visudo ensures the safe editing of the sudoers file. Specifically, it locks the file to prevent multiple simultaneous edits. It also performs basic sanity checks and can roll back changes if a syntax error is detected. This prevents the corruption of the file.

Finally, visudo uses a predefined list of text editors set at compile time, with the default editor typically being vi.

3. How to Use the visudo Command

Naturally, we need to have root privileges to run the visudo command:

$ sudo visudo

Running the command without options opens the sudoers file in the default text editor, usually vi or nano.

3.1. Changing the Editor

However, we can change the default editor by setting the EDITOR environment variable:

$ export EDITOR=nano

This command sets nano as the default editor for the current shell session.

3.2. Granting a User or Group sudo Access

Perhaps the most common use case for the visudo command is granting a user or a group sudo access. By default, only users in the sudo group have root privileges.

We can grant a specific user sudo access by using ALL in the sudoers file:

johndoe ALL=(ALL:ALL) ALL

This gives the user johndoe full sudo privileges, allowing this user to run any command as any other user.

Similarly, we can also grant sudo access to a group of users:

%developers ALL=(ALL) ALL

This command grants all users in the group developers sudo privileges. Notably, we use the % symbol to distinguish groups from regular users.

3.3. Limiting Commands With sudo

We can also limit the commands a user can run with sudo by specifying the ones that are allowed.

Let’s look at an illustration of how to limit the commands a user can run with root privileges:

johndoe ALL=(ALL) /bin/ls, /bin/cat

In this configuration, johndoe can only run the ls and cat commands with sudo. Any attempt to run other commands with sudo should be denied.

3.4. Configuring Passwordless sudo

For convenience, we can also configure passwordless sudo for specific users or groups. This can be especially useful for scripts or automation tasks where entering a password isn’t feasible or appropriate.

To allow a user to run sudo commands without a password prompt, we can add the NOPASSWD directive:

johndoe ALL=(ALL) NOPASSWD:ALL

This way, we provide a way for the user johndoe to execute any command with sudo without a password input requirement.

Alternatively, we can also restrict passwordless access to specific commands:

johndoe ALL=(ALL) NOPASSWD:/bin/ls

In this example, johndoe can only run the ls command without a password prompt.

3.5. Using Aliases in the sudoers File

For larger systems with several users and commands, it can be tedious to list every command explicitly multiple times. We use command and user aliases to simplify the configuration of such a scenario.

For example, let’s create an alias for a specific set of commands:

Cmnd_Alias FILEOPS = /bin/cp, /bin/mv, /bin/rm

Next, we can reference FILEOPS in the user permissions:

johndoe ALL=(ALL) FILEOPS

Thus, we allow johndoe to run cp, mv, and rm with sudo.

Similarly, we might want to create user aliases:

User_Alias ADMINS = johndoe, janedoe
ADMINS ALL=(ALL) ALL

These lines grant both johndoe and janedoe full sudo privileges without repeating their permissions.

3.6. Restricting sudo Access to Specific Hosts

In environments with multiple machines, we can restrict users to running sudo commands only on specific hosts.

As an illustration, let’s look at how to restrict sudo access of a user to a specific host:

johndoe webserver01=(ALL) ALL

This way, we limit the user johndoe to using sudo on the machine named webserver01.

4. Best Practices for Using visudo

Let’s look at some of the best practices for configuring and using the visudo command.

4.1. Minimize the Use of ALL

Granting users or groups unrestricted access can pose a significant security risk. Instead, we should limit permissions to specific commands necessary for their tasks.

For example, we can grant a user privileges to only the apt-get and journalctl commands:

johndoe ALL=(ALL) /usr/bin/apt-get, /bin/journalctl

This restricts johndoe to package management and viewing logs, keeping the system more secure.

4.2. Use Groups for Better Manageability

Even in medium-sized deployments, assigning privileges to groups rather than individual users often simplifies administration.

For instance, if we have a group of system managers who need access to certain commands, we can create a group and then assign privileges to that group:

%sysadmins ALL=(ALL) /usr/bin/docker, /usr/bin/kubectl

This way, we grant all members of the sysadmins group the ability to run docker and kubectl commands. This method is usually easier to manage than writing several lines for each user.

4.3. Test Changes With the -l Option

Before we make critical changes, we can test how a specific user’s sudoers permissions will apply using the -l option:

$ sudo -l -U johndoe
Matching Defaults entries for johndoe on johndoe-HP-ProBook-440-G7:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User johndoe may run the following commands on johndoe-HP-ProBook-440-G7:
    (ALL : ALL) ALL

This command lists all the commands johndoe is permitted to run based on the current configuration of the sudoers file.

4.4. Back up the sudoers File

As with any critical configuration file, we should always back up the current sudoers file before making any changes:

$ sudo cp /etc/sudoers /etc/sudoers.bak

This line creates a backup file called sudoers.bak local to the original sudoers configuration.

In case of any errors, we can restore the backup and recover the system:

$ sudo cp /etc/sudoers.bak /etc/sudoers

This gives us a quick way of restoring the sudoers file in case we make any errors.

5. Summary

In summary, controlling user access to different parts of the environment is an important security principle in all systems. It ensures that users operate within restricted boundaries, protecting the system from undue influence. Furthermore, the visudo command plays a crucial role in managing these privileges by safely editing the sudoers file. By using visudo, administrators can maintain the integrity of the sudoers file and ensure accurate configurations.

In particular, the sudoers file enables precise control over user permissions. For instance, using directives such as johndoe ALL=(ALL:ALL) ALL grants comprehensive access, whereas %admin ALL=(ALL) ALL provides specific group-based permissions.

Overall, by understanding and correctly implementing these directives, administrators can ensure effective privilege management. Consequently, this approach not only enhances system security but also enables flexible and precise administrative control.