SU Exec CGI a PHP skriptů

Apache multiuser MPM

Install apache2-mpm-itk package. Then you can set different users/groups in apache's sites-available. Nice bonus is that you can also set custom nice value and limit number of parallel clients for each site:

<IfModule mpm_itk_module> AssignUserID myusername www-data #MaxClientsVHost 10 #NiceValue 6 </IfModule>

Lighttpd

For lighttpd you can use CGI wrapper (you have to compile it by yourself). First enable mod_cgi and then assign .php to desired wrapper. Also be sure that you are not using mod_fastcgi (well… while not completely unreal, it's probably not easy or desirable to wrap fastcgi).

cgi.assign = ( #".pl" => "/usr/bin/perl", #".cgi" => "/usr/bin/perl", ".php" => "/usr/local/bin/php-cgi-su", )

CGI SU Exec wrapper code

Source: https://github.com/Harvie/Programs/tree/master/c

/* * SU-EXEC Wrapper * Execute script under it's owner's privileges * CopyLefted by: Harvie 2oo9 */ #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <pwd.h> #include <grp.h> #define INTERPRETER "/usr/bin/php-cgi" //#define INTERPRETER "/usr/bin/perl" void auth_fail() { puts("Error: Permission denied!\n"); exit(-1); } int main(int argc, char **argv, char **environ) { if(argc != 2) { //Do not accept more than one argument printf( "SetUID wrapper for %s interpretter\n" "Usage: %s script\n\n", INTERPRETER, argv[0] ); return -1; } struct stat st; if(!stat(argv[1], &st)) { //Get user info struct passwd *pw; if(!(pw = getpwuid(st.st_uid))) auth_fail(); //Change groups if(initgroups(pw->pw_name, pw->pw_gid)) auth_fail(); //Change UID a GID if(setgid(pw->pw_gid)) auth_fail(); if(setegid(pw->pw_gid)) auth_fail(); if(setuid(pw->pw_uid)) auth_fail(); if(seteuid(pw->pw_uid)) auth_fail(); //Fail if still have root privileges if(getuid() == 0 || getgid() == 0) auth_fail(); //Launch binary return(execve(INTERPRETER, argv, environ)); } else { printf("Error: Can't stat file: %s\n\n", argv[1]); return -1; } }