sudo runs one command as another user, normally root, after checking that you are allowed to. The point is not convenience — it is that nobody needs to know the root password, every privileged action is attributable to a person, and permissions can be granted narrowly rather than all at once.
sudo and su are different
sudo | su | |
|---|---|---|
| Password asked for | Yours | The target user’s |
| Scope | One command | A whole shell |
| Logged | Every invocation | Only the switch |
| Granularity | Per user, per command | All or nothing |
That is why most distributions now ship with the root password locked and administration done through sudo. If three people administer a server, sudo means three revocable grants and an audit trail, instead of one shared secret that has to be changed whenever anyone leaves.
Everyday use
sudo systemctl restart nginx # one command as root
sudo -u www-data ls /var/www # as a specific user
sudo -i # a root login shell
sudo -s # a root shell, keeping your environment
sudo -l # what am I allowed to run
sudo -k # forget the cached authentication
sudo !! # re-run the previous command with sudosudo !! is the one you will use ten times a day, and sudo -l is the one worth knowing when you land on an unfamiliar machine — it prints exactly what your account may do.
After a successful authentication, sudo remembers you for a while — fifteen minutes by default, per terminal. That is why the password prompt seems to appear unpredictably.
The redirection trap
sudo echo "127.0.0.1 test" >> /etc/hosts
bash: /etc/hosts: Permission deniedThis surprises everyone once. The shell sets up the redirection before sudo runs anything, so the file is opened by your shell, as you, without privileges. sudo elevated echo — which was never the part that needed elevating.
# Append
echo "127.0.0.1 test" | sudo tee -a /etc/hosts
# Overwrite
echo "contents" | sudo tee /etc/motd
# Discard the echoed output
echo "contents" | sudo tee /etc/motd > /dev/null
# Or elevate the whole shell command
sudo sh -c 'echo "127.0.0.1 test" >> /etc/hosts'The same logic explains why sudo cmd1 | cmd2 only elevates cmd1, and why a shell glob like sudo cp /root/* fails — the shell expands it as you, before sudo is involved.
Editing sudoers
Never open /etc/sudoers in an editor directly. A syntax error in that file can lock every administrator out of privilege escalation on the machine, and if the root account is disabled you may have no way back in short of a rescue boot.
sudo visudo # edits with a syntax check before saving
sudo visudo -f /etc/sudoers.d/deploy # a drop-in file, same protection
sudo visudo -c # check the current configurationvisudo validates the file and refuses to install a broken one. Prefer drop-in files under /etc/sudoers.d/ to editing the main file: they survive package upgrades, and one bad file is easier to remove than a mangled sudoers.
Keep a second root session open while changing sudo configuration, exactly as with sshd. Test in the new terminal; if it went wrong, fix it in the old one.
The syntax
kevin ALL=(ALL:ALL) ALL
│ │ │ └─ which commands
│ │ └────────── which users:groups they may become
│ └─────────────── on which hosts
└─────────────────────── who# Everyone in a group gets full rights
%sudo ALL=(ALL:ALL) ALL # Debian, Ubuntu
%wheel ALL=(ALL) ALL # Fedora, RHEL, Arch
# One user, two specific commands, no password
deploy ALL=(ALL) NOPASSWD: /bin/systemctl restart myapp, /bin/systemctl status myapp
# Run as a particular user rather than root
kevin ALL=(www-data) /usr/bin/phpThe group is the normal way in. On Debian and Ubuntu that is sudo; on Fedora, RHEL and Arch it is wheel. Adding someone is usually all you need:
sudo usermod -aG sudo kevin # Debian, Ubuntu<br>sudo usermod -aG wheel kevin # Fedora, RHEL, ArchThe -a matters enormously. Without it, usermod -G replaces every secondary group the user has rather than adding one, which is a memorable way to remove your own access.
Group membership applies at login, so the user must log out and back in before it takes effect.
Restricting commands is harder than it looks
A rule like deploy ALL=(ALL) NOPASSWD: /usr/bin/vim looks like it grants a little. It grants everything: many programs can launch a shell from inside themselves, and a shell launched by a root process is a root shell. Editors, pagers, and anything with a scripting feature all fall into this category — vim, less, find, awk, tar, package managers, and language interpreters among them.
The rule of thumb: grant a specific command with specific arguments, and prefer commands that do exactly one thing. Allowing systemctl restart myapp is defensible. Allowing systemctl with any arguments is much less so, and allowing an editor is equivalent to granting full root.
Where someone genuinely needs to edit a file as root, sudoedit exists for exactly that: it copies the file, runs your normal unprivileged editor on the copy, and writes it back with privileges.
kevin ALL=(ALL) sudoedit /etc/nginx/nginx.confNOPASSWD
NOPASSWD is necessary for automation — a deploy script cannot type a password. It is also the line most often written too broadly:
# Reasonable: one job, one command
deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl reload nginx
# Not reasonable: anyone who compromises this account owns the machine
deploy ALL=(ALL) NOPASSWD: ALLThe second form turns any weakness in that account — a leaked key, a vulnerable web application running as it — into immediate root. If you find it in a configuration you inherited, narrowing it is usually the highest-value security change available for the effort involved.
The environment
sudo deliberately builds a clean environment rather than passing yours through. Two consequences:
secure_pathoverridesPATH. A command in~/binor a version manager’s shims will not be found under sudo, even though it works normally. Use the full path.- Shell aliases and functions do not apply.
sudo llfails becausellis an alias your shell expands, and sudo never sees it.
sudo -E command # preserve your environment (use sparingly)
sudo env "PATH=$PATH" command # preserve just PATH
sudo printenv # see what the command actually gets-E is convenient and worth thinking about before using: passing your whole environment into a root process is precisely what env_reset exists to prevent.
Who did what
sudo journalctl -t sudo # systemd systems
sudo grep sudo /var/log/auth.log # Debian, Ubuntu
sudo grep sudo /var/log/secure # Fedora, RHEL
sudo journalctl _COMM=sudo --since todayEvery invocation is logged with the user, the working directory, the target user and the exact command line. This is the main practical benefit of sudo over a shared root password, and it is worth actually reading occasionally rather than only after something has gone wrong. See systemctl for more on journalctl.
Gotchas
“user is not in the sudoers file”
This incident will be reported — and it means exactly what it says. Either the account is not in the right group, or it was added and has not logged out since. Check with groups or id.
sudo su – is redundant
It works, but sudo -i does the same thing more directly and is what the tool intends. Nothing breaks either way; it is just a habit worth updating.
Files created as root belong to root
Run a build or a package install with sudo in your home directory and you will find files you can no longer write. sudo chown -R $USER:$USER . puts it right — see file permissions. Better still, do not use sudo for things that do not need it.
The lecture, and the timeout
Both are configurable in sudoers — Defaults lecture=never, and Defaults timestamp_timeout=30 for a longer or shorter cache. Setting the timeout to -1 means it never expires, which quietly removes a useful safety property on a shared machine.
Quick reference
sudo command # as root
sudo -u user command # as someone else
sudo -i # root login shell
sudo -l # what am I allowed to do
sudo !! # repeat the last command with sudo
sudo -k # forget the cached password
echo x | sudo tee -a /etc/file # redirect into a root-owned file
sudo sh -c 'cmd > /etc/file' # the alternative
sudo visudo # the only safe way to edit sudoers
sudo visudo -f /etc/sudoers.d/x # a drop-in
sudo visudo -c # validate
sudoedit /etc/file # edit as root with your own editor
sudo usermod -aG sudo alice # grant (Debian) — note the -a
sudo usermod -aG wheel alice # grant (RHEL, Arch)
sudo journalctl -t sudo # who ran whatRelated
- File permissions — what root can do, and why files created under sudo cause trouble.
- ssh — disabling root login and relying on sudo instead.
- systemctl — the most common thing people are granted narrow sudo rights for.
- cron — scheduled jobs run as a user, which is often the better answer than NOPASSWD.
polkit— the desktop equivalent, behind graphical authentication prompts.
