Configuring sudo Access (sudoers)
On a Linux server you rarely want people logging in as root (the all-powerful administrator account). Instead you give normal users permission to run some commands with admin rights using sudo (“superuser do”). The rules that decide who can run what live in a file called the sudoers file. Getting these rules right is one of the most important security jobs on any Ubuntu server, because a sloppy rule can hand an attacker full control of the machine.
This page explains where those rules live, why you must edit them with a special tool called visudo, and how to grant a user or group exactly the access they need and nothing more.
What is the sudoers file?
The sudoers file is a plain-text configuration file that tells the sudo command which users and groups are allowed to run privileged commands. There are two places it lives on Ubuntu 22.04 / 24.04 LTS:
| Location | What it is | When to use it |
|---|---|---|
/etc/sudoers | The main file, shipped with the system | Almost never edit directly — leave it as-is |
/etc/sudoers.d/ | A directory of small “drop-in” files | Preferred: add one file per rule or per team |
The main /etc/sudoers file contains a line, @includedir /etc/sudoers.d, which means it automatically reads every file inside that directory. Putting your own rules in /etc/sudoers.d/ keeps them separate and survives system upgrades cleanly, so that is the modern best practice.
Each file in
/etc/sudoers.d/must have permissions0440(read-only for owner and group, no access for others). If the permissions are wrong,sudosilently ignores the file. Tools likevisudoset this for you automatically.
Why you MUST use visudo
A single typo in the sudoers file can lock everyone out of admin access — including you. There is no “undo”, and you may not be able to fix it because fixing it requires sudo. That is why you never open this file in a plain editor like nano directly.
Instead you use visudo, a wrapper that checks the syntax before saving. If you make a mistake, it refuses to save the broken file and lets you fix it. Think of it as a spell-checker that prevents you from bricking your own access.
To edit the main file:
sudo visudo
To create or edit a drop-in file (recommended), point visudo at a file inside /etc/sudoers.d/:
sudo visudo -f /etc/sudoers.d/deploy
By default visudo opens the system editor. On Ubuntu that is usually nano. If you ever see vi and prefer nano, set it for one session:
sudo EDITOR=nano visudo
When you save and exit, visudo validates the file. A good save prints nothing. A broken file looks like this:
Output:
>>> /etc/sudoers.d/deploy: syntax error near line 2 <<<
What now?
Options are:
(e)dit sudoers file again
e(x)it without saving changes to sudoers file
(Q)uit and save changes to sudoers file (DANGER!)
Always choose e to fix it. Never choose Q unless you know exactly why.
Understanding a sudoers rule
A typical rule has four parts:
user host = (runas) commands
For example:
deploy ALL=(ALL:ALL) ALL
deploy— the user the rule applies to.ALL(the host part) — which machines the rule applies to. On a single server, leave it asALL.(ALL:ALL)— which user and groupdeploymay run commands as.(ALL:ALL)means any user, includingroot.ALL(the commands part) — which commands are allowed.ALLmeans every command.
So the line above gives deploy full admin rights. That is the most common rule, but also the most powerful — only give it to trusted administrators.
Granting a user specific commands
Most of the time you do not want to give someone every command. The whole point of sudoers is to grant the minimum needed. To let the user webops only restart Nginx (a popular web server) and view logs, create a drop-in file:
sudo visudo -f /etc/sudoers.d/webops
Add these lines:
# webops may manage Nginx and read logs, nothing else
webops ALL=(root) /usr/bin/systemctl restart nginx, /usr/bin/systemctl status nginx
webops ALL=(root) /usr/bin/journalctl -u nginx*
Now webops can run those exact commands with sudo, but sudo apt install or sudo rm will be denied. Always use the full path to each command (find it with which systemctl); a bare command name can be bypassed by an attacker.
Granting access to a group
If you have a team, manage access by group instead of listing every person. On Ubuntu, members of the sudo group already get full admin rights. To add a user to it:
sudo usermod -aG sudo alice
You can also write rules for a custom group by prefixing the group name with %:
# everyone in the "deployers" group may run the deploy script as root
%deployers ALL=(root) /opt/app/deploy.sh
Passwordless sudo for automated deploys
By default sudo asks for the user’s password. That is a problem for automation — a deploy script or CI/CD pipeline (a tool that builds and ships your code automatically) cannot type a password. The NOPASSWD tag removes the prompt:
sudo visudo -f /etc/sudoers.d/ci-deploy
# CI runs ONLY this one script as root, no password required
ci ALL=(root) NOPASSWD: /opt/app/deploy.sh
Security warning:
NOPASSWDis dangerous. Anyone who gains access to theciaccount can run that command as root with no second barrier. Never combineNOPASSWDwithALL(e.g.ci ALL=(ALL) NOPASSWD: ALL) — that turns a single compromised key into total server takeover. Scope it to one specific, full-path command, and make that script non-writable by theciuser (sudo chown root:root /opt/app/deploy.sh && sudo chmod 755 /opt/app/deploy.sh).
When to use passwordless sudo (and when not)
| Use NOPASSWD when | Avoid NOPASSWD when |
|---|---|
| A CI/CD service account runs one fixed command | A human administrator logs in interactively |
| The command is a single, root-owned, read-only script | The rule would allow ALL or a shell |
| You can’t supply a password (automation) | The account’s keys are shared or weakly protected |
Checking what a user is allowed to do
To see the rules that apply to the current user without editing anything:
sudo -l
Output:
User webops may run the following commands on web01:
(root) /usr/bin/systemctl restart nginx
(root) /usr/bin/journalctl -u nginx*
This is the fastest way to confirm a rule works before you rely on it.
Best practices
- Always edit through
visudo(orvisudo -f) so syntax is checked before saving. - Put your rules in
/etc/sudoers.d/as small named files, not in/etc/sudoers. - Grant the fewest commands possible and always use full command paths.
- Prefer group rules (
%groupname) over per-user rules for teams. - Treat
NOPASSWDas a last resort, scoped to one root-owned command. - Run
sudo -lto verify access, and keep an extra admin session open while you test new rules so a mistake can’t lock you out.