Categories
Past Tutorials WordPress

WordPress Multi-Site SSL setup on NGINX using Let’s Encrypt

The folllowing tutorial is based off my recent experience setting up a LEMP stack on an Ubuntu installation hosted by Digital Ocean.

Setting up a Multi-Site SSL isn’t difficult. The “gotchas” is in your server block’s .conf file. Before we get to that part, set up your Digital Ocean Droplet before installing WordPress with the following steps:

  1. Initial Server Setup with Ubuntu 16.04
  2. How To Install Linux, Nginx, MySQL, PHP (LEMP stack) in Ubuntu 16.04
  3. How To Secure Nginx with Let’s Encrypt on Ubuntu 16.04
  4. How To Set Up Nginx Server Blocks (Virtual Hosts) on Ubuntu 16.04
  5. WordPress Multi-Site NGINX server block configuration
  6. How To Install WordPress with LEMP on Ubuntu 16.04

Adding domains to your Multi-Site setup

Let’s define some terms before we continue with this tutorial:

  1. “primary-domain.com” = WordPress Multi-Site setup
  2. “satellite-domain-one.com” = 1st child site created under primary-domain.com
  3.  “satellite-domain-two.com” = 2nd child site created under primary-domain.com
  4. etc.

Assuming you’ve already set up your SSL and server block for primary-domain.com, we’ll proceed by attaching additional domains to the primary-domain.com certificate. After adding the satellite domains to your droplet inside your Digital Ocean account, make sure each one is pointing to the default server block. If you don’t see the “Welcome to NGINX” page after you point each satellite domain to your Droplet, you’ll have to create individual server blocks for each before continuing to Let’s Encrypt.

After logging into your Digital Ocean droplet via the terminal, enter the following command:

sudo letsencrypt certonly -a webroot --webroot-path=/var/primary-domain.com/html -d satellite-domain-one.com -d www.satellite-domain-one.com -d satellite-domain-two.com -d www.satellite-domain-two.com

If you have additional domains you want to attach to your primary-domain.com certificate, append them the command with -d and make sure to add the www subdomain to your root domain like so: -d satellite-domain-three.com -d www.satellite-domain-three.com

After the process is complete, regenerate you Diffie-Hellman Group by entering the following command:

sudo openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048

This process will take a while.

Next we’ll create a configuration snippet for each satellite domain pointing to the SSL key and certificate. Enter the following command:

sudo nano /etc/nginx/snippets/ssl-satellite-domain-one.com.conf

Inside the editor, add the following directives pointing to the certificate and key:

ssl_certificate /etc/letsencrypt/live/satellite-domain-one.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/satellite-domain-one.com/privkey.pem;

Write out and close the editor. Repeat the previous 2 steps for each satellite domain you added to your Multi-Site setup.

Configuring the Server Block

Instead of creating separate server blocks for each sattilite domain, we will add them to the primary-domain.com server block conf file:

sudo nano /etc/nginx/sites-available/primary-domain.com

Add your NGINX map directive:

map $http_host $blogid {
    default                     0;
    primary-domain.com      1;
    satellite-domain-one.com    2;
    satellite-domain-two.com    3;
}

Add after the NGINX map directive:

server {
    listen 80;
    listen [::]:80;
    server_name satellite-domain-one.com www.satellite-domain-one.com;
    return 301 https://$server_name$request_uri;
}

server {
    listen 80;
    listen [::]:80;
    server_name satellite-domain-two.com www.satellite-domain-two.com;
    return 301 https://$server_name$request_uri;
}

and after those:

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    include snippets/ssl-satellite-domain-one.conf;
    include snippets/ssl-params.conf;
    
    root /var/www/primary-domain.com/html;
    
    index index.php index.html index.htm index.nginx-debian.html;
    
    server_name satellite-domain-one.com www.satellite-domain-one.com;
    
    location ~ [^/].php(/|$) {
        fastcgi_split_path_info ^(.+?.php)(/.*)$;
        
        if (!-f $document_root$fastcgi_script_name) {
            return 404;
        }
    
        include fastcgi_params;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_pass unix:/run/php/php7.0-fpm.sock;
        fastcgi_read_timeout 300;
    }
    
    location ~ /.ht {
        deny all;
    }
    
    location ~ /.well-known {
        allow all;
    }
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    include snippets/ssl-satellite-domain-two.conf;
    include snippets/ssl-params.conf;

    root /var/www/primary-domain.com/html;

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

    server_name satellite-domain-two.com www.satellite-domain-two.com;

    location ~ [^/].php(/|$) {
        fastcgi_split_path_info ^(.+?.php)(/.*)$;
        
        if (!-f $document_root$fastcgi_script_name) {
            return 404;
        }
    
        include fastcgi_params;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_pass unix:/run/php/php7.0-fpm.sock;
        fastcgi_read_timeout 300;
    }
    
    location ~ /.ht {
        deny all;
    }
    
    location ~ /.well-known {
        allow all;
    }
}

Write out the primary-domain.com config file and close. Test it by entering the following command:

sudo nginx -t

The response you will receive if your .conf files are error free:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

Now let’s restart NGINX:

sudo systemctl restart nginx

Note that for each satellite domain, we set the root to the primary-domain.com. The root is usually the “Gotcha” as most will usually set the root to root directory of the satellite domain.

On the WordPress side of things

If you haven’t already, install and setup the WordPress MU Domain Mapping plugin.

In Network Admin > Settings > Domain Mapping add your Droplet’s IP address in the Server IP Address field and check options 1-4 in the Domain Options and save.

Under Network Admin > Settings > Domains link your Site IDs to your satellite domains, make sure “Primary” is checked under each domain setup.

Next, download the Really Simple SSL plugin and activate it. Use it to force SSL on each of your satellite sites, and your done.

Apache

Unfortunately as of this moment I do not know how to setup Multi-Site SSL on Apache. If you have knowledge on the subject, please leave a comment below.

Click here to receive a $10 credit when you sign up to Digital Ocean