In recent years, web browsers have brought SSL to the attention of all users. Google Chrome began to move towards a more secure web in January 2017 and have shown all pages served over HTTP as "Not Secure" since July 2018. Serving a site over HTTPS is a must these days and so the process of maintaining SSL certificates is of utmost importance. Many tools exist for creating certificates, with many web hosts including management for free (Cloudflare SSL, Azure Management Certificates).
Simply, an SSL certificate is a digital certificate that authenticates a website's identity. These certificates allow a website to be encrypted by serving content over HTTPS rather than HTTP.
An SSL certificate is digitally signed by a trusted Certificate Authority (CA) such as DigiCert. Anyone can create a certificate, but a browser will only trust a certificate that has been signed by a trusted CA.
A certificate is only valid for a given amount of time. Once the certificate expires, a browser will no longer trust it. Certificates must be renewed before they expire so that your site is never unsecured.
The main reason to have an SSL certificate is so that a site can be served over HTTPS. This provides encryption between the client and server to keep users' data private. Having this end-to-end encryption prevents a person-in-the-middle attack, which would allow an attacker to eavesdrop on communications. Having the site served over HTTPS means users will see the trusty padlock in their address bar, assuring them their connection is secure.
To receive an SSL certificate from a CA you must verify that you own the domain - usually through DNS. This means that a user can be certain that the server hosting the site is run by the same people who own the domain and that the site can be trusted.
Historically, a business would purchase a certificate from a CA. They would then need to manually renew their certificate before it expired and re-upload it to their server. These certificates were often long-lived (1-2 years) so did not have to be renewed frequently. This is an option that is still widely used, however, many businesses now opt to use free services to get their certificates.
A Self-Signed certificate can be created for free. As the name implies, these are not signed by a trusted CA and will not be trusted by a browser. This is because there is no outside authority to verify the origin is who it claims to be. This type of certificate is often used for development as it can be trusted locally.
Let's Encrypt is a free, automated, open and trusted CA that has become a very popular service with ~3 million certificates issued per day. Automation tools can be used with Let's Encrypt to automatically renew a certificate before it expires - such tools include win-acme and Posh-ACME. These are tools Audacia use for applications that are hosted on VMs as they can easily be set up as background tasks to manage the certificates.
To simplify the process even further, many hosting services offer free certificate management. Many of our systems are hosted in Azure App Services which since May 2021 have offered free management of certificates. A developer only has to set up the certificate once and Azure will handle renewals indefinitely. Processes like these reduce the need for a business to maintain and monitor their SSL certificates lowering the risk of something going wrong.
Whilst our application is hosted in an Azure App Service, we are unable to use their managed certificates due to the lack of support for wildcard certificates. We provide a multi-tenancy application that a customer can access through a custom subdomain, for example,
customer-2.our-app.com. Rather than assigning a new custom domain to the App Service each time we add a new customer (Azure has a hard limit of 500 custom domains), we point
*.our-app.com at the app service. For our customers to see a padlock when accessing the product, we need to obtain a wildcard certificate.
As we are not hosting our application in a VM, it would not be straightforward to use win-acme as we do for other applications. It would not have been cost-effective to have a VM running just to renew our certificates.
Instead, our process was for someone to manually run Let's Encrypt every couple of months and upload the certificates. In total, there were 10 certificates to renew for our two environments. This process was less than optimal as it would take 1-2 hours each time and the Head of Engineering was the only person with permission to update the production system.
We estimated that an automated system would take around a day to set up. With the manual process taking two hours every two months, it would only take 8 months to get a return on the invested development time. Being automated would greatly reduce the risk of certificates expiring due to the renewal being forgotten, or the person being absent.
With our repo hosted in Azure DevOps, we used Azure Pipelines on a schedule to handle our certificate renewals. This gives both developers and stakeholders an easy overview of the renewals from a pipeline status.
I won't go into detail about how we set this up as credit must go to Brent Robinson's excellent guide. This was used as the basis of our process with a few tweaks to make it more suitable for our needs.
First, the pipeline tries to download cached Posh-ACME data from an Azure Blob Storage Container. This contains the domains, thumbprint and dates of the previously created certificate.
Posh-ACME will then configure itself from this cached data and work out if it needs to request a new certificate. A new certificate will be requested from Let's Encrypt if the previous certificate is due to expire within the next 30 days.
We then get the current certificate from Azure Key Vault and compare the thumbprint of this to the thumbprint from Posh-ACME. If the thumbprints do not match then a new certificate has been generated.
The new certificate is then uploaded to the Key Vault where it will automatically be picked up by Azure Front Door within the next 72 hours.
The final step of the pipeline is to upload the new Posh-ACME data to Blob storage so that it can be downloaded in the first step of the next run.
SSL certificates are a requirement when hosting a website for both the browser and users to trust your site. Using a certificate that is managed by your hosting provider is the obvious choice to reduce the risk of something going wrong. However, there may be scenarios in which these cannot be used. For this Audacia project, using Azure Pipelines with Posh-ACME was a good solution as it is inexpensive to run and we get excellent visibility of the status of our renewals within our existing Azure DevOps project.
Audacia is a software development company based in the UK, headquartered in Leeds. View more technical insights from our teams of consultants, business analysts, developers and testers on our technology insights blog.
This article was written by Audacia Senior Software Developer, Jack Percy. Jack is currently on a team building a no-code SaaS platform using VueJS and .NET Core. Prior to this project, he has worked across several industries including automotive repairs and house building. Jack enjoys all things DevOps, particularly CI and CD.