A Simpler Introduction to Sudoers Files
Despite editing simple sudoers files for over 15 years, I still don't get the basics, each time resorting to ready-to-use examples. Time to change that.
1 Ramblings
I can still remember as if it were yesterday the first time I read the sudoers man page, eager to find a quick answer to some questions I had. But as I skimmed through it and reached the Sudoers File Format section, my heart sank when the author first wanted me to learn how to read EBNF before getting to understand how to write a portion of sudoers file.
Young and impatient as I was, I couldn't be bothered to learn about something I'd never asked for just to learn that thing I was aching to know about. So I just left it at that, decided that I didn't need to write sudoers files anyway and went about doing something else instead.
Today, years of wisdom later, as I'm painstakingly learning about the virtues of patience and humility, I'm stumbling upon the same questions about how to write a sudoers file. First I Google it up, not finding any hit that really answers my questions, and then I decide that maybe the time has come for me to display that diligence I ought to show, do my EBNF and just read the sudoers man page which, in honest truth, is an example of writing man pages to follow. And write this short guide I would have wanted to have 15 years ago.
2 A Word of Caution: Use Visudo
I was rather pleased when I discovered that one didn't have to directly edit /etc/sudoers
but could organise sudoers specifications in separated files under the /etc/sudoers.d/
directory. What I naively believed for some reason though, is that I didn't have to worry too much about errors in those files and therefore I tended not to use visudo. How foolish of me! Syntax correctness for files under the /etc/sudoers.d/
directory is just as critical. So use visudo -f
before you start experimenting and lock yourself out.
3 A Started Guide to Sudoers Files
I'm not going to present things the EBNF way, nor am I going to discuss aliases which simple needs don't require. Let's cut to the chase and talk about what most people need: allow certain users to do some things, optionally without bothering them with passwords. What we call User Specifications. You'll get to write stuff along the lines of:
alice, bob, carol foo.example.com, bar.example.com = NOPASSWD: /usr/bin/corge, /usr/bin/grault
- The
alice, bob, carol
part is a comma-separated list of e.g. usernames, groups or aliases thereof. - The
foo.example.com, bar.example.com
part is a comma-separated list of e.g. hostnames, IP addresses or aliases thereof. Now you might be wondering why on earth you'd even want to specify this, why you'd wish to have something else than your own host's name here. Think distributed computing: imagine one sudoers file on a network file system which multiple servers access, or one sudoers file deployed on multiple servers. - The optional
NOPASSWD:
part is a tag. Tags can be many things, and this one has sudo not ask for a password. - The
/usr/bin/corge, /usr/bin/grault
part is a comma-separated list of e.g. commands, with or without arguments, directories, or aliases thereof.
Note the existence of the ALL
alias which applies to users, hosts, commands. Type ALL ALL = NOPASSWD: ALL
and it's party time for hackers, as you would expect.
You'll come across many examples on teh interwebs also including the optional run-as part between parenthesis (with the occasional colon) right after the =
sign and before the tags. What's before the colon are acceptable users to run commands on behalf of, what's after the colon are acceptable groups to run commands on behalf of. Omitting both users and groups, i.e. specifying (:)
or ()
means you can only run the command on behalf of yourself. And omitting the run-as part altogether as we've previously done means you can run the command as root, which is probably what you want most of the time. That's why I didn't particularly suggest using it here.