Comments on PHP-FPM/Nginx Security In Shared Hosting Environments (Debian/Ubuntu)
PHP-FPM/Nginx Security In Shared Hosting Environments (Debian/Ubuntu) If you want to use nginx and PHP-FPM for shared hosting environments, you should make up your mind about security. In Apache/PHP environments, you can use suExec and/or suPHP to make PHP execute under individual user accounts instead of a system user like www-data. There's no such thing for PHP-FPM, but fortunately PHP-FPM allows us to set up a "pool" for each web site that makes PHP scripts execute as the user/group defined in that pool. This gives you all the benefits of suPHP, and in addition to that you don't have any FTP or SCP transfer problems because PHP scripts don't need to be owned by a specific user/group to be executed as the user/group defined in the pool.
7 Comment(s)
Comments
Hi,
I just got the same problem and I solved it.
The owner group of the socket is useless, your socket needs to be owned by the user of the application which needs to have priviledges on it. The early information of that is when your current configuration only works if you let any user access to it ('other' permissions).
Thus, set permissions to 0600 and change the listen-user in your pool configuration file from PHP-FPM (/etc/nginx/fpm/pool.d/*.cong) to 'nginx'. The group is useless.
I don't know if this is a bug in the spawn of the PHP-FPM UNIX socket or if this is the genuine behavior of UNIX sockets, but I am a little lost on this. I don't get it either.
Enjoy!
This maybe because the fastcgi pass is coming from ,nginx and not the pool user. Also there maybe an issue with the openbase_dir restriction set ?
Hi,
I'm not sure about this but I think using TCP sockets is inherently insecure in this setup.
Let's assume you're running 2 pools:
Pool1 User: www-data Port: 9000
Pool2 User: bob Port: 9001
While PHP scripts run as Bob and therefore have only the same rights as Bob, wouldn't it be possible to simply write a PHP script that connects to 127.0.0.1:9000 and pass some script that will be executed as www-data?
Yes, using php-fpm listening to TCP sockets allow any local process from the IP in the listen configuration option (127.0.0.1 in this example) can connect to it. If you only have your own applications in your own server that is usually not a problem, but in a shared hosting it is.
The problem is that the FastCGI specification has not authentication mechanism for the connecting clients. That is stated in the original whitepaper as: "FastCGI applications should only accept connections from Web servers that they trust (the application library includes support for IP address validation). Future versions of the protocol will include support for applications authenticating Web servers...". So far the original FastCGI spec was never updated and so there is no way to filter or authenticate TCP connections made from the same server.
So, you have to use Unix sockets, and you should set properly the listen.owner and listen.group options, so that only the web server can connect to the fpm process. (Also, listen.mode should be 0660, not 0666 or you will have the same security problem). BTW, the example here for using Unix sockets has the listen.owner and listen.group wrong, they should have the values of the web server which are not the same than the "user" and "group" options).
Regards, MValdez.
user = web1
group = client0
these should be real system user or can be anything?
It must be clearear, please fix tutorial, because nginx starts must listen ant listen to the socket, and then only the ftp user itself as process:
listen.owner = nginx
listen.group = nginx
listen.mode = 0660
user = web1
group = client0
then restart nginx and after that php-fpm service. P.S. listen on TCP ports connection is big overhead to the system, so it's better to use socket's.