Is it possible in nginx configure different user per virtual host?
Something like
server {
user myprojectuser myprojectgroup;
...
}
Server Fault is a question and answer site for system and network administrators. It only takes a minute to sign up.
Sign up to join this communityIs it possible in nginx configure different user per virtual host?
Something like
server {
user myprojectuser myprojectgroup;
...
}
No, because all server stanzas in an nginx config are served from the same set of worker processes. Furthermore, from a security perspective, you're better to run it like that, as it means that the content is automatically unwritable by the webserver (absent stupidities like a chmod -R 0777
), so that if there is a vulnerability in nginx, none of the content is at risk.
www-data
and perms 0710
when you setup the vhost (since this needs root to configure nginx, it's not a problem to have your automation also set the necessary permissions). Then the contents of the docroot just need to be o+x
for directories and o+r
for files.
– womble♦
Mar 18 '12 at 2:46
www-data
, every user that can serve a PHP script or a cgi-bin process can access any file accessible to the www-data
user. This appears to be non-obvious to anyone who stores database passwords in config.php.inc
or similar on a shared machine.
– Ivan Vučica
Apr 7 '14 at 18:15
peter
and john
. They are hosting their web pages in ~/public_html
. Absent a different approach not mentioned by any of the people discussing this above, a .php script has the same permissions as the web server as it is also executing under www-data
. This means that, just like the web server and PHP interpreter, it can read any other .php script.
– Ivan Vučica
Jun 3 '14 at 16:59
Yes. It is possible and recommended for extra security (see why below).
Considering that you are using PHP-FPM (you probably are, as it is the most usual), you can create a spool, owned by a different user, for each domain.
PS: I wrote a detailed step-by-step tutorial here:
https://learnwithdaniel.com/2019/06/user-per-virtual-host-nginx/
1. Create spools:
Add the spools to /etc/php/7.0/fpm/pool.d/www.conf
or create a new .conf
file for each new spool.
Spool #1 (myuser1):
[myprojectuser1]
user = myuser1
group = myprojectgroup
..
listen = /run/php/myuser1.sock
...
listen.owner = www-data
listen.group = www-data
Spool #2 (myuser2):
[myprojectuser2]
user = myuser2
group = myprojectgroup
..
listen = /run/php/myuser2.sock
...
listen.owner = www-data
listen.group = www-data
PS: Keep your listen.owner/listen.group to the same nginx user (usually www-data).
2. Assign each spool to its server block (virtual host for apache users):
Host 1:
server {
...
location ~ \.php$ {
fastcgi_pass unix:/run/php/myuser1.sock;
}
...
}
Host 2:
server {
...
location ~ \.php$ {
fastcgi_pass unix:/run/php/myuser2.sock;
}
...
}
Restart FPM and NGINX services
sudo /etc/init.d/php7.0-fpm restart
sudo service nginx restart
Testing:
Create a pinfo.php (or whatever name) file that will show the current process user:
<?php
echo str_replace("\n", '<br>', shell_exec('ps -u -p '.getmypid()));
Or create the pinfo.php file via bash:
echo "<?php echo str_replace(\"\\n\", '<br>', shell_exec('ps -u -p '.getmypid()));" > pinfo.php
Then open "http://.../pinfo.php" on your browser.
Why to use multiple users (security reasons):
If you run all your websites under the same user (www-data), a PHP call to system()/passthru()/exec() will have access to all websites! NGINX will not protect you against this. The PHP is just an example, but any popular webserver language have similar calls. As a hacker, you can "ls .." to navigate through all websites and "cp/echo/mv" to write your own code in any file (including another website files). Even if all websites on the server are owned by the same person (ex. you) it's advisable to run each website with a different user, as it will prevent eventual hackers/virus (ex. Wordpress viruses) from accessing your other websites.
/etc/php-fpm.d/www.conf
and my .sock is at /run/php-fpm/www.sock
. I've made the appropriate adjustments because of this but it still says I am running as the nginx user.
– James
Feb 26 '20 at 13:37
chmod 500
to all files and folders then the site is working fine except for images being read by "nginx" user, which leads to 403 error
– artnikpro
Jul 3 '20 at 3:59
chown siteuser:nginx
and chmod 440
on all images
– artnikpro
Jul 3 '20 at 4:09
In response to Ivan's comment above and which seems applicable to the OP. Two things:
The application document root would be something like /blah/peterWeb/html
and /blah/johnWeb/html
. Both NGINX and Apache2 would not allow one to peruse or operate in the other directory even if they are both running www-data as group.
Placing each directory tree under their own user permission would allow each user to ssh/login to a UNIX system and keep their directories private to each - just don't put each user into the www-data group. If you agree, then your sentence:
every user that can serve a PHP script or a cgi-bin process can access any file accessible to the www-data user.
might be more accurately written as:
every user that you put in the same group as the apache/nginx server (www-data) can then do whatever they want (including running a php script) in any file that is accessible to it (which would essentially be everything on a web server).
EDIT 1: Having to address some Server Admin issues I looked further into this topic. I was unaware of how accurate Ivan's information was! If you intend to give users the ability to upload and run scripts on a shared hosting configuration then take heed. Here is one approach. Hat tip to Ivan for making sure I understood this vulnerability.
www-data
. If Johnny can create a script and have it run under www-data
(which on naive setups he can), then Johnny's script can read Peter's scripts and send them back to Johnny. This has nothing to do with groups. Proper solution is to have suPHP (if naively setup, bad, as poorly written code then endangers all of this user's files), or a jail, or dedicated additional web user per user.
– Ivan Vučica
Jun 5 '14 at 21:12