1
  • Apache HTTP Server 2.2.21 with VirtualHosts under SuExec
  • PHP 5.3.8 via fcgid
  • Arch Linux 2011.08.19

I am in the process of migrating from shared hosting to VPS. The code I had ran fine before the move but is now failing at this line:

require_once($_SERVER['DOCUMENT_ROOT'] . 'includes/content/header.php');

Error log says:

PHP Fatal error: require_once(): Failed opening required '/srv/www/hostname/public/includes/content/header.php' (include_path='.:/usr/share/pear') in /srv/www/hostname/public/index.php on line 3

I tried the same line without the document root part, with and without ./, file in the same directory, etc. with no luck. No difference with require, include_once, or include, either. Yet, I can verify that the file exists at that exact location by copy-pasting from the error log and cding to it.

I asked this question on SO and somebody told me it was likely a server issue so I'm restating here. (The most similar question I could find here was never answered) Summary of attempts:

  • No combination of permissions helps (on directories or files); have tried from 644 to 777.
  • All of the files are chown'd by the SuExec user/group.
  • PHP reports itself as running under the correct user/group.
  • Apache & SuExec error logs report nothing.
  • Safe Mode is set to "Off" in php.ini.
  • dirname(__FILE__) and exec('pwd') return the same as $_SERVER['DOCUMENT_ROOT'] but without the trailing slash; prefixing with one or the other makes no difference.
  • include, include_once, fread, file_exists, file_get_contents, and realpath(dirname(__FILE__)) all return false.
  • set_include_path() has no effect.
  • Running require via php-cgi directly from the command line returns Internal Server Error while include returns blank output; running either via php returns blank output.

Here's my vhost config:

<VirtualHost *:80>
    ServerAdmin admin@hostname.com
    DocumentRoot "/srv/www/hostname/public/"
    ServerName hostname.com
    ServerAlias www.hostname.com
    SuexecUserGroup hostname hostname
    ErrorLog "/srv/www/hostname/logs/error.log"
    LogLevel debug
    CustomLog "/srv/www/hostname/logs/access.log" combined

    <Directory /srv/www/hostname/public>
        Order allow,deny
        Allow from all
    </Directory>

    # http://www.linode.com/forums/viewtopic.php?t=2982
    <IfModule !mod_php5.c>
    <IfModule !mod_php5_filter.c>
    <IfModule !mod_php5_hooks.c>
    <IfModule mod_actions.c>
    <IfModule mod_alias.c>
    <IfModule mod_mime.c>
    <IfModule mod_fcgid.c>
        AddHandler php-fcgi .php
        Action php-fcgi /fcgid-bin/php-fcgid-wrapper
        Alias /fcgid-bin/ /srv/www/hostname/fcgid-bin/

        <Location /fcgid-bin/>
            SetHandler fcgid-script
            Options +ExecCGI
            Order allow,deny
            Allow from all
        </Location>

        ReWriteEngine On
        ReWriteRule ^/fcgid-bin/[^/]*$ / [PT]
    </IfModule>
    </IfModule>
    </IfModule>
    </IfModule>
    </IfModule>
    </IfModule>
    </IfModule>
</VirtualHost>
Hugh Guiney
  • 245
  • 1
  • 8
  • 20

2 Answers2

1

Do you have apparamor installed and if so does it limit what apache process can access? (check /etc/apparmor.d )

Additionally try doing something like this:

sudo -u hostname cat /srv/www/hostname/public/includes/content/header.php

What does it give you?

Alex N
  • 772
  • 3
  • 10
  • 23
  • Also check for selinux (`/var/log/audit.log` or `/var/log/audit/audit.log` in most distributions). Either way, the problem may be a limitation on php-cgi, not on apache itself. – DerfK Oct 30 '11 at 02:19
  • No apparmor, no SELinux. This is Arch Linux which comes with nothing but the bare minimum. I've installed nothing in regard to security; just basic daemons (httpd, sshd, pure-ftpd, tomcat7, etc.) and their dependencies. sudo -u cat command gives me the contents of the file. – Hugh Guiney Oct 30 '11 at 02:47
1

Check to see if you have open_basedir set to something other than a parent directory of /srv/www/hostname/public/includes/content/. This would block opening or including that file. Also make sure that the file you are opening isn't a symlink to something outside your open_basedir.

This would normally print a Warning-level message indicating that the file was blocked due to open_basedir, but if you have the errors disabled (or at least E_WARNING disabled) then you would not see the message.

DerfK
  • 19,313
  • 2
  • 35
  • 51
  • That did it! I didn't realize that `open_basedir` was unaffected by Safe Mode being off—it was looking in `/srv/http/` but not `/srv/www/`. Thank you! – Hugh Guiney Oct 30 '11 at 14:46