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:
sudo visudovisudo uses the editor in $EDITOR or $SUDO_EDITOR, falling back to a default that may be vi. To use nano for one session:
sudo EDITOR=nano visudoRead the sudoers syntax
A typical rule has this shape:
user host = (run-as-user:run-as-group) commandsFor example, the line that gives root full rights:
root ALL=(ALL:ALL) ALLroot: who the rule applies to.- First
ALL: on any host. On a single server this is alwaysALL. (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) ALLOn AlmaLinux and Rocky it is:
%wheel ALL=(ALL) ALLLines 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.dOlder 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:
sudo visudo -f /etc/sudoers.d/deployFile 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) ALLUsually 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 nginxFind 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) ALLThe 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) WEBCTLChange 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=5Check a file without opening it
Validate all sudoers files at once:
sudo visudo -c/etc/sudoers: parsed OK
/etc/sudoers.d/deploy: parsed OKDrop-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:
sudo chown root:root /etc/sudoers.d/deploy
sudo chmod 0440 /etc/sudoers.d/deployCheck it works
From a new login as the affected user, list what they may run:
sudo -lThe 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:
visudocaught a mistake. Presseto edit again, orxto exit without saving. Do not chooseQ, 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
visudoto fix the faulty line.
Next steps
- Allow passwordless sudo for automation, carefully: Allow sudo without a password (NOPASSWD).
