Allow Apache to run a command as a different user
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
Related videos on Youtube
Andrei
Updated on September 17, 2022Comments
-
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 viaexec()
, 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
'ssudo
passwordHow to I get this to work without a password ?
-
Andrei almost 14 yearsI'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 almost 14 yearsRead
man sudo
and take a look at the parameter-u
. -
Andrei almost 14 yearsThanks ! 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 almost 14 yearsNevermind, found the solution here : gratisoft.us/sudo/sudoers.man.html
-
joschi almost 14 yearsEhm, running
sudo
insudo
is kind of fail. Why not callsudo -u $USER /home/user/bin/script.sh
in the first place? -
Andrei almost 14 yearsWell, that's what I'm doing, right ? :
www-data ALL=(ALL) NOPASSWD: /usr/bin/sudo -u user /home/user/bin/script.sh
-
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 almost 14 yearsThanks 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. 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.