Stuck on nginx multisite Wordpress (LEMP)

May 24, 2017 960 views
WordPress Nginx Networking Ubuntu 16.04

Hi! I have read a lot about this, but I can't figure it out why is not working for me. The idea is the following: I want to host several websites on a single droplet. The scheme is like this:

wargostudio.com -> stuck
oncativosa.wargostudio.com -> working fine
jalisco.wargostudio.com -> working fine

example2.com
sub1.example2.com
... etc

when I go to wargostudio.com, I get a blank page. In the error log, the server is trying to access /usr/share/nginx/html/ but** I have specified another path.** Whats going on?

Thanks very much, and sorry for the length of the question.

So my first domain is: wargostudio.com and the config file:

server {
    listen 80 default_server;
    listen [::]:80 default_server;
    root /var/www/wargostudio;

    index index.php index.html index.htm index.nginx-debian.html;

    # include snippets/wp-supercache.conf;

    server_name wargostudio.com www.wargostudio.com;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php7.0-fpm.sock;
    }

    location ~ /\.ht {
        deny all;
    }

    location ~ /.well-known {
        allow all; 
    }

}
server {
    # SSL configuration

    listen 443 ssl http2 default_server;
    listen [::]:443 ssl http2 default_server;
    include snippets/ssl-wargostudio.com.conf;
    include snippets/ssl-params.conf;
}

And one subdomain (oncativosa.wargostudo.com) is like this:

server {
    listen 80;
    listen [::]:80;

    root /var/www/oncativosa;

    index index.php index.html index.htm index.nginx-debian.html;

    server_name oncativosa.wargostudio.com;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php7.0-fpm.sock;
    }

    location ~ /\.ht {
        deny all;
    }
}

And finally jalisco.wargostudio.com

server {
        listen 80;
        listen [::]:80;

        root /var/www/jaliscopaletas;

        index index.php index.html index.htm index.nginx-debian.html;

        include snippets/wp-supercache.conf;

        server_name jalisco.wargostudio.com;

#       location / {
#               try_files $uri $uri/ /index.php?$args;
#       }

        # Caching of media: images, icons, video, audio, HTC
        location ~* \.(?:jpg|jpeg|gif|png|ico|cur|gz|svg|svgz|mp4|ogg|ogv|webm)$ {
                expires 2M;
                add_header Cache-Control "public";
        }

        location ~ \.php$ {
                include snippets/fastcgi-php.conf;
                fastcgi_pass unix:/run/php/php7.0-fpm.sock;
        }

        # CSS and Javascript
        location ~* \.(?:css|js)$ {
                expires 1d;
                add_header Cache-Control "public";
        }


        location ~ /\.ht {
                deny all;
        }
}

4 Answers

@francarranza

When it comes to PHP-FPM, it's best to setup a new user for each site, and in turn, a separate config file for each.

Side Note -- Take your time on this, it's lengthy and easy to overlook a step.

The default configuration should be located in:

/etc/php/7.0/fpm/pool.d

In that directory, you should see a file (if you've not changed the name) named www.conf. That's the base configuration file that'll help you get started.

...

To get started, what I would do is create three users:

useradd -d /var/www/wargostudio wargostudio
useradd -d /var/www/oncativosa oncativosa
useradd -d /var/www/jaliscopaletas jaliscopaletas

What these commands do is create a new user, which we'll use to setup individual PHP-FPM pools. The -d defines the home directory for the user.

...

Now, with our new users, we'll create our individual pool files by copying the current pool.

cp /etc/php/7.0/fpm/pool.d/www.conf /etc/php/7.0/fpm/pool.d/wargostudio.conf
cp /etc/php/7.0/fpm/pool.d/www.conf /etc/php/7.0/fpm/pool.d/oncativosa.conf
cp /etc/php/7.0/fpm/pool.d/www.conf /etc/php/7.0/fpm/pool.d/jaliscopaletas.conf

Now, we can simply remove www.conf unless you want to keep it (you can always copy one of the others to a new file using the same command, so it's not really needed):

rm /etc/php/7.0/fpm/pool.d/www.conf

Now, inside of each of those files, you'll want to modify the fourth line, which should be:

[www]

Change that to [wargostudio], [oncativosa], or [jaliscopaletas] depending on the file.

Now you'll want to find:

user = www-data
group = www-data

Change that to:

user = wargostudio
group = wargostudio
user = oncativosa
group = oncativosa
user = jaliscopaletas
group = jaliscopaletas

Now you'll want to find:

listen = /run/php/php7.0-fpm.sock

And change that to:

listen = /run/php/php7.0-fpm.wargostudio.sock
listen = /run/php/php7.0-fpm.oncativosa.sock
listen = /run/php/php7.0-fpm.jaliscopaletas.sock

As above, the line corresponds to the user we created. This helps us to keep things separated.

Now, finally, in each of the files, find:

listen.owner = www-data
listen.group = www-data

And, much like we did with the previous, change that to:

listen.owner = wargostudio
listen.group = wargostudio
listen.owner = oncativosa
listen.group = oncativosa
listen.owner = jaliscopaletas
listen.group = jaliscopaletas

That's all we need to change in the PHP-FPM configuration files. We then need to make sure that we set our NGINX server block up to reflect the new sockets.

Find each instance of:

fastcgi_pass unix:/run/php/php7.0-fpm.sock;

And change the path to the socket so that it corresponds with the new user / socket.

fastcgi_pass unix:/run/php/php7.0-fpm.wargostudio.sock;
fastcgi_pass unix:/run/php/php7.0-fpm.oncativosa.sock;
fastcgi_pass unix:/run/php/php7.0-fpm.jaliscopaletas.sock;

The reason for doing all this extra work is to ensure that we have actual separation. It's not just extra work, rather, it's adding a layer of security. It separates each user by process as well as prevents one user form modifying the files of another -- that's not possible if every site uses www-data.

Now, we need to make sure permissions are correct. Since we setup new users, we need to make sure our directories and files are owned by these users.

chown -R wargostudio:wargostudio /var/www/wargostudio
chown -R oncativosa:oncativosa /var/www/oncativosa
chown -R jaliscopaletas:jaliscopaletas /var/www/jaliscopaletas

...

At this point, you need to restart PHP-FPM and NGINX:

service php7.0-fpm restart
service nginx restart

...

With proper separation and proper permissions, if there are any errors that pop up, they should be more specific.

It's not recommended to run every site under the same user (i.e. www-data), which is the point of doing all this -- and it should be done for each site, ideally.

Beyond the above, I would start with the most basic NGINX configuration possible until you're up and running 100%. Then add extras to tighten security, work with SSL, etc.

So what I would do is reduce those server blocks down to:

server {
    listen [::]:80 default_server;
    server_name wargostudio.com www.wargostudio.com;

    root /var/www/wargostudio;

    index index.php index.html;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php7.0-fpm.wargostudio.sock;
    }
}
server {
    listen [::]:80;
    server_name oncativosa.wargostudio.com;

    root /var/www/oncativosa;

    index index.php index.html index.htm index.nginx-debian.html;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php7.0-fpm.oncativosa.sock;
    }
}
server {
    listen [::]:80;
    server_name jalisco.wargostudio.com;

    root /var/www/jaliscopaletas;

    index index.php index.html index.htm index.nginx-debian.html;

    location / {
        try_files $uri $uri/ /index.php?$args;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php7.0-fpm.jaliscopaletas.sock;
    }
}

I've already modified the socket line in the above for you, so you should be able to just copy and paste.

Make Sure you backup the others first, just in case you need them for reference. The above should work, but it's nice to have something to fall back to.

Hi, thanks for the answer. I'm having now this issue:
Connection refused (111), your cache admin is root. It seems to have a problem with the permissions for the new users.

@francarranza

I've actually never seen that error to be honest, though there is one more thing we can try and it doesn't require too many changes.

Instead of using sockets, we can use TCP.

In each of the ./pool.d files we modified, find the listen = directive. We'll set PHP-FPM to listen on a specific port instead of using a socket. You'll increment the port for each site, starting with port 9000.

/etc/php/7.0/fpm/pool.d/wargostudio.conf

listen = 127.0.0.1:9000

/etc/php/7.0/fpm/pool.d/oncativosa.conf

listen = 127.0.0.1:9001

/etc/php/7.0/fpm/pool.d/jaliscopaletas.conf

listen = 127.0.0.1:9002

No other changes should need to be made as long as you've made the previous changes, so let's go ahead and restart PHP-FPM:

service php7.0-fpm restart

Now we need to modify each NGINX server block to match the new TCP connections.

wargostudio

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass 127.0.0.1:9000;
    }

oncativosa

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass 127.0.0.1:9001;
    }

jaliscopaletas

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass 127.0.0.1:9002;
    }

You'd now restart NGINX:

service nginx restart

Now, I can't tell what's in snippets/fastcgi-php.conf, so if you can post that to a code block using the </> icon, we can see if there's anything there that may be causing some issues too.

  • @jtittle
    after giving permission to new user

    chown -R wargostudio:wargostudio /var/www/wargostudio
    

    would i be able to upload/edit files through FTP using my sudo user?

    also as per the following tutorial
    https://www.digitalocean.com/community/tutorials/how-to-install-wordpress-with-lemp-on-ubuntu-16-04#upgrading-wordpress

    is suggested to bring ownership back to sudo user after configuring wordpress

    sudo chown -R sammy /var/www/html
    

    so is that need as well if i follow ur guide here?

    WordPress is the most popular CMS (content management system) on the internet. It allows you to easily set up flexible blogs and websites on top of a MySQL backend with PHP processing. WordPress has seen incredible adoption and is a great choice for getting a website up and...
    • @francarranza

      PHP-FPM requires a valid user and group to run, and that ownership properties on the files and directories that the process is set to read be set to that user and group.

      From a security standpoint, you should run each PHP-FPM process as a different user (as I've outlined in my previous response). The reason for this is to prevent one user + group from being able to read + write to all your websites directories and files.

      While that may not seem like an issue initially, if someone successfully, for one reason or another, hacks one of your sites, they are going to attempt to get as far as they possibly can. With one user owning all files and directories, it'd be relatively simple (very simple), to move around and attack the others, even if they others are not vulnerable to same attack vector.

      ...

      For example, let's say everything is owned by the user and group sammy -- all of your website directories and files.

      Now let's say I successfully attack and break in to wargostudio and I can place a file in one of your directories (if I can do it once, I can do it again). I can get the owner and group in 2 lines of PHP code, that means I now know who owns all your files, so the first thing I'm going to do is see if I can get further.

      If sammy owns everything, that means I have access to everything that reports back with ownership of that user and group, and I can read and write.

      Using PHP, I can read something really basic like $_SERVER to get a good view of what all I might could attack, or I could just echo out __DIR__ to get the path to the current directory. I could even use an iterator to get multiple paths and files in less than a second.

      I could then do something as simple as:

      <?php
      system( 'rm -rf *' );
      

      Short for recursively remove with force (i.e. no confirmation).

      Wherever that's executed, all files and directories are gone, and unless you have a backup, there's no recovery.

      But I probably wouldn't do that first, I'd look to see if you have database credentials in some location that I can access, because if you do, I'll grab those and get in to your database so it's either deleted or damaged. I'd then remove your files.

      ...

      When each PHP-FPM process runs as it's own user, the damage is limited. If I'm able to break in, I won't be able to access the directories and files of another user and group, thus damage would be limited to the site I break in to. I could still delete one site, but I wouldn't, in normal circumstances, be able to delete them all.

      ...

      That's just a very very basic example (and I've seen it happen).

      ...

      So if you need to transfer files, from a security standpoint, each site should have it's own SFTP, meaning each of the new users we created would be granted SFTP abilities and the sammy user would simply be your sudo user for anything that required root (and uploading files doesn't).

      ...

      That guide is meant to introduce you to the basics of creating a sudo user, it's not an all-inclusive security guide. There's a lot more to security than using a sudo user for root instead of using the actual root user :-).

Thanks so much to everyone!!

Have another answer? Share your knowledge.