List

Now, that I got a bit more time on my hands I decided to make a few upgrades to my personal website.
I’m currently redesigning and making code adjustments to V2 and have my hands full with a few projects I’m working on I’ll be publishing early 2016.

But after Let’s Encrypt finally went into Public Beta I had enough motivation today to try and update my site with SSL encryption.

If you already know what Let’s Encrypt, Digital Ocean and ServerPilot are, and if you don’t need an introduction to these great services scroll down to the Tutorial Section.

letsencrypt

 

Let’s Encrypt is a free, automated, and open certificate authority (CA), run for the public’s benefit. Let’s Encrypt is a service provided by the Internet Security Research Group (ISRG).

The key principles behind Let’s Encrypt are:

  • Free: Anyone who owns a domain name can use Let’s Encrypt to obtain a trusted certificate at zero cost.
  • Automatic: Software running on a web server can interact with Let’s Encrypt to painlessly obtain a certificate, securely configure it for use, and automatically take care of renewal.
  • Secure: Let’s Encrypt will serve as a platform for advancing TLS security best practices, both on the CA side and by helping site operators properly secure their servers.
  • Transparent: All certificates issued or revoked will be publicly recorded and available for anyone to inspect.
  • Open: The automatic issuance and renewal protocol will be published as an open standard that others can adopt.
  • Cooperative: Much like the underlying Internet protocols themselves, Let’s Encrypt is a joint effort to benefit the community, beyond the control of any one organization.

Simply put, they enable you to get SSL certification for your Website to offer full encryption between your website and your visitors without paying a single cent for the Certificate.

This might not be sufficient for significant E-Commerce sites or Payment processors that need additional verification, but it’s perfect to make your side projects and personal website a safer place.

 

do_logo_blue

Like most of my other projects, I’m running this Website on a DigitalOcean VPS.

Digital Ocean is a Cloud Hosting provider that lets you rent so called “Droplets,” unmanaged servers on the Internet you can use for all kinds of neat stuff.

Now as we all learned from Spiderman, great power comes with great responsibility.
That’s why if you are not a Linux Magician they have a bunch of Tutorials to get your server up and running with a reasonable level of security.

A Digital Ocean VPS doesn’t come with a control panel that would allow me to manage a few different sites and databases or install a complete WordPress or PHP installation with a single click and if I’m in the Colombian Jungle with no Internet access for a week I ideally don’t want my server to be hacked and abused to DDOS someone else’s website. That’s where having a control panel comes in handy.

There are commercial versions that are expensive and take a lot of resources from your Server, and then there is Serverpilot.

What Serverpilot does

  • Software Installation – ServerPilot installs all of the software your server needs, including PHP, MySQL, Nginx, and Apache.
  • Firewall Configuration – ServerPilot secures your server with an iptables firewall.
  • Automatic Updates – ServerPilot keeps your server’s packages updated.
  • Simple Control Panel – ServerPilot’s control panel makes it easy to host multiple sites on a server, manage databases, change PHP versions, deploy SSL and more.
  • Stats and Monitoring – ServerPilot provides stats and monitoring for your servers and apps.
  • Professional PHP and WordPress Hosting – ServerPilot’s Free plan provides everything you need for secure, reliable hosting on your server. Our paid plans offer additional features that may be helpful to you as your business grows.

As you can see in the Free version, you can have Unlimited Servers and websites you can manage, and they do automatic Firewall and Server security updates for you while only the Coach and their Business plan offers SSL deployment from their control panel.

There is also a special way they automatically set your server up during installation.

ServerPilot configures a LAMP/LEMP stack on your server. LAMP stands for Linux + Apache + MySQL + PHP. As ServerPilot also configures Nginx on your server, this is sometimes called a LEMP stack because Nginx is pronounced “Engine X.”

ServerPilot configures Nginx as the public-facing web server because it is much more scalable than Apache. Unlike Apache, Nginx can handle tens of thousands of simultaneous client connections. As Nginx waits until it has completely received the request before proxying the request through to Apache, your server is safe from Slowloris attacks. For your SSL-enabled apps, Nginx also provides extremely efficient SSL handling and HTTP/2 support.

So, if you combine a DigitalOcean VPS with ServerPilot, you get a pretty easy to manage and neat service package to start, without needing endless experience in how to set up and manage a server.

For my needs the Free ServerPilot plan is perfect, and I was thinking about upgrading to the Coach plan for easy SSL deployment for a while. But after seeing a lot of requests on Twitter and the Serverpilot team for obvious reasons politely declining to easily integrate this functionality for Free Users ( Yes I totally understand that you need some unique features for your paid options)my inner tinkerer accepted the challenge to get this up and running on my DigitalOcean VPS managed by Serverpilot with a free LetsEncrypt SSL certificate.

This is where the Tutorial starts if you just scrolled down.

First of all, make sure you have an actual backup of your server available! I can’t stress this enough.

While I was able to perform these steps and get everything up and running smoothly, you might not be as lucky because of something as simple as a typo or forgetting a step. I’ll take no responsibility if you f*ck up in any way and no, I will not assist or help you on Teamviewer, mail or Skype to get your server back running or do the Installation for you.

With Digitalocean having a working backup is super easy.

Go to https://cloud.digitalocean.com/login and log in with your Username and Password. If you don’t have Two Factor Authentification enabled, while not necessary for this Tutorial this is the perfect time to do so.

Go to Droplets -> Click your droplets name and make sure you have a Backup you can restore from, and if you don’t have one and are not using the Backup Service (which you should) you can Power Off the Droplet and make a Snapshot you can restore from.

Now log into your server via SSH.

First we need to install Let’s Encrypt and switch into its directory.

$ sudo git clone https://github.com/letsencrypt/letsencrypt
$ cd letsencrypt

Then we are stopping nginx-sp for a moment because Serverpilot binds it to port 80, which we need for Let’s Encrypt to generate our certificates.  Otherwise, the installer will throw us an error.

$ sudo service nginx-sp stop

I have not tried it but if you don’t want to stop Nginx-sp for the ten or so seconds it takes to generate a certificate from reading the Let’s Encrypt documentation you can try to create the certificate with

$ sudo ./letsencrypt-auto certonly --standalone-supported-challenges tls-sni-01 -d yourdomain.com -d www.yourdomain.com 

if you have stopped nginx-sp and port 80 is free, use:

$ sudo ./letsencrypt-auto certonly --standalone -d yourdomain.com -d www.yourdomain.com 

This tells lets encrypt to generate a certificate for the domain you are using. I had a few problems only creating the www.yourdomain.com certificate as I’ve been using bjoernfranzen.com most of the time, so generating a certificate that has the www prefix and without worked perfectly for me in the end. If you have something like subdomain.yourdomain.com, make sure to add it via -d as well.

If generating your certificate was successful you will get a response in the shell that your newly generated certificate can be found in /etc/letsencrypt/live/$domain.  Where $domain is your domain name, but don’t worry the correct full path will show in your shell. You can now start your nginx-sp service again by using the command

$ sudo service nginx-sp start 

Please copy the full path where your new certificates are stored into a document on your desktop / Evernote or wherever you take notes (like a Moleskin with real paper) because we need it soon.

Now you switch to /etc/nginx-sp/vhosts.d, where Serverpilot stores the configuration files for the apps (website(s), ) your created over the Serverpilot control panel.

If you get an error that you don’t have permission to enter the directory you might need to switch to your superuser. In the shell, this would look like this.

$ sudo su
$ cd /etc/nginx-sp/vhosts.d

Next we log into Serverpilot to find out what our app name is we want to to add our SSL certificate to.
serverpilot-1

In my case it’s wordpressbf, you write your app name down too.

Now we need to create an SSL configuration file in /etc/nginx-sp/vhosts.d which is the directory we should still be in. We do that by typing:

$ sudo nano yourappname.ssl.conf

Remember to replace yourappname with the app name you just wrote down.

You can replace nano with any text editor you like. But I prefer nano.

You should have an empty file open now.

Next we need to fill in our SSL configuration you can copy & paste mine or make changes to your liking.

Remember to replace “yourdomain.com” and “www.yourdomain.com” with your actual domain name.

“yourdomain” placeholder with the correct replacement from the path you wrote down after successfully generating the certificates, and  “yourappname” with the app name you wrote down from your Serverpilot Dashboard.

By adding “http2” behind the listen commands you can activate support for http2 if your Nginx-SP is above version 1.9.5 you can check your version by typing $ nginx-sp -V and look out for the –with-http_v2_module flag.


server {
	listen 443 ssl http2;
	listen [::]:443 ssl http2;
	server_name  yourdomain.com www.yourdomain.com;


	ssl on;

	# letsencrypt certificates
	ssl_certificate      /etc/letsencrypt/live/yourdomain/fullchain.pem;
	ssl_certificate_key  /etc/letsencrypt/live/yourdomain/privkey.pem;

        #SSL Optimization
	ssl_session_timeout 1d;
	ssl_session_cache shared:SSL:20m;
	ssl_session_tickets off;

        # modern configuration
	ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
        ssl_prefer_server_ciphers on;

        ssl_ciphers 'ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK'; 

        # OCSP stapling 
        ssl_stapling on; 
        ssl_stapling_verify on; 

        # verify chain of trust of OCSP response 
        ssl_trusted_certificate /etc/letsencrypt/live/yourdomain/chain.pem;
        #root directory and logfiles 
        root /srv/users/serverpilot/apps/yourappname/public; 

        access_log /srv/users/serverpilot/log/yourappname/yourappname_nginx.access.log main; 
        error_log /srv/users/serverpilot/log/yourappname/yourappname_nginx.error.log; 

        #proxyset 
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-SSL on; 
        proxy_set_header X-Forwarded-Proto $scheme; 

        #includes 
        include /etc/nginx-sp/vhosts.d/yourappname.d/*.nonssl_conf; 
        include /etc/nginx-sp/vhosts.d/yourappname.d/*.conf; 
} 

When you are done with the changes, press Ctrl+X to save and confirm the save dialog by pressing return. If you get an error that the file can’t be saved, you most likely forget to write sudo before entering the nano command.

Now restart nginx-sp so the changes can take effect by typing

$ sudo service nginx-sp restart

Awesome. If you now type your domain in the SSL Server Test from Qualys SSL Labs, you should get a response like this after the testing.

result

 

Now we are almost done, all you need to do is go to your WordPress Admin Dashboard and update the WordPress Address and site address to https instead of HTTP like shown here.

wordpress

 

And afterward, force SSL by redirecting HTTP to HTTPS in your .htaccess file.

RewriteCond %{HTTP:X-Forwarded-Proto} !=https
RewriteRule (.*) https://%{HTTP_HOST}/$1 [R=302,L]

If you are using an SCP Client like WinSCP make sure you enable hidden files in the settings before logging in with your server pilot username and password so you can see the .htaccess file.

Last but not least, my personal advice is to install and activate the Really Simple SSL Plugin. It is maintained and helps you with avoiding problems in WordPress with SSL.

Also to check If your website has the support for HTTP/2 enabled you can use this tool.

Don’t forget to renew your certificate after 90 days by executing the same command you used to create it in the first place.

Just to make sure here is a step by step how to renew your certificate quickly.

$ cd /home/user/letsencrypt
$ sudo service nginx-sp stop
$ sudo -H ./letsencrypt-auto certonly --standalone -d yourdomain.com -d www.yourdomain.com
$ sudo service nginx-sp start

Don’t forget to change the directory to the directory you git cloned letsencrypt into and also replace yourdomain.com and www.yourdomain.com with your domain name.  If you need additional subdomains, you can easily add them via -d subdomain.domain.com for example.

If everything went fine, you’d get a screen like this in your shell.

letsencrypt

In case you want to automate this process, Inan Berbatov sent me a mail that he found a super easy way to update the certificate via a cronjob he found on lesaff’s gist .

All you need to do is edit the root user’s crontab in the Linux shell by typing the following commands:

$ sudo crontab -e

Choose the editor of your choice, I enjoy using nano and then add this command to the end of the file:

@monthly /home/ubuntu/letsencrypt/letsencrypt-auto certonly --renew-by-default --webroot -w /srv/users/serverpilot/apps/app_name/public -d domain.tld -d www.domain.tld 

Don’t forget to exchange the home directory to the directory your letsencrypt git copy resides in, the app_name with your server pilot app name and the domains including subdomains you want the SSL certificate for.

Also, keep in mind that there is a limitation how often you can request an SSL certificate per week for your server. So if you host more than seven domains on the same server, you might want to modify the cron script to execute at different times in the month per domain.

If you wonder what Cron does, it allows Linux and Unix users to run commands or scripts on a given date and time. You can schedule scripts to be executed periodically.

And in case something went terribly wrong you can just restore to the Snapshot you made from your Digitalocean VPS or any other cloud hosting provider you may be using and try again.

Enjoy.

Bjoern

 

Update Jan 2nd, 2016:

Ben Meredith from benandjacq.com sent me a mail that he had a tip in case your site still doesn’t force SSL after this Tutorial.

I noticed today after following your instructions and getting letencrypt set up on my site, that my site was still not forcing ssl, even with the changes to the .htaccess file.

So, I fixed it by modifying the .conf files in the etc/nginx-sp/vhosts.d directory. According to a tutorial I found online, the way to prevent serverpilot from overwriting a change in that directory is to change the name for YOURAPPNAME.conf to YOURAPPNAME.custom.conf.

I modified the server block in that conf file by adding “rewrite ^https://$server_name$request_uri? permanent;” (without the quotes) and then restarted nginx-sp.

Now my site forces SSL.

Thanks for the great tip Ben, I think I solved the problem by changing permissions to the .conf file so that Serverpilot is not overwriting it, but I’d need to check permissions when I am back home to verify.

If you run into the same problem as Ben, try his quick and elegant fix. In case the description is too technical for you let me know via the contact form, and I’ll update his tip by adding the exact commands and one or two screenshots to make it easier for you to achieve his result.

If Bens advice helped you, feel free to visit his website and send a little appreciation his way.

Happy Encrypting.