NGINX / PHP / Server Setup

NGINX and PHP-FPM. What my permissions should be?

by ,


We have by far the largest RPM repository with dynamic stable NGINX modules and VMODs for Varnish 4.1 and 6.0 LTS. If you want to install NGINX, Varnish, and lots of useful modules for them, this is your one-stop repository to get all performance-related software.
You have to maintain an active subscription in order to be able to use the repository!

Being an avid StackExchange user, I could see how many users completely lack understanding of the proper permissions model in the most popular, LEMP stack.

You can see recommendations that 777 is never good, but I could not see a simple guide on permissions that can be used as a reference point for everyone.

The following permissions/ownership model applies to all NGINX/PHP-FPM websites and allows you to host websites without any problems, in a secure way.

PHP-FPM user (as known as the website user)

The PHP-FPM user should be a special user that you create for running your website, whether it is Magento, WordPress, or anything.
Its characteristics are the following:

  • This is the user that PHP-FPM will execute scripts with
  • This user must be unique. Do not reuse an existing user account. Create a separate user for each website!
  • Do not reuse any sudo capable users. If your website user is ubuntu or centos, or, root – you’re asking for much trouble.
  • Do not use www-data or nginx as website user. This is wrong and will lead to more troubles!
  • The username should reflect either the domain name of the website that it “runs”, or the type of corresponding CMS, e.g. magento for a Magento website; or example for example.com website.

Let’s create this user:

useradd example

Now, set its password by running:

passwd example

Each website in PHP-FPM should be run under a separate pool. In the pool settings file, e.g. /etc/php-fpm.d/example.com.conf, you must set things to match with the created username:

listen = /var/run/php-fpm/example.com.sock
listen.owner = example
listen.group = example
listen.mode = 0660
...

The webserver user

NGINX must run with it own unprivileged user, which is nginx (RHEL-based systems) or www-data (Debian-based systems).

This is the “global” webserver user that is used for all websites. So the configuration is straightforward and translates to the following directives in /etc/nginx/nginx.conf:

user nginx;

Connecting website and webserver users

Now the magic. We must connect things up so that NGINX (webserver) user can read files that belong to the website user’s group.

This will allow us to control what NGINX can read or not, via group chmod permission bit.

usermod -a -G example nginx

This reads as: add nginx user to group example.

File ownership (chown)

Here is a simple rule: all the files should should be owned by the website user:

chown -R example:example /path/to/website/files

Permissions (chmod)

The following general chmod setup will allow for any website to function properly:

chmod -R u=rwX,g=rX,o= /path/to/website/files

This translates to the following:

  • Website user (example) can read, write all files and read all directories
  • Website group (webserver user) can read all files and traverse all directories, but not write
  • All other users cannot read or write anything

In octal notation, this results in 0750 chmod for all directories and 0640 for all files.

If you simply stick to this permissions model, you will not encounter any chmod / chown issues in the future.
This is the only proper model, functionality, and security-wise.

These general permissions are quite secure already out of the box. But of course, if you know your website structure, you may want to tighten up permissions even further.

For example, see Magento 1.x lockdown chmod.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: