Skip to content
DevOps devops linux-admin 6 min read

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:

LocationWhat it isWhen to use it
/etc/sudoersThe main file, shipped with the systemAlmost never edit directly — leave it as-is
/etc/sudoers.d/A directory of small “drop-in” filesPreferred: 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 permissions 0440 (read-only for owner and group, no access for others). If the permissions are wrong, sudo silently ignores the file. Tools like visudo set 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 as ALL.
  • (ALL:ALL) — which user and group deploy may run commands as. (ALL:ALL) means any user, including root.
  • ALL (the commands part) — which commands are allowed. ALL means 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: NOPASSWD is dangerous. Anyone who gains access to the ci account can run that command as root with no second barrier. Never combine NOPASSWD with ALL (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 the ci user (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 whenAvoid NOPASSWD when
A CI/CD service account runs one fixed commandA human administrator logs in interactively
The command is a single, root-owned, read-only scriptThe 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 (or visudo -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 NOPASSWD as a last resort, scoped to one root-owned command.
  • Run sudo -l to verify access, and keep an extra admin session open while you test new rules so a mistake can’t lock you out.
Last updated June 15, 2026
Was this helpful?