How to Restrict a User’s sudo Rights to Only Specific Commands

The Task

I have a situation on a CentOS server where I need to grant one low privileged user account the ability to run a single command as root. Here’s how I did it:

Enter visudo and the sudoers File

This probably deserves its own post, but for now let it suffice to know that if you are editing the sudoers file, you need to use visudo. It checks your syntax before saving the file which will prevent you from swearing like a drunken stevedore in between hysterical crying fits.

Run visudo as root and scroll down to the section that assigned rights to user accounts. You’ll almost certainly see see a line that says

root ALL=(ALL) ALL

That’s the beginning of the section that we’re interested in. But, what does that even mean? Let’s talk about that before we edit anything.

The syntax for the user lines in the sudoers file follows this syntax:

who host=(accounts) commands

Broken down, that means:

  • who: the account that is having its ability to use sudo privileges modified
  • host: the system that the account is able to run these sudo commands on (the sudoers file can be shared across multiple computers, so that’s when this would come into play)
  • accounts: what other accounts on the machine the user running sudo can act as
  • commands: the commands that the account represented by who can run as sudo

That means root ALL=(ALL) ALL is broken down thusly: The root account can use sudo on all computers that have this sudoers file and assume the identity of any of the accounts on those machines to perform any command that is available on them.

There are a few other additional options that can be placed on the line to further define each user’s sudo privileges. I won’t go into detail about those options (mostly because I just learned about them the other day and I’m still clueless), but you can read much more about the whole thing using its man pages.

The specific option that I’m interested in is the NOPASSWD option. You see, I need to call sudo to run a specific command as root within a script and not be prompted for a password. In that case, I place the NOPASSWD option just before the commands that I want use as root without a password. It would look something like this:

backupuser ALL=(ALL) NOPASSWD: /usr/bin/backuptool

And that is how I restricted an account’s ability to use one single command as root using sudo without a password. Any thoughts? Caveats? The sudoers file is a behemoth invention that can do quite a few different things. Let me know your ideas below.

10 Comments

  1. Erik

    April 11, 2012 at 7:59 am

    Many people (especially beginners) will probably be scared to find them selves in vi for the first time when you use stuff like vipw or visudo.

    One handy trick here is to set the EDITOR enviroment variable to something that you prefer.

    So – for the ultra beginners:
    # export EDITOR=nano
    # visudo

    Reply

    • Wesley David

      April 11, 2012 at 12:59 pm

      vi is everyone’s friend. It’s here to help you…

      Reply

  2. furicle

    April 11, 2012 at 8:12 am

    It can get complicated quickly, but I think for most people just a few simple items in there can save a world of headaches.

    Like you I’ve got a couple of backup scripts that normal users need to run (for me it’s while I’m on vacation). I actually tied them to bash .bash_profile so all they do is log in and voila, the backup runs as root without intervention.

    It’s handy to let nagios run SMART checks on the drives too.

    User Aliases and Command Aliases can prevent you having to type things over and over again – e.g.

    Cmnd_Alias OFFSITEBU = /usr/local/bin/syncOffsiteDrive
    User_Alias OFFSITEBUCREATORS = adam, bruce, cindy
    OFFSITEBUCREATORS ALL=NOPASSWD: OFFSITEBU

    Reply

    • Wesley David

      April 11, 2012 at 12:56 pm

      There is so much around the topic of the sudoers file, and also scoping commands, that an entire book should be written about it.

      Reply

  3. Michael Graziano

    April 11, 2012 at 8:25 am

    A few caveats – two that don’t affect you:

    Caveat #1: backupuser probably doesn’t need to be able to run backuptool as any user on the system – I’d restrict it to root (or another account with appropriate privileges if root would be overkill). Doesn’t really matter for backups, as you probably want to run it as root, and at that point any added security of the user restriction is wiped out anyway.

    Caveat #2: Command specifications can include wildcards (even though yours didn’t). For people who set sudo up this way, this Is Probably Not What You Want. The Right Thing is to specify individual commands explicitly as you did here.

    …and two that do affect you:

    Caveat #3: You can pass any argument to a command. Giving John Doe the right to run rm so he can clean up some dump directory also gives him the right to run “rm -rf /vmunix” — Use wrapper scripts extensively.

    Caveat #3a: Your wrapper scripts run with whatever elevated privileges you specify in sudoers. Make sure they’re secure, because someone will one day pass them really heinous parameters.

    Presumably `backuptool` is a wrapper script that prevents someone from doing something crazy like restoring last week’s /etc/motd over the current /vmunix, but if not a little paranoia goes a long way…

    Reply

    • Wesley David

      April 11, 2012 at 12:58 pm

      C1 - Pertinent and noted.

      C3 - I lurved the ability to restrict arguments when I found that. My eyes lit up like it was Christmas morning and I heard my dad drop a heavy present on his foot.

      C3a – Presumably `backuptool`is a wrapper script. Yeah… it’s a wrapper script… that’s it… it’s just a wrapper…

      Reply

  4. Jason Wellband

    April 13, 2012 at 3:28 pm

    Use aliases for everything :) It makes you file more behmoth, but it makes it a lot easier to extend access (e.g. give Alice the same access that Bob has; add a command for Alice and Bob)

    You can also negate commands to. We do something like this at work (going from memory):

    Cmnd_Alias SU=/bin/su
    Cmnd_Alias SHELLS=/bin/bash, /bin/ksh, /bin/tcsh, /bin/csh

    SOME_GROUP SOME_HOSTS=ALL !SU !SHELLS

    So in this case, SOME_GROUP could run anything on SOME_HOSTS-except- for a shell. This would prevent the user from easily becoming root. It’s not a panacea though – sudo vi, then :!su – would get you a root shell. If you care, arrange for their shell to use rvi instead of vi.

    You can even use system groups. It’s common to see something like this:

    @wheel ALL=ALL

    So anybody in the wheel group gets sudo :)

    Reply

    • Wesley David

      April 13, 2012 at 3:44 pm

      Clearly the sudoers file requires a book to itself to scratch the surface of its capabilities. Thanks for the tips!

      Reply

  5. [...] I explored how to limit a user’s ability to runs commands with sudo. As a tangential topic, I needed to restrict the commands that a user account had access to when [...]

    Reply

  6. Sudoers access to user

    September 19, 2013 at 7:24 am

    [...] restrict user to one command": http://answers.oreilly.com/topic/432…ons-with-sudo/ http://thenubbyadmin.com/2012/04/11/…ific-commands/ …with examples and [...]

    Reply

Leave a Reply

Follow TheNubbyAdmin!

follow us in feedly

Raw RSS Feed:

%d bloggers like this: