Never Ending Security

It starts all here

Run php-fpm with separate user/uid and group on linux


Php fpm is the new way to setup php to run with your webserver. Php-fpm is a fastcgi process manager for php that is totally separate from the webserver. The webserver communicates with fpm through a socket and passes the name of the script to execute. So fpm can run with any web server that is fastcgi compatible.

I recently moved from my old shared hosting to linode. Linode provides linux vps hosting at economic prices. However the servers are totally unmanaged are just raw linux machines that have shell access. So through the shell you have to setup everything including the web server, php and the web files.

So this time I decided to go with the combination of nginx and php-fpm. I had multiple sites to setup on this new webserver. Nginx deals with these through separate server blocks (aka vhost in apache). However there was another thing needed. Php on each site should run with its own user and not the nginx common user named www-data.

Running each site with its own uid/gid is more secure and easier to deal with. If all sites ran with same user, then php on one site could read/write the files of other users. This is a security concern. Moreover having separate users gives benefits like separate crontabs, ability to identify processes from each user etc.

Separate Pools

Php-fpm creates and manages a pool of php processes, also called workers that receive and server requests to execute php files from the web directory. Now fpm can run multiple separate pools each with its own uid/gid. This is actually very easy to setup.

On ubuntu, the directory that contains the pool configuration files is


A file called http://www.conf already exists which can be copied to create more pool configuration files. Each file must end with .conf to be recognised as a pool configuration file by php fpm.

The file is very long but starts with something like this.

; Start a new pool named 'www'.
; the variable $pool can we used in any directive and will be replaced by the
; pool name ('www' here)

; Per pool prefix
; It only applies on the following directives:
; - 'slowlog'
; - 'listen' (unixsocket)
; - 'chroot'
; - 'chdir'
; - 'php_values'
; - 'php_admin_values'
; When not set, the global prefix (or /usr) applies instead.
; Note: This directive can also be relative to the global prefix.
; Default Value: none
;prefix = /path/to/pools/$pool

; Unix user/group of processes
; Note: The user is mandatory. If the group is not set, the default user's group
;       will be used.
user = enlightened
group = enlightened

; The address on which to accept FastCGI requests.
; Valid syntaxes are:
;   ''    - to listen on a TCP socket to a specific address on                                                                       
;                            a specific port;
;   'port'                 - to listen on a TCP socket to all addresses on a
;                            specific port;
;   '/path/to/unix/socket' - to listen on a unix socket.
; Note: This value is mandatory.
listen = /var/run/php5-fpm.sock

; Set listen(2) backlog.
; Default Value: 128 (-1 on FreeBSD and OpenBSD)
;listen.backlog = 128

So create a copy of this file and name it to anything like the site which will be using this pool. The important fields to edit are

1. Pool name. It is on the top [www]. Rename it to [mysite].

2. Next, change the user and group field and put the username and group to run it with.

user = mysite_user
group = mysite_user

3. Change the socket file name. Every pool should have its own separate socket. And the particular site should use this particular socket file to connect to fpm.

listen = /var/run/php5-fpm-mysite.sock

Now restart php-fpm

$ sudo service php5-fpm restart

Now check the processes in htop. You should see the new pool running with separate username.
Check the documentation for details about all the configuration parameters. Each pool can have different configuration depending on the needs of the site.

Configure Nginx

If you are using nginx, then put the socket descriptor in the right place and it will use it.

location ~ \.php.*$ {
	fastcgi_split_path_info ^(.+\.php)(/.+)$;

	# NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini

	# With php5-cgi alone:
	# fastcgi_pass;
	# With php5-fpm:
	fastcgi_pass unix:/var/run/php5-fpm.sock;
	fastcgi_index index.php;
	include fastcgi_params;

	fastcgi_param PATH_INFO $uri;

Put the socket descriptor path in the fastcgi_pass line.

fastcgi_pass unix:/var/run/php5-fpm-mysite.sock;

Thats it. Nginx will now use this socket and hence its pool for mysite.

Configure Apache (mod_fastcgi)

Apache can use php-fpm through mod_fastcgi which can talk to external fastcgi servers and get the requests processed. When using external fastcgi server like fpm, mod_fastcgi becomes a mere proxy that relays requests and responses between apache and fpm.

A typical fpm configuration in apache with mod_fastcgi looks like this

<IfModule mod_fastcgi.c>

	# all .php files will be pushed to a php5-fcgi handler
	# $_SERVER['REDIRECT_HANDLER'] in php will contain this name
	AddHandler php5-fcgi-handler .php

	# redirect handling of type "php5-fcgi" to /php5-fcgi-uri uri
	# $_SERVER['ORIG_SCRIPT_NAME'] will contain this name
	Action php5-fcgi-handler /php5-fcgi-uri

	# map the /cool-uri uri to a location (the location need not be real) which is the fcgi application
	# $_SERVER['ORIG_SCRIPT_FILENAME'] will contain this name
	Alias /php5-fcgi-uri fcgi-application

	# define the fcgi application
	# Make sure to use -flush, otherwise php output gets buffered 
	FastCgiExternalServer fcgi-application -socket /var/run/php5-fpm.sock -pass-header Authorization -idle-timeout 30000 -flush


This configuration goes inside the VirtualHost block of the site that wants to use fpm to run php scripts.

Note the last line. It declares an external fastcgi server using the FastCgiExternalServer directive of mod_fastcgi. Over here we specify the fpm socket we want to use. So change it to

FastCgiExternalServer fcgi-application -socket /var/run/php5-fpm-mysite.sock -pass-header Authorization -idle-timeout 30000 -flush

Restart apache and now the particular vhost should use that fpm socket (and hence that fpm pool) to run php scripts.

One response to “Run php-fpm with separate user/uid and group on linux

  1. Matthew Simmons 19 May 2015 at 13:58

    I can’t bear reading long posts, simply as i’ve got a small amount of dislexia, but
    i really loved this one

Leave a Reply

Please log in using one of these methods to post your comment: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s