Manually Add SSL to ServerPilot on Digital Ocean & Force Redirect – Nginx
The solution for this was harder to find than it should be – probably because ServerPilot wants to preserve the need to upgrade to their paid plans, which is fair enough, but $10/month seems a bit steep just to handle SSL certificate installation (which is quite simple once you understand what you’re doing).
The most confusing part of the process was ensuring that your don’t screw up ServerPilot’s settings, but allowing you to have multiple SSL certificates running for different domains. This tutorial is going to show you how to secure example.com
and then you can recreate these steps to secure any domain or sub-domain that you’ve set an app up for in ServerPilot. The specifics of how this is possible have to do with something called SNI (Server Name Indication), which when enabled allows you to have multiple SSL certificates on one IP address – we won’t get into the details of that in this post, but if you’re so inclined, you can check out this SNI (Server Name Indication) – Wikipedia – just know that ServerPilot has done the heavy-lifting for you on this and it’s enabled and ready to go already.
This tutorial is going to assume you’ve already created your CSR and purchased your SSL certificate – whoever you bought the certificate from should have given you a ZIP file containing your Certificate (.crt) file and a CA bundle file. You’re also going to need to be logged into your server using your root login. These steps cannot be completed properly without the root login. In this example, I’m going to use a test case that assumes the certificate that was purchased was a PositiveSSL certificate from Comodo – bought through NamesCheap.
You’re going to want all your certificate files in one place – this step isn’t necessary, but certainly makes things easier – plus, it’s always good to be organized. I opt for setting up a certs folder in your nginx configuration folder, like so:
cd /etc/nginx-sp
mkdir certs
Then we’re going to create a folder for each of the sites we’ve purchased SSL certificates for – in this tutorial we’re just going to concentrate on example.com
cd certs
mkdir example.com
cd example.com
Now move all your certificate files into this folder – this includes your .csr
and .key
files you would have generated before purchasing your certificate. You’re going to have load the certificate and the CA bundle files from your computer to the server obviously – how you do this is up to you, but the simplest way would be to load them to your existing site using FTP and then move into the folder using SSH.
First, we’re going to want to create a chained certificate – this is done by combining the certificate file and the bundle file – both which would have been supplied to you by the site you bought your certificate from.
cat example_com.crt example_com_ca_bundle > example_com_chained.crt
Now it’s time to set up the SSL configuration, as well as the forced redirect to https for our site. ServerPilot has each of your applications available inside the virtual hosts folder (<serverpilot_app_name>.d
) – these folders allow you to add extra nginx configuration without having to alter the the default .conf
file that ServerPilot manages. The reason we don’t want to edit the default .conf
file is because any change you make in ServerPilot will cause them to rewrite these files, and you’ll lose all your changes. Since ServerPilot doesn’t include any SSL information in the default configuration file on the free plan, we can create a supplemental configuration file that does this for us.
Create ssl.conf
inside our virtual host folder for the specific app that we made; in this case example.com
:
cd /etc/nginx-sp/vhosts.d/example.d
vi ssl.conf
Paste the following into our ssl.conf
file:
listen 443 ssl;
listen [::]:443 ssl;
ssl_certificate /etc/nginx-sp/certs/example.com/example_com_chained.crt;
ssl_certificate_key /etc/nginx-sp/certs/example.com/example_com.key;
ssl_session_cache shared:SSL:20m;
ssl_session_timeout 10m;
ssl_prefer_server_ciphers on;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH!aNULL:!MD5:!DSS;
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/nginx-sp/certs/example.com/example_com_chained.crt;
set $ssl_status off;
if ($scheme = "https") {
set $ssl_status on;
}
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Ssl $ssl_status;
Now save and close the file.
With that created, you’re site is now setup with SSL (we’ll need to restart nginx first though) – but, since you have the SSL, you’ll probably want to force users into the secure version of your site. This part is obviously optional, but I don’t see why you’d want the non-secure version available; however, this is totally up to you.
This can be accomplished using .htaccess
, but I prefer to do it directly in the nginx configuration.
Create a file in the same folder we create ssl.conf
and call it off.nonssl_conf
Paste the following into this new file:
if ($scheme != "https") {
return 301 https://$server_name$request_uri;
}
Save and close the file. Now we just need to test out nginx configuration to make sure there aren’t any problems:
nginx-sp -t
If everything comes back good, we can go ahead and restart nginx:
service nginx-sp restart
There, you’re done! Now when you go to your site, it should force you into https and your certificate should show as valid (assuming you’re not using a self-signed certificate).
This method can be duplicated to work with another domain on your server or a sub-domain of any domain.
worked great, thanks
This works! Thanks for the info…
you rock, thanks 🙂
Awesome Info.
Thank you very much
Hi, thanks for the great article. Helped me a lot, just thought I would add that you should not use an if test for 301 redirect as it requires extra processing on the part of NGINX.
Can simply use
server {
listen 80;
server_name http://www.domain.com;
return 301 https://www.domain.com$request_uri;
}
Normally what you suggested would be the better solution; however, ServerPilot creates the server{} setup for non-ssl (listen 80) manually in their conf file and you can’t declare it twice – but if you overwrite their main file, the next time they do an update or make a change, it will overwrite whatever you’ve done – so, unfortunately, the only way is to do the condition in the extra file that was created to avoid conflict with ServerPilot’s setup (or just pay the monthly fee and let ServerPilot setup the SSL for you)