Deploying Jekyll to a VPS
Part 5: Switching to HTTPS Only
While a secure connection may not seem relevant for a static website, it affects search engine rankings now that Google uses HTTPS as a ranking signal. And apart from purchasing a certificate or generating a free certificate from Let’s Encrypt, it’s not that difficult to support.
Vagrant Certificate
To start, let’s generate a self-signed certificate on the Vagrant server to allow us to test the configuration changes. We can do so by SSHing into the Vagrant server and running the following commands. Note that it can take some time to generate the dhparam
file.
On OS X we need to trust the generated certificate. To do so copy the example.com.crt
file out of the Vagrant server and drag it into the “Keychain Access” program. After it’s added, double click it, expand the “Trust” section, and set the “When using this certificate” option to “Always Trust”.
Also, since we generated the certificate for example.local
we need to add it to our local hosts file. To add a host on OS X, add 127.0.0.1 example.local
on a blank line to the /etc/hosts
file. Note that we need to use sudo
to write to it.
Server Configuration
Now we need to ensure nginx compiles with the SSL and SPDY modules, creates a new file for the SSL configuration, and uses the new configuration file when a certificate is present.
SSL and SPDY Modules
To compile with SSL and SPDY we add the modules to the node configuration. We also ensure the gzip static module is still available.
Now we can run bundle exec knife solo cook vagrant
to recompile nginx with the modules.
SSL Configuration
Next we need to add a lot of configuration to use and configure the SSL and SPDY modules. We’re going to create it in a separate example.ssl.nginx
file to only enforce HTTPS when a certificate is present.
To learn more about what each directive does, check out the documentation for ngx_http_ssl_module. We could also generate this with the configuration generator from Mozilla, which also supports generation for other servers.
We can add a small condition to our default server recipe to use the new SSL configuration when the certificate is present.
We can run bundle exec knife solo cook
to update the configuration, but note that this will break access to the server until we update Vagrant to handle the new SSL port.
Vagrant Port Forwarding
Next we need update the Vagrant port forwarding. And since it’s kind of annoying having to request http://example.local:8080
or https://example.local:4443
we’re also going to improve the handling to better match the production version. First we need to install the vagrant-triggers
plug-in to allow us to run commands for any Vagrant events.
Now we can run arbitrary commands when starting or stopping the Vagrant instance, so we’ll use pfctl
to map the ports to the standard 80
and 443
ports. We’re also adding a new forwarded port for HTTPS.
Note that we’ll have to enter our password now, since we need sudo
to run the commands. After running vagrant reload
to forward the ports we can access the website at https://example.local. And if we try to access it over HTTP at http://example.local it will redirect us to HTTPS.
Remote Certificate
For production we need a trusted certificate rather than a self-signed version. As mentioned before we can use Let’s Encrypt, but for now we’ll stick with DNSimple from before.
Buy a Certificate
After signing into DNSimple, navigate to the domain we’re going to buy a certificate for. In the SSL certificates section click on “Buy a new SSL Certificate”. Choose the appropriate subdomain for the “Host Name”, which is www
if we’re securing the root domain such as our example.com
.
Creating the certificate will take a bit of time, but we’ll receive a few e-mails when it’s completed. We can also check the status on the DNSimple certificate page.
And while that’s running, let’s generate the dhparam
on the production server.
Install the Certificate
Once DNSimple knows the certificate is available it will provide the certificate bundle and private key. We can find the download links for them under the nginx section of the “Install the SSL Certificate” page linked from the certificate page.
The www_example_com.pem
file is our certificate, which we’ll store at /etc/ssl/example.com.crt
. And the www_example_com.key
file is our certificate key, which we’ll store at /etc/ssl/example.com.key
. Now if everything is correct when we run bundle exec knife solo cook example
it will use the new SSL configuration.
Summary
We now have an HTTPS only website, which will help with our SEO and ensure any access is secure. See the jekyll-vps-server repository for the complete Chef source code, with the part-5 branch being specific to this article.
One final item to remember is to use HTTPS for external resources, such as forms and external CSS or JavaScript. Also update any hardcoded URLs, such as the asset domain or base URL in Jekyll.
E-mail me if you have any tips, comments, or questions.