Allow Apache to run a command as a different user

29,459

Solution 1

Finally got it working with this line :

www-data ALL=(ALL) NOPASSWD: /usr/bin/sudo -u user /home/user/bin/script.sh

Since I needed arguments to my script, I had to add a "shell-style wildcard" at the end of the line :

www-data ALL=(ALL) NOPASSWD: /usr/bin/sudo -u user /home/user/bin/script.sh [[\:alpha\:]]*

It's not exactly what I was looking for, but it works (ie. it happens that my arguments start with alphabetic characters, but in fact I would like the expression to match only alphanumeric characters, dashes and periods).

I'm not at all familiar with shell wildcards and POSIX character classes, the one I use is basically copy-pasted from the sudoers manual. Anyone who knows how these apply to this kind of problem, please leave your comments !

Solution 2

Why are you running su inside sudo? (or worse, sudo inside sudo)

www-data ALL=(user) NOPASSWD: /bin/bash /home/user/bin/script.sh

This should work.

Solution 3

If it weren't a script, you could've just suid'd the executable, and set the group & permissions so only the webserver could execute it.

You can also use suExec (apache only) or CGIWrap (any webserver) to run CGIs under other users. There's also suPHP specifically for PHP in non-CGI mode on Apache.

They offer slightly different options (eg, CGIwrap can set resource limits), but in general, they'll run programs as alternate users.

Solution 4

I've made a different approach to this, to allow the apache user to sudo to a specified user that can then run all commands (or you can specify a list if you only need one or a few.

APACHEUSER        ALL=(USERNAME)        ALL
Defaults:APACHEUSER       targetpw
Defaults:APACHEUSER             !requiretty

this allows the password to be sent from code (eg read from database) using :

echo password | sudo -u username -S bash -c command_here arguments_here

Just make sure you use a dedicated user for this, and don't put that user in the wheel group.

see also here

geert

Share:
29,459

Related videos on Youtube

Andrei
Author by

Andrei

Updated on September 17, 2022

Comments

  • Andrei
    Andrei almost 2 years

    I have a script that executes several commands in a user's home directory. The files are owned by the user and Apache (the www-data group) only has read privileges to them. The script needs to be executed on demand by PHP via exec(), and performs some deletions / untarring of files, which fail since Apache doesn't have write permissions to the directories.

    I've tried editing the sudoers file like this :

    www-data ALL=(user) NOPASSWD: /bin/su user -c /home/user/bin/script.sh
    

    but it prompts me for the user's password

    I've also tried

    www-data ALL=(root) NOPASSWD: /usr/bin/sudo su user -c /home/user/bin/script.sh
    

    but that prompts for www-data's sudo password

    How to I get this to work without a password ?

  • Andrei
    Andrei almost 14 years
    I've tried your solution before and the script is still being run by www-data, that's why I thought of using sudo su user to switch the user before running the script...
  • joschi
    joschi almost 14 years
    Read man sudo and take a look at the parameter -u.
  • Andrei
    Andrei almost 14 years
    Thanks ! I've managed to get it working by adding this line to the sudoers file : www-data ALL=(ALL) NOPASSWD: /usr/bin/sudo -u user /home/user/bin/script.sh However, it doesn't work with arguments, and my script uses arguments...
  • Andrei
    Andrei almost 14 years
    Nevermind, found the solution here : gratisoft.us/sudo/sudoers.man.html
  • joschi
    joschi almost 14 years
    Ehm, running sudo in sudo is kind of fail. Why not call sudo -u $USER /home/user/bin/script.sh in the first place?
  • Andrei
    Andrei almost 14 years
    Well, that's what I'm doing, right ? : www-data ALL=(ALL) NOPASSWD: /usr/bin/sudo -u user /home/user/bin/script.sh
  • Joe H.
    Joe H. almost 14 years
    @Andrei : For one script at a time, sudo should be fine, so long as you're only limiting it to a script with a fixed set of arguments and running it as a non-root user; the ones I mentioned are useful for when you've got a collection of scripts that all need to run as a single user, eg. installing something you've downlaoded and you don't want to open up everything to the webserver user. They're also useful for multi-user systems, so each user can install CGIs but can't mess with each other's scripts.
  • Andrei
    Andrei almost 14 years
    Thanks for this explanation ! I'm running this script on a dedicated server, my main concern is to keep www-data doing what's is supposed to be doing (reading some files, and writing only in some directories). I'm still having trouble with the shell wildcards required to enable arguments for commands in sudoers though...(see below)
  • Joe H.
    Joe H. almost 14 years
    @Andrei : any of the solutions I mentioned should keep you from having to deal with the issue of arguments. You might also be able to allow the script to take any argument, and then do the argument checking in the script rather than the sudoers file.