I have an AWS EC2 LAMP server (using Apache 2.0 and mod_php5) with a basic directory structure like this:

    |-- www
    |   `-- api_folder (NOT public)
    |   |   |-- sensitive files (NOT public)
    |   |   |-- folder with sensitive files and 1 public webhook API file
    |   |   |   |-- sensitive files (NOT public)
    |   |   |   |-- Public_Webhook.php file receiving POST <== (PUBLIC)
    |   |   |   |-- sensitive files (NOT public)
    |   '-- public_html (PUBLIC)
    |   |   |-- files_and_folders (PUBLIC)
    |   |   |-- ...


  1. Does a PHP file need to be publicly accessible in order to be able to receive a POST webhook from some service?
  2. If yes, is it possible to make the Public_Webhook.php file receiving POST as public while the folder its in and the rest of the contents are all private and not accessible to the public?
  3. If possible, would I just chmod 700(Do I need to then set the files myself to 600 or will it be done auto if I set folder to 700?) the whole private API folder and set permissions on the private PHP file to 644?


Running $ ps aux | grep http, gets me:

$ ps aux | grep http
root     32267  0.0  1.9 370488 19968 ?        Ss   14:40   0:00 /usr/sbin/httpd
apache   32275  0.0  2.5 459372 26324 ?        S    14:40   0:00 /usr/sbin/httpd
apache   32276  0.0  2.6 460168 27080 ?        S    14:40   0:00 /usr/sbin/httpd
apache   32277  0.0  2.5 459400 26412 ?        S    14:40   0:00 /usr/sbin/httpd
apache   32278  0.0  2.5 459240 26272 ?        S    14:40   0:00 /usr/sbin/httpd
apache   32279  0.0  2.5 459372 26304 ?        S    14:40   0:00 /usr/sbin/httpd
apache   32280  0.0  2.5 459372 26288 ?        S    14:40   0:00 /usr/sbin/httpd
apache   32314  0.0  2.5 459372 26288 ?        S    14:50   0:00 /usr/sbin/httpd
apache   32316  0.0  2.5 459372 26288 ?        S    14:50   0:00 /usr/sbin/httpd
apache   32319  0.0  2.5 459236 26240 ?        S    14:50   0:00 /usr/sbin/httpd
apache   32324  0.0  2.4 458332 25132 ?        S    14:50   0:00 /usr/sbin/httpd
ec2-user 32524  0.0  0.2 110456  2208 pts/0    S+   15:50   0:00 grep --color=auto http

So my apache user is simply apache (whereas I assume on some distros, this would be like www-data or ubuntu, etc).

Currently, I do not have a a /public_html directory but that is what I am planning to set up. At the moment, my public folder is /var/www/html/ and all the sensitive files are in that directory -- eek!

$ ls -l /var/www/html shows this:

drwxrwsr-x 2 ec2-user www 4096 Jul  2 19:56 archive
-rw-r--r-- 1 ec2-user www  364 Jul  7 00:02 config.ini.php
drwxrwsr-x 4 root     www 4096 Jun 30 21:42 private_api_files
drwxrwsr-x 2 root     www 4096 Jun 26 21:29 some_assets
-rw-r--r-- 1 ec2-user www  643 Jul  6 00:02 mail_test.php
-rw-rw-r-- 1 root     www   18 Jul  5 22:53 phpinfo.php
drwxrwsr-x 7 ec2-user www 4096 Jul  2 20:25 PHPMailer-master

Pretty much all of those directories/files are private and will contain sensitive information. That looks wrong for some reason, but I'm too new to this to tell.


Please correct me if I am wrong. So,

  1. I would move .../Public_Webhook.php to /var/www/html/public_html/ while leaving the sensitive files in their place and relinking them properly in the webhook PHP file.

  2. Then, I'd run the following on the newly created, private /var/www/html/private_api_files/ and change it to:
    $ chown -R apache:apache /var/www/html/private_api_files/
    $ chmod -R go-rwx /var/www/html/private_api_files/
    $ chmod -R 700

  3. Then I'd run the opposite on the newly created /var/www/html/public_html/
    $ chown -R apache:apache /var/www/html/public_html/
    $ chmod -R rwxr-xr-x /var/www/html/public_html/
    $ chmod -R 755


  1. Would it be cleaner to move all sensitive files out of /var/www/html/ and into a folder, like /var/www/all_sensitive_api_files/ and simply keeping everything in /var/www/html/ public -- it seems this way, I wouldn't have to alter ownership/permissions or Apache DocumentRoot directive settings, right?)

PS: I'm so low on Server Fault points, I can't even upvote you :/

  • No worries. If it answers your question I guess you can accept it as an answer?
    – gview
    Jul 8, 2016 at 23:26
  • Ok, so .. what I would suggest is this, have a user to own all the files that is not the apache user. I don't know what you have right now. Have the directories in question provide group access rights to a different user, or add the apache user to that user's group. Then give minimal access rights to the group.
    – gview
    Jul 8, 2016 at 23:27
  • In my ignorance I created a mess, so in same folder I have a directory like this drwxrwsr-x 2 root www 4096 Jun 26 21:29 some_assets and another like this drwxrwsr-x 7 ec2-user www 4096 Jul 2 20:25 PHPMailer-master. Mind you, I created both of them, but then messed with perms/owner/group for some but not others. Seems like I modded the PHP folders cuz my user ec2-user needed access? Anyway, my user is ec2-user and you can see how my /var/www/html is setup right above Solution? Jul 8, 2016 at 23:31
  • I would suggest you make a new user to own the files in webspace. I actually create a new user for every separate web project. Then when you login as ec2-user you can sudo su - newuser. For quite a while I've been using git and so typically I just have to set things up so that user can pull files from my git repo when I want to deploy. A whole other long story but works pretty well.
    – gview
    Jul 9, 2016 at 0:17
  • What that entails, is going into that user and creating a .ssh directory, setting the perms to 700, and adding the private key for a user that will pull from github, bitbucket or wherever the source code is. Frequently for small businesses or projects that ends up being bitbucket because they let you have small private repos for free, whereas github doesn't.
    – gview
    Jul 9, 2016 at 0:25

1 Answer 1


In your case, php is essentially the same user as apache forks. So the user that owns the child apache processes is the user that requires access to files.

The user apache runs as is configured in the apache conf file. You can verify who this user is on your running system by running:

ps aux | grep http

You will see a process owned by root, and a number of child processes that are the ones you are interested in.

From a directory standpoint, that is the user that needs RX permissions.

Nothing needs to be "public" in the sense that every user on the system needs access to it, but the user that apache is running as needs access to whatever files it will be reading.

There is a concept of the Apache webroot. You configure this in your conf file, typically in a vhost section using the DocumentRoot directive. Files under the webroot are accessible via the running Apache server. It appears that public_html is your webroot. If that is the case, then Public_Webhook.php should be under the webroot.

That does not mean however that any of the private files need to be under the webroot. You can define the path the those files and access them from Public_Webhook.php, and this is a common practice.

Most frameworks with a front controller only place the front controller itself along with static assets under the webroot. All other files are placed outside of the webroot and included as required.

Again, any private files simply have to be accessible by the user Apache is running as, and you can make those permissions as open or limited as you would like.

As for default permissions and file ownership there is a lot to that question. There is the umask, and then there are some things you can do that are more granular. You can configure unmask for the user who is being used to own the directories in question, and setting that user's umask will probably take care of your concerns when new files are added to existing directories. See this site for umask basics

See this question for more advanced things you can do with the installation of directory acl.

Changing permissions for a directory simply requires some combination of using wildcards and/or the recursive option. That works for both ownership and perms:

Ownership, changed recursively:

chown -R apache:apache /some/dir


Remove all perms for group/other recursively

chmod -R go-rwx  /some/dir

Set owner only perms recursively:

chmod -R 700

Again, keep in mind that a php script that needs to access a file does not need execute permission for that file.

What does tend to be confusing is that the directory needs execute permission in order for apache (or any user) to read files inside of it. The files themselves (not including .php scripts that will be executed) do not have to have execute, and can be set so that apache only has R access.

From a security standpoint, you are not providing much security if the apache user has RWX access to everything. Even under the webroot you do not want the apache user to have Write access to the directories and scripts.

Typically people who are using apache/mod_php set things up so that Apache access files via the group permission for the file.

This allows you to have a different user for owning/editing/updating the directories and file, and you concentrate on the group permissions and make those as limited as possible.

Updated, solution answers:

  1. Yes, reference the inclusion of files. In PHP all file related functions refer not to "webspace" but to the actual filesystem. For this reason you can include/fopen etc. files anywhere on the system that the user running the php script can access.
  2. Have your directories, both private and webspace, owned by a user on the system who is not apache. To keep it simple this user will own all files as user|group, where the username and group name is the same. For now let's call this account fsuser.

    chown -R fsuser:fsuser /var/www/html/private_api_files/ chown -R fsuser:fsuser /var/www/html/public_html/

Now handle the Directory permissions and only give access to user and group.

chmod -R 750 /var/www/html/public_html
chmod -R 750  /var/www/html/private_api_files

Now for the individual files in the directories, for php files only, give them this:

chmod find /var/www/html/public_html -type f -name '*.php' -exec chmod 650 {} \;

For the other directory, you don't want to set the execute bit, so you only want group to have READ access. This finds all files, and sets their access.

find /var/www/html/private_api_files/ -type f -exec chmod 640 {} \;

Now you simply have to add the apache user as supplemental group member to the fsuser group:

usermod -a -G fsuser apache

Make sure you always restart apache after making any of these types of changes or tweaks.

sudo service httpd restart
  • ...Oh, but I can comment! :D Thank you. I updated my question. Jul 8, 2016 at 23:22

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .