Linux VPS

Edit the sudoers file safely with visudo

Change who can use sudo without breaking it. Learn the sudoers syntax, use visudo and drop-in files in /etc/sudoers.d, and grant full or limited admin rights.

IntermediateLinux server5 min read

The sudoers file decides who can run commands as root on your server. One typo in it can stop sudo from working for everyone, which is a real problem if root login is disabled. This guide explains the syntax, shows why visudo is the only safe way to edit it, and walks through the most common rules using drop-in files.

Before you start

  • A Linux VPS with Ubuntu 22.04 or 24.04, Debian 12, or AlmaLinux or Rocky Linux 8 or 9.
  • An SSH session as root or a working sudo user.
  • A second session open as root (sudo -i) while you edit. If something goes wrong, you can fix it from there.

Warning: A broken sudoers file can lock every user out of sudo. Keep a root shell open until you have tested your change from a fresh login. If you do get locked out, the browser console in your VPS provider's control panel gives you root access to repair it.

Why you must use visudo

Never open /etc/sudoers directly in nano or vim. visudo does three things a plain editor does not:

  • It locks the file so two people cannot edit it at once.
  • It edits a temporary copy.
  • It checks the syntax before saving. If there is an error, it tells you the line and asks what to do instead of saving a broken file.

Open the main file with:

Bash
sudo visudo

visudo uses the editor in $EDITOR or $SUDO_EDITOR, falling back to a default that may be vi. To use nano for one session:

Bash
sudo EDITOR=nano visudo

Read the sudoers syntax

A typical rule has this shape:

user  host = (run-as-user:run-as-group)  commands

For example, the line that gives root full rights:

root    ALL=(ALL:ALL) ALL
  • root: who the rule applies to.
  • First ALL: on any host. On a single server this is always ALL.
  • (ALL:ALL): they may run commands as any user and any group.
  • Last ALL: they may run any command.

Rules for a group start with %. The default admin rule on Ubuntu and Debian is:

%sudo   ALL=(ALL:ALL) ALL

On AlmaLinux and Rocky it is:

%wheel  ALL=(ALL)       ALL

Lines starting with # are comments, except #include and #includedir, which are directives. Newer sudo versions also accept @includedir.

Note: When several rules match a user, the last matching rule wins. Put specific exceptions after general rules.

Use drop-in files in /etc/sudoers.d

The main file ends with a line that loads every file in /etc/sudoers.d/:

@includedir /etc/sudoers.d

Older releases write it as #includedir /etc/sudoers.d. It is not a comment. Leave it in place.

Putting your own rules in separate files is cleaner than editing the main file. Package updates will not overwrite them, and you can remove one rule by deleting one file. Create a drop-in with:

Bash
sudo visudo -f /etc/sudoers.d/deploy

File names in this folder must not contain a dot or end with ~, or sudo ignores them. Use names like deploy or 90-webteam, not deploy.conf.

Common rules

Full sudo for one user

deploy  ALL=(ALL:ALL) ALL

Usually it is simpler to add the user to the sudo or wheel group instead. See Add a user to a group in Linux.

Limited sudo for one user

Allow only restarting and checking one service. Always use full paths:

deploy  ALL=(root) /usr/bin/systemctl restart nginx, /usr/bin/systemctl status nginx

Find the full path of a command with command -v systemctl. More patterns are in Give a user sudo access to specific commands only.

Run commands as another user

Let deploy run anything as the app user webapp, but not as root:

deploy  ALL=(webapp) ALL

The user then runs sudo -u webapp <command>.

Aliases

Aliases give names to lists and keep large files readable. Names must be in capitals:

User_Alias  WEBTEAM = anna, deploy
Cmnd_Alias  WEBCTL  = /usr/bin/systemctl restart nginx, /usr/bin/systemctl reload nginx
WEBTEAM ALL=(root) WEBCTL

Change a default

Defaults lines change sudo's behaviour. For example, ask for the password again after 5 minutes instead of the default:

Defaults timestamp_timeout=5

Check a file without opening it

Validate all sudoers files at once:

Bash
sudo visudo -c
/etc/sudoers: parsed OK
/etc/sudoers.d/deploy: parsed OK

Drop-in files should be owned by root with mode 0440. visudo -f sets this for you. If you copied a file in another way, fix it:

Bash
sudo chown root:root /etc/sudoers.d/deploy
sudo chmod 0440 /etc/sudoers.d/deploy

Check it works

From a new login as the affected user, list what they may run:

Bash
sudo -l

The output ends with the rules that apply, for example (root) /usr/bin/systemctl restart nginx. Then try one allowed and one blocked command to confirm the rule behaves as you expect. Only close your root session after this works.

Troubleshooting

  • "syntax error near line 30" after saving: visudo caught a mistake. Press e to edit again, or x to exit without saving. Do not choose Q, which saves the broken file.
  • "deploy is not in the sudoers file": no rule matches the user. Add them to the admin group or create a drop-in. See Fix "user is not in the sudoers file".
  • Your drop-in rule is ignored: the file name contains a dot, or a later rule overrides it. Rename the file and check with sudo -l.
  • sudo is broken for everyone: log in as root through your VPS provider's browser console and run visudo to fix the faulty line.

Next steps

Was this guide helpful?

Still stuck?

Ask MdmHost AI for a quick answer, or open a ticket and our team will take a look. We are here 24/7.