Site icon GetPageSpeed

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

Linux Command Line

Linux Command Line

Being an avid StackExchange user, I could see how many users completely lack an 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:

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
user = example
group = example

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 be owned by the website user and the website user’s group:

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

Incorrect chown examples:

Correct chown example:

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:

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.

A read-only user

When you want to provide a read-only access for someone else, you can leverage setfacl program. For example, to allow user foo to read a directory and all files inside:

setfacl --recursive --modify u:foo:rX,d:u:foo:rX /path/to/website/files

Troubleshooting tips

To see all directory and file permissions, up to a specific path, use this command:

namei -om /path/to/file/or/directory
Exit mobile version