I have an Apache webserver. I have some PHP scripts on it. Scripts are run as the user www-data - it is as the user that runs Apache. I want to configure Apache so that PHP scripts are run with permissions of the owner of the script. In the past I could use suphp, but now it is orphaned and dead upstream, so Debian decided to remove it ( why I don't have suphp in debian testing ). In this situation, what should I use instead? Is there any not dead Apache module doing the same?


I have not used PHP, but I've used FastCGI to accomplish a similar thing with other lanaguages, and that's the approach I'd recommend, especially since php 5.3.3 and newer has an implementation built in, PHP-FPM. You can find documentation on how to use this on the official PHP website: FastCGI Process Manager (FPM).

This has many features, but the most relevant is that workers can have different user and group ids (and different php.inis, for that matter).


You can't. Apache runs under a low-privilege account — typically called apache or httpd — on purpose. The only way Apache could be configured as you propose is if it ran as root, which would make Apache a massive security risk.

You will have to use the OS's suid bit bit feature to get the effect you want.

You don't say which OS you're using; it matters.

Some OSes know how to run scripts (meaning anything with a shebang line at the top in this context) with the suid bit set, securely. This includes modern BSDs and some SVR4 variants.

In that case, the solution is simple. First move the commands that need to run as another user to a separate script with a PHP shebang line at the top:

your commands here

Then set it to run as the other user:

$ sudo chown otheruser myscript.php
$ sudo chmod u+s otheruser myscript.php

If you're running Linux, there's an excellent chance that the OS blocks suid scripts. You may find references to workarounds like perl -wT, but some OSes or configuration modes on those OSes block that, too. This is not the place to catalog all of the workarounds and all of the ways those workarounds can be blocked. Suffice it to say, if your OS doesn't specifically have a core feature that allows secure execution of suid scripts, you can't do it.

The standard solution is to create a suid wrapper in C, like this:

int main(int argc, char* argv[])
     execv("/full/path/to/my-script.php", argv);

Then execute these commands in this order to build the wrapper and set its permissions to allow it to run as the other user:

$ make my-script-wrapper
$ sudo chown otheruser my-script-wrapper
$ sudo chmod u+s my-script-wrapper

(Order matters because every time a file with the suid bit is changed, most OSes will clear the suid bit. There is no alternate ordering of those three commands that will do what you want.)

Now when you run my-script-wrapper, it will run as otheruser, so that when it launches my-script.php, that script will run with the privileges of otheruser.

The wrapper is intentionally extremely simple, so as to avoid introducing security flaws. I can think of several ways to make it more complicated and useful, but beware that this buys you a whole pile of problems.

You might just want to use sudo instead. It can be configured to run a script as some user other than root, and to skip the need for a password.

  • Will it work? I thought that suid does not work on scripts (executable files with shebang). – user983447 Jul 2 '15 at 18:58
  • @user983447: It may, or it may not. That depends on your OS and how it is configured, which you haven't specified. ("Debian" isn't nearly enough information to answer the question.) I've added some alternatives to the original solution that will work on any Unix or Unix-like OS. – Warren Young Jul 2 '15 at 20:13
  • 1. Apache has to at least start as root to bind to port 80, in the absence of other fancy configuration. It can do some basic startup tasks and the drop privs. 2. There are actually a number of ways this can be done which are arguably better than the setuid script approach. – mattdm Jul 2 '15 at 20:23
  • @mattdm: 1. I obviously didn't mean "run briefly as root, then drop privileges" when I said "run as root." I meant "run continuously as root, so as to be able to call setuid() on scripts to run them as other users. 2. I gave two of those alternatives: C wrapper and sudo. – Warren Young Jul 2 '15 at 20:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.