Create SSL with multisite domain mapping?


How do you create ssl with let’s encrypt if you run a multisite with domain mapping?


I ended up rolling my own shell script to handle this myself:

# Run Lets Encrpyt
/opt/letsencrypt/letsencrypt-auto certonly --webroot -w /var/www/<root-domain>/htdocs/ -d <> -d <> -d <> --email <your-email> --text --agree-tos

# Restart Nginx
sudo ee stack reload --nginx

A note on thinfs you need to change:

<root-doamin> - This is the path of the root domain from where your multisite is served. If you set-up a new site with EasyEngine for the site then the root domain would be

<> - These are the names of the domains that should be included in the cert. You can append multiple domain names with the -d argument

<your-email> - Your email address. Let’s Encrypt will send you a notification when your certificate is about to expire.

If you put this in a shell script you can renew your certificate whenever you want or set-up with a cron job to run every 30 days.


Good job! Thx! But what about nginx config? /var/www/root-domain have one ssl.conf file with ssl-options for root network domain. How about


Declare the ssl.conf once. When you register your cert with Let’s Encrypt you can register multiple domain names for one certificate. If you need a concrete example check out and and view the certificate. Look at the DNS Name section at the bottom.


Thx! Do you mean that if you need to add a subsite of the network root site, you just need to update the LE-certificate with new domains pool? This is great! Can you describe more clearly how to do auto-update certificate after some time?


When I started this command again LE created a new cert in etc/letsencrypt/live/ directory. How can I add new domains to LetsEncrypt cert? And what the command for update cert after 30-60 days?

400 Bad Request after installing LetsEncrypt SSL on WordPress Multisite installation

Replace certonly with renew i nthe command above.

Test the shell script by running it manually. If your script is called then make it executable sudo chmod +x You can run it by typing ./ Make sure the output looks good.

You can run a cron job to run the shell script every 30 days. sudo crontab -e will let you edit the cron tab. Go all the way to the bottom and add something like this:

# Renew SSL certs on the 28th of each month
0 0 28 * * /path/to/your/script/ > /dev/null 2>&1

See for figuring out how to change when your cron job is run.

Hope that helps.

400 Bad Request after installing LetsEncrypt SSL on WordPress Multisite installation

I’ve done ee site update --letsencrypt to enable SSL but obviously this doesn’t cover the custom domains. I’ve tried using your shell script with the proper domains to get it going but it’s just not working. I’ve tried --letsencrypt=off in case too but no dice. Any extra pointers?

Do I need to use the WordPress MU Domain Mapping plugin if the WP I’m running is 4.7.2?


EasyEngine’s version is lame because it only supports one domain name.

This is the shell script I have in the root of my server so I can run it whenever I need to update the cert:

#! /bin/bash

# Clean-up challenge directories
sudo rm -rf /var/www/

# Stop Redis server to free up memory
sudo ee stack stop --redis

# Run Lets Encrpyt
/opt/letsencrypt/letsencrypt-auto certonly --webroot -w /var/www/ -d -d -d -d -d -d --email --text --agree-tos

# Start Redis again
sudo ee stack start --redis

# Restart Nginx
sudo ee stack reload --nginx

I also have this in /var/www/

listen 443 ssl http2;
#  ssl on;
ssl_certificate     /etc/letsencrypt/live/;
ssl_certificate_key     /etc/letsencrypt/live/;

if ($scheme = http) {
  return 301 https://$host$request_uri;

The last conditional there redirects any http traffic to https at the server level. You wouldn’t want to do this if some of your sites in the multisite network are only available via http.

Also after you make any changes don’t forget to restart nginx for them to take effect by doing sudo ee stack restart --nginx

400 Bad Request after installing LetsEncrypt SSL on WordPress Multisite installation

Also you don’t strictly need to run a MU Domain Mapping plugin. You just need the domain to respond so Lets Encrypt can verify you control the site. Let’s Encrypt puts a file in the root directory and verifies that it can access that file over the Internet.

Here are instructions for mapping a domain name without a plugin: and The only thing you need to watch out for is setting the COOKIE DOMAIN to the proper value otherwise WordPress won’t let you login


I have set up EasyEngine in my Ubuntu 16.04 LTS (Xenial Xerus) machine. And have successfully created multisite wordpress with subdomain. Then I have configured main domain multisite to get subdomain. Also pointed subdmain CNAME to main domain.

I can successfully browse main domain and subdomain over http.

The question here is when ever I try to update site with letsencrypt. I can only browse main domain it auto redirects to https. But subdomain does not redirect to https rather opens nginx default page over http. And when I manually enter https://subdomain it opens the wordpress page.

What can I do to correct this issue? I have not used domain mapping for both case, will that make any difference?


I have the same question. (I use wordpress multidomain with plugin) I would just really like to see an example server block(s) showing multiple sites using ssl/let’s encrypt. I am fine with having a cert for each site.

I want all of my sites to redirect to SSL. The primary site does this. The others do not. (well they kind of do but they give the invalid cert warning) If I try to got to the sub-domains via http I get the nginx default welcome page.

400 Bad Request after installing LetsEncrypt SSL on WordPress Multisite installation

Thanks @kingkool6, everything works great except for the following code:

if ($scheme = http) {
  return 301 https://$host$request_uri;

Instead of http being redirected to https, a server default page is loaded from /var/www/html/.


Hi Marcel, you may need to add an IPv6 directive to your ssl.conf otherwise all IPv6 traffic over https will indeed go to the default server.

listen [::]:443 ssl http2;