2

I have installed httpd and php on a fresh centos7 and put some files into /var/www/html including an install script I wrote. This script needs to write to a config file in the /var/www/html directory. I created an empty config file and chowned it to apache:apache. However trying to fopen this file with write access always gives the error:

fopen(/var/www/html/config-local.php): failed to open stream: Permission denied

Doing research I read this quote: "in order to reach a file, ALL parent directories must be readable." So I checked and they are. /, /var, /var/www and /var/www/html are all readable by everyone.

So what's going on here? It appears that the apache user is some kind of specially restricted user since testing the same scenario with a standard user works fine.

jpro
  • 133
  • 1
  • 3
  • 1
    "in order to reach a file, ALL parent directories must be readable" -- orthogonal to your problem, but this statement is incorrect. All parent directories must be *executable* in order to reach a file. – womble Jun 30 '17 at 05:39

2 Answers2

3

It's likely an SELinux permissions issue. /var/log/audit/audit.log should be able to confirm.

SELinux context is probably system_u:object_r:httpd_sys_content_t:s0, but should be system_u:object_r:httpd_sys_rw_content_t:s0. This can be altered with chcon.


I'm also not sanguine about having a config file within the DocumentRoot of your webserver. I could be mistaken as you haven't provided enough detail, but that would be the case if you haven't altered the defaults.

84104
  • 12,698
  • 6
  • 43
  • 75
  • 1
    i had just discovered that it was an SELinux problem: `chcon -t httpd_sys_rw_content_t config-local.php` re config file location - it's not an uncommon scenario to put it there. wordpress does that. – jpro Jun 30 '17 at 03:31
  • consider using `semanage` to update the fcontext definition or restorecond; which should be running, may eventually put it back to the incorrect context. chcon changes can be easily reverted by moving files around or by restorecond. – Aaron Jun 30 '17 at 12:15
0

Spent a lot of time looking for this answer but it's all in bits and pieces and no one every posts a solution (well most of the time) so here is my solution and it's used on various web control panels as well.

install and use MOD_RUID2

Install PHP with CLI (this is standard on newer versions)

In your HTTPD.CONF file in the virtual hosts, you'll add the following, replacing username with the user's login name, and usergroup with the user's group (These are usually the same)

<IfModule !mod_ruid2.c>
    SuexecUserGroup username usergroup
</IfModule>
<IfModule mod_ruid2.c>
    RMode config
    RUidGid username usergroup
    RGroups @none
</IfModule>

An example of a Virtual host conf is:

<VirtualHost *:443>
  DocumentRoot "/home/imtheuser/public_html"
  ServerName imtheuser.com
  <IfModule !mod_ruid2.c>
    SuexecUserGroup imtheuser imtheuser
  </IfModule>
  <IfModule mod_ruid2.c>
    RMode config
    RUidGid imtheuser imtheuser
    RGroups @none
  </IfModule>
  <Directory "/home/imtheuser/public_html">
    allow from all
    Options None
    Require all granted
  </Directory> 
</VirtualHost>

This will allow apache/php to write to a directory owned by the user. It's much safer then setting your chmod to 0777.

mike
  • 1