Skip to content

How to grant a user sudo access

Use this guide when a user on a server needs to run commands as root, either with full administrator rights or for a few specific commands only.

Before you begin

  • You have a root shell, or an account that can already use sudo.
  • Replace <USERNAME> in the commands with the login name of the user who gets the rights, for example alice.

Don't lock yourself out

A syntax error in a sudoers file can stop sudo working for everyone, including you. On a server without a root password, that leaves you without administrator access. Before you change anything, open a second session and start a root shell in it with sudo -i, and keep it open until you have verified the result. Validate every file with visudo before sudo reads it, as the steps below do, and never remove your own account from the admin group.

Make sure sudo is installed

Check that the sudo command exists:

$ command -v sudo
/usr/bin/sudo

If the command prints nothing, install sudo from a root shell, for example after logging in as root or running su -:

# apt install sudo

Ubuntu always installs sudo. The Debian installer sets it up only when you leave the root password empty.

Ubuntu 26.04 uses sudo-rs, a reimplementation of sudo in Rust, by default. It reads the same sudoers files, and every command in this guide works with it.

# dnf install sudo

sudo is installed by default.

# pacman -S sudo

sudo isn't part of the base package, so a minimal installation may lack it.

# emerge --ask app-admin/sudo

sudo isn't part of the stage 3 system, so you install it yourself.

Create the user

Skip this section if the account already exists.

  1. Create the account with a home directory and the Bash shell:

    sudo useradd --create-home --shell /bin/bash <USERNAME>
    

    On Debian and Ubuntu, the interactive adduser <USERNAME> command does the same and asks for a password.

  2. Set a password. sudo asks users for their own password, so the account needs one unless you grant password-less access:

    sudo passwd <USERNAME>
    

Grant full administrator rights

Add the user to the group that the distribution's sudoers policy treats as administrators. This is the simplest way to grant full rights, and the easiest to undo.

The sudo group is already allowed to run any command:

sudo usermod --append --groups sudo <USERNAME>

The wheel group is already allowed to run any command:

sudo usermod --append --groups wheel <USERNAME>
sudo visudo -c

The rule for the wheel group is commented out in /etc/sudoers. Enable it in a drop-in file rather than editing the main file, so that package updates never conflict with your change. Write the rule to a scratch file, validate it, and only then install it:

echo '%wheel ALL=(ALL:ALL) ALL' > sudoers-wheel
sudo visudo -cf sudoers-wheel
sudo install -m 0440 -o root -g root sudoers-wheel /etc/sudoers.d/10-wheel
rm sudoers-wheel
sudo usermod --append --groups wheel <USERNAME>
sudo visudo -c

The rule for the wheel group is commented out in /etc/sudoers. Enable it in a drop-in file rather than editing the main file, so that dispatch-conf never asks you to merge your change. Write the rule to a scratch file, validate it, and only then install it:

echo '%wheel ALL=(ALL:ALL) ALL' > sudoers-wheel
sudo visudo -cf sudoers-wheel
sudo install -m 0440 -o root -g root sudoers-wheel /etc/sudoers.d/10-wheel
rm sudoers-wheel
sudo usermod --append --groups wheel <USERNAME>
sudo visudo -c

The new group membership takes effect the next time the user logs in. Sessions that are already open keep their old groups.

Grant rights in a drop-in file instead

Use a drop-in file when you want to grant rights to one user without changing group memberships, or when the rule needs options such as a list of allowed commands. sudo reads every file in /etc/sudoers.d/ whose name contains no dot (.) and doesn't end in ~, so name the file after its purpose, for example 50-<USERNAME>.

  1. Write the rule to a scratch file in your home directory. This rule lets the user run any command as any user, like the admin group does:

    echo '<USERNAME> ALL=(ALL:ALL) ALL' > sudoers-<USERNAME>
    
  2. Check the syntax. visudo -c checks without changing anything, and -f names the file to check:

    $ sudo visudo -cf sudoers-<USERNAME>
    sudoers-alice: parsed OK
    

    If visudo reports a syntax error, correct the scratch file and check it again. sudo hasn't read it yet, so a mistake here can't lock anyone out.

  3. Install the file with the ownership and mode that sudo expects (owned by root, not writable), then check the whole configuration:

    sudo install -m 0440 -o root -g root sudoers-<USERNAME> /etc/sudoers.d/50-<USERNAME>
    rm sudoers-<USERNAME>
    sudo visudo -c
    

Tip

To edit a drop-in file interactively, run sudo visudo -f /etc/sudoers.d/50-<USERNAME>. visudo opens the file in an editor and checks the syntax before it saves, and offers to reopen the file if there is an error.

Restrict a user to specific commands

Use a drop-in file that lists the allowed commands instead of ALL. This example lets a user read the kernel log with dmesg, which ordinary users can't do on any of the supported distributions. The commands use <LIMITED_USER> for that user, which must not be in the admin group. If the account doesn't exist yet, create it as described in Create the user.

  1. Find the full path of each command. sudo matches commands by path, so always give it in full:

    $ command -v dmesg
    /usr/bin/dmesg
    
  2. Write the rule to a scratch file, check it, and install it:

    echo '<LIMITED_USER> ALL=(root) /usr/bin/dmesg' > sudoers-<LIMITED_USER>
    sudo visudo -cf sudoers-<LIMITED_USER>
    sudo install -m 0440 -o root -g root sudoers-<LIMITED_USER> /etc/sudoers.d/50-<LIMITED_USER>
    rm sudoers-<LIMITED_USER>
    sudo visudo -c
    

    (root) means the user may run the command as root only. A command given without arguments may be run with any arguments. To allow only exact arguments, list them, as in /usr/bin/systemctl restart nginx.service; to allow the command only without arguments, follow it with "". Separate several commands with commas.

Warning

Only allow commands that can't start a shell or write arbitrary files. Editors, pagers such as less, interpreters, and tools such as find or tar let the user escape to a root shell, which is the same as granting ALL. To let a user edit a particular file as root, allow sudoedit with that file's path instead of an editor.

Verify

  1. List what the user may run. -l lists the rules that apply, and -U chooses whose rules to list:

    $ sudo -l -U <USERNAME>
    Matching Defaults entries for alice on server1:
        env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin, use_pty
    
    User alice may run the following commands on server1:
        (ALL : ALL) ALL
        (ALL : ALL) ALL
    

    The output differs between distributions, and sudo-rs on Ubuntu shows only the rules. In this example, the user is allowed everything twice: once through the sudo group and once through the drop-in file. One of them is enough; remove the one you don't need.

  2. Check a single command. With a command after -l, sudo prints its full path and exits with status 0 if the user may run it, or exits with a non-zero status if not:

    $ sudo -l -U <LIMITED_USER> /usr/bin/dmesg
    /usr/bin/dmesg
    

    For a command the user may not run, sudo prints nothing and exits with status 1. Check this with echo $? straight after the command:

    sudo -l -U <LIMITED_USER> /usr/bin/cat /etc/shadow
    

  3. Test as the user. Log in as the user in a new session, or switch to the account with su, and run a harmless command through sudo. sudo asks for the user's own password:

    $ su - <USERNAME>
    $ sudo whoami
    root
    

When the result is what you expect, close the spare root shell.

Undo the change

  • Remove the user from the admin group with sudo gpasswd --delete <USERNAME> sudo (Debian and Ubuntu) or sudo gpasswd --delete <USERNAME> wheel (other distributions).
  • Delete a drop-in file with sudo rm /etc/sudoers.d/50-<USERNAME>, then run sudo visudo -c.

Troubleshooting

<USERNAME> is not in the sudoers file or Sorry, user <USERNAME> may not run sudo. The rule doesn't apply yet. If you used a group, the user must log out and in again; check the session's groups with id. If you used a drop-in file, check that its name contains no dot and that sudo -l -U <USERNAME> lists the rule.

sudo: /etc/sudoers.d/50-<USERNAME> is world writable or a similar warning about ownership. sudo ignores files that other users could modify. Reinstall the file with install -m 0440 -o root -g root, or fix it with chmod 0440 and chown root:root.

sudo reports a parse error and no longer works. Use the root shell you kept open to run visudo -c, which names the broken file and line, then correct or remove that file. If you no longer have a root shell, log in as root on the console, or boot into rescue mode, and do the same.