49

How do I specify command arguments in sudoers? As a background, aws command is actually a gateway to a whole bunch of sub-systems and I want to restrict the user to only run aws s3 cp ...any other args...

When I try the following in /etc/sudoers

Cmnd_Alias AWSS3_CMD = /usr/local/bin/aws s3 cp, /usr/local/aws/bin/aws s3 cp
gbt1 ALL=(gbt-ops) NOPASSWD: AWSS3_CMD

The shell unfortunately prompts for password

$ sudo -u gbt-ops aws s3 cp helloworld s3://my-bucket/hw.1
gbt-ops's password:

If I remove the command args in Cmnd_Alias, then it flows as desired (without password prompt), but the authorization are way too broad. So, what is the right way of restricting to only certain types of command invocations.

Cmnd_Alias AWSS3_CMD = /usr/local/bin/aws, /usr/local/aws/bin/aws

Then

$ sudo -u gbt-ops aws s3 cp helloworld s3://my-bucket/hw.1
...happy

Thanks a lot.

muru
  • 72,889
Dinesh
  • 1,291

4 Answers4

58

You haven't used any wildcards, but have provided two arguments. Therefore sudo looks for commands exactly as written (excepting path-lookup) (from man 5 sudoers):

 If a Cmnd has associated command line arguments, then the arguments in
 the Cmnd must match exactly those given by the user on the command line
 (or match the wildcards if there are any).

Try something like:

Cmnd_Alias AWSS3_CMD = /usr/local/bin/aws s3 cp *, /usr/local/aws/bin/aws s3 cp *

Note that:

 Wildcards in command line arguments should be used with care.  Because
 command line arguments are matched as a single, concatenated string, a
 wildcard such as ‘?’ or ‘*’ can match multiple words. 

So, only one wildcard is needed per command.

muru
  • 72,889
  • 2
    Note that sudo doesn't properly respect separation of arguments which can be used for exploits in some cases, see https://unix.stackexchange.com/a/279142/43920. So instead of specifying /usr/local/bin/aws s3 cp in sudoers, it is safer to replace that with a script (only writable by root). – pcworld Dec 07 '17 at 00:42
12

The same as @muru, but for those who like full working example:

# Cmnd alias specification
Cmnd_Alias ECHO_CMD=/bin/echo A *,/bin/echo B *

# Make USER run specific commands on given HOSTNAME
# USER_NAME 

#userx
userx ALL=(root) NOPASSWD: /sbin/cmd1,/sbin/cmd2,ECHO_CMD

While /sbin/cmd1,/sbin/cmd2 can be any other commands.

The purpose of ECHO_CMD is to present that sudo echo X A will ask for passphrase, while sudo echo A X not, and to allow you to gain confidence through such simple experiment.

(It was assumed that echo sits in /bin/echo, to check where it is on your system try whereis echo)

  • Yes, there is /bin/echo binary, but most shells also have built-in function echo which will be used instead of this binary if you don't provide full path. – Marki555 Jun 18 '19 at 12:24
1

you can use regexp in sudoers too.

this will allow /usr/bin/apt update upgrade and auto-remove to be run without password but if you specify a .deb name or apt install it will still prompt for password.

Cmnd_Alias UPDATES = /usr/bin/apt (update|upgrade|auto-remove)
%sudo ALL=(ALL:ALL) NOPASSWD: UPDATES
%sudo ALL=(ALL:ALL) ALL
stoggy
  • 236
  • 1
    Important caveat: this requires at least sudo 1.9.10, so taking Ubuntu for example, 20.04 and 22.04 are out. – muru Nov 19 '23 at 01:57
  • @muru, wow even the latest LTS haven't get this feature yet. This would save a lot of repetitive configuration. – annahri Feb 16 '24 at 02:50
0

I know this is old but lets say that this is cat instead of echo and there is a file C that a user doesn't have access to. You add the user to sudoers which allows:

# Cmnd alias specification
Cmnd_Alias ECHO_CMD=cat A *,cat B *

I would then have access to file C by running:

sudo echo A C

since C follows the wildcard syntax properly. I think this is a good example of bad security when using wildcards in sudo commands. I would be very careful with this usage and account for any possible variation the wildcard could produce!

AdminBee
  • 22,803