You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@httpd.apache.org by Jonas Meurer <jo...@freesources.org> on 2018/04/23 13:40:30 UTC

[users@httpd] Re: mod_suexec with mod_userdir and fcgid (webapps in subdirs with separated user context)

Hello again,

maybe my previous mail was to verbose, or maybe simply nobody has an
idea. Still I'd like to give it a second try:

Do you have a good idea why php-cgi7.0 throws the following error when
used with mod_fcgid, mod_usermod and mod_suexec?

uid: (1002/webapp1) gid: (1002/webapp1) cmd: php-fcgi-starter cannot get
docroot information (/var/www/webapp1)

$ ls -al /var/www/webapp1
drwxr-xr-x 9 root root 4096 Jun 29  2014 .
drwxr-x---  2 webapp1 webapp1  4096 Nov  7 15:14 php-fcgi
drwxr-x---  2 webapp1 webapp1  4096 Apr 11  2015 www
[...]

The same setup works perfectly fine without mod_usermod (i.e. when the
whole VHost has a dedicated suexec user). Only with mod_usermod, we get
this strange error.

Cheers,
 jonas

Am 15.04.2018 um 12:26 schrieb Jonas Meurer:
> Hello list,
> 
> I try to make web applications available in subfolders of one
> VirtualHost, but each one in an isolated user context. All web apps are
> PHP applications and I use mod_fcgid to run them.
> 
> Unfortunately, SuexecUserGroup is not not allowed in Directory context,
> which would be by far the simples solution.
> 
> So to achieve my goal, I tried (and failed with) two different approaches:
> 
> 1. Using mod_userdir together with mod_suexec
> 2. ProxyPass to separate localhost vhosts for each app
> 
> Since the first approach seems much cleaner and more straight forward to
> me, I'd prefer that one.
> 
> Maybe you have other suggestions on how to achieve my goal?
> 
> ---
> 
> Now to the problem I ran into with my first approach:
> 
> I have UserDir enabled for system user 'webapp1' and the UserDir path
> set to '/var/www/*/www' (see the VirtualHost config below). This works
> as expected, I can access static content from within the UserDir.
> 
> Additionally, I have fcgid configured for the UserDir and apparently the
> php scripts are executed using suexec and php-cgi7.0. A suexec process
> is spawned by user 'webapp1' when requesting a php file, but it
> immediately turns into 'suexec <defunct>' (a zombie process).
> 
> In the apache2 error log shows:
> 
> uid: (1002/webapp1) gid: (1002/webapp1) cmd: php-fcgi-starter
> cannot get docroot information (/var/www/webapp1)
> 
> And the apache2 suexec log:
> 
> [fcgid:warn] [pid 30884:tid 140484201527040] (104)Connection reset by
> peer: [client 192.168.0.1:31937] mod_fcgid: error reading data from
> FastCGI server
> [core:error] [pid 30884:tid 140484201527040] [client 192.168.0.1:31937]
> End of script output before headers: index.php
> 
> 
> I double checked that all files under /var/www/webapp1 belong to
> user+group 'webapp1' and that they're accessible. I even recursively set
> world-readable permissions on the directory, which didn't change anything.
> 
> Do you have a good idea on why running php-cgi7.0 through fcgi with
> suexec and userdir results in this suexec error 'cannot get docroot
> information'?
> 
> Any hints and suggestions would be highly appreciated :)
> 
> The VirtualHost config (my current take) is as follows:
> 
> <VirtualHost *:443>
>     [...]
>     Userdir disabled
>     Userdir enabled webapp1
>     UserDir /var/www/*/www
> 
>     <IfModule fcgid_module>
>         <Directory /var/www/webapp1/www>
>             AddHandler fcgid-script .php
>             FCGIWrapper /var/www/webapp1/php-fcgi/php-fcgi-starter .php
>             Options +ExecCGI
>         </Directory>
> 
>         IPCConnectTimeout 20
>         IPCCommTimeout 60
>         FcgidBusyTimeout 60
>         MaxRequestLen 10485760
>     </IfModule>
> </VirtualHost>
> 
> 
> Looking forward to your responses.
> 
> Kind regards,
>  jonas
> 



Re: [users@httpd] Re: mod_suexec with mod_userdir and fcgid (webapps in subdirs with separated user context)

Posted by Luca Toscano <to...@gmail.com>.
Hi Jonas,

2018-05-10 0:59 GMT+02:00 Jonas Meurer <jo...@freesources.org>:
>
>
> Thanks a ton. I'm still not 100% sure whether I do it the right way, but
> it occurs to me as if I just discovered two bugs in Apache2 suExec that
> make crazy workarounds necessary.
>
> What do you think?
>

Sorry for the lag in answering. I reviewed a bit the code and found out
that this is a pretty common use case (looking for AP_USERDIR_SUFFIX and
suexec in Google revealed a ton of material). suexec is compiled separately
from httpd, since as you can see from the source it gets a main() by
itself. This means that whatever you set in the httpd's config will not
affect AP_USERDIR_SUFFIX, that is a parameter compiled with suexec (you can
tune it using httpd's configure though at build time, but once you create
the suexec binary it is done). As far as I can see there are suexec
variant's shipped with some distributions that allow a suexec config file,
but I don't have a lot of experience with systems like these.

In this list there should be people running into the same issue that you
encountered, let's see if another ping triggers some answers :)

Hope that helps!

Luca

Re: [users@httpd] Re: mod_suexec with mod_userdir and fcgid (webapps in subdirs with separated user context)

Posted by Jonas Meurer <jo...@freesources.org>.
Hi Luca,

thanks for your valuable feedback. With your help I finally found a
solution. It feels like a dirty hack, but it works ;)

Am 24.04.2018 um 10:36 schrieb Luca Toscano:
>>     Do you have a good idea why php-cgi7.0 throws the following error when
>>     used with mod_fcgid, mod_usermod and mod_suexec?
>> 
><     uid: (1002/webapp1) gid: (1002/webapp1) cmd: php-fcgi-starter cannot get
>>     docroot information (/var/www/webapp1)
>> 
>>     $ ls -al /var/www/webapp1
>>     drwxr-xr-x 9 root root 4096 Jun 29  2014 .
>>     drwxr-x---  2 webapp1 webapp1  4096 Nov  7 15:14 php-fcgi
>>     drwxr-x---  2 webapp1 webapp1  4096 Apr 11  2015 www
>>     [...]
>> 
>>     The same setup works perfectly fine without mod_usermod (i.e. when the
>>     whole VHost has a dedicated suexec user). Only with mod_usermod, we get
>>     this strange error.
> 
> Premise: I am super ignorant about suexec & C, but this snippet of code
> in suexec.c seems to be the one returning the error:
> 
>     if (getcwd(cwd, AP_MAXPATH) == NULL) {
>         log_err("cannot get current working directory\n");
>         exit(111);
>     }
> 
>     if (userdir) {
>         if (((chdir(target_homedir)) != 0) ||
>             ((chdir(AP_USERDIR_SUFFIX)) != 0) ||
>             ((getcwd(dwd, AP_MAXPATH)) == NULL) ||
>             ((chdir(cwd)) != 0)) {
>             log_err("cannot get docroot information (%s)\n",
> target_homedir);
>             exit(112);
>         }
>     } 
> 
> As far as I can see, this is what it tries to do:
> 
> - save the current working dir to 'cwd'
> - change dir to "target_homedir", that should be in this
> case /var/www/webapp1
> - change dir to AP_USERDIR_SUFFIX, that if not re-defined should be
> "public_html" (#define AP_USERDIR_SUFFIX "public_html" in suexec.h)

Which seems like a bug to me. mod_userdir explicitly allows to change
the default path to userdir and suExec should take that into account
instead of hardcoding AP_USERDIR_SUFFIX at compile-time.

> - set the variable 'dwd' (docroot working directory) to the above
> - change dir back to cwd (current working directory) 
> 
> So I'd try to add a public_html directory and see how it goes.

Indeed, that helped! I created /var/www/webapp1/public_html as empty
directory. Next error I got was:

[2018-05-10 00:27:34]: command not in docroot
(/var/www/webapp1/php-fcgi/php-fcgi-starter)

Which comes from the following code in suexec.c:

    if ((strncmp(cwd, dwd, strlen(dwd))) != 0) {
        log_err("command not in docroot (%s/%s)\n", cwd, cmd);
        exit(114);
    }

So next step was to replace the newly created directory with a symlink:


$ ln -s php-fcgi /var/www/webapp1/public_html

and replace

    FCGIWrapper /var/www/webapp1/php-fcgi/php-fcgi-starter .php

with

    FCGIWrapper /var/www/webapp1/public_html/php-fcgi-starter .php

in the VHost config. Unbelievable, but that finally worked. My PHP apps
now run with php-fcgi as the userdir user 'webapp1' by suExec. Yay!

So it seems like I have to trick suExec twice to get it working with
mod_userdir and a custom userdir path:

1. create subdir public_html inside home directory of my suExec user
2. make public_html a symlink to the dir where the php-fcgi starter
   script resides and run it from theere as suExec otherwise refuses to
   run the script.

Thanks a ton. I'm still not 100% sure whether I do it the right way, but
it occurs to me as if I just discovered two bugs in Apache2 suExec that
make crazy workarounds necessary.

What do you think?

Cheers,
 jonas


Re: [users@httpd] Re: mod_suexec with mod_userdir and fcgid (webapps in subdirs with separated user context)

Posted by Luca Toscano <to...@gmail.com>.
Hi Jonas,

2018-04-23 15:40 GMT+02:00 Jonas Meurer <jo...@freesources.org>:

> Hello again,
>
> maybe my previous mail was to verbose, or maybe simply nobody has an
> idea. Still I'd like to give it a second try:
>
> Do you have a good idea why php-cgi7.0 throws the following error when
> used with mod_fcgid, mod_usermod and mod_suexec?
>
> uid: (1002/webapp1) gid: (1002/webapp1) cmd: php-fcgi-starter cannot get
> docroot information (/var/www/webapp1)
>
> $ ls -al /var/www/webapp1
> drwxr-xr-x 9 root root 4096 Jun 29  2014 .
> drwxr-x---  2 webapp1 webapp1  4096 Nov  7 15:14 php-fcgi
> drwxr-x---  2 webapp1 webapp1  4096 Apr 11  2015 www
> [...]
>
> The same setup works perfectly fine without mod_usermod (i.e. when the
> whole VHost has a dedicated suexec user). Only with mod_usermod, we get
> this strange error.


Premise: I am super ignorant about suexec & C, but this snippet of code in
suexec.c seems to be the one returning the error:

    if (getcwd(cwd, AP_MAXPATH) == NULL) {
        log_err("cannot get current working directory\n");
        exit(111);
    }

    if (userdir) {
        if (((chdir(target_homedir)) != 0) ||
            ((chdir(AP_USERDIR_SUFFIX)) != 0) ||
            ((getcwd(dwd, AP_MAXPATH)) == NULL) ||
            ((chdir(cwd)) != 0)) {
            log_err("cannot get docroot information (%s)\n",
target_homedir);
            exit(112);
        }
    }

As far as I can see, this is what it tries to do:

- save the current working dir to 'cwd'
- change dir to "target_homedir", that should be in this
case /var/www/webapp1
- change dir to AP_USERDIR_SUFFIX, that if not re-defined should be
"public_html" (#define AP_USERDIR_SUFFIX "public_html" in suexec.h)
- set the variable 'dwd' (docroot working directory) to the above
- change dir back to cwd (current working directory)

So I'd try to add a public_html directory and see how it goes.

Hope that helps!

Luca