Chat with LLM: Obtain a Free SSL Certificate
Introduction
The production server for a project I am working on is an Azure VM that's only accessible via an IP address, which couldn't establish HTTPS connections. This is a situation I found unsatisfactory. To enable HTTPS, we first need to register a domain name, then configure DNS resolution, and finally apply for an SSL certificate. The key to achieving this for free lies in obtaining a domain name at no cost, since Cloudflare offers free DNS resolution services and Let's Encrypt provides free SSL certificates. However, acquiring a free domain name is challenging, and Cloudflare might not recognize such free domains. Consequently, I kept postponing this task.
Recently, while conversing with an LLM again, I discovered that Azure allows us to claim a free domain name ([your-chosen-prefix].[vm-region].cloudapp.azure.com) for a VM's public IP address, and it also provides free DNS resolution services. This significantly simplified my task, as Azure had handled the most difficult part. I only needed to apply for the SSL certificate.
Thus, this blog post was born: how to apply for a free SSL certificate from Let's Encrypt. Note that the vast majority of this post's content was generated by an LLM. I successfully obtained the SSL certificate by following these instructions, so I decided to document them.
Steps
1️⃣ Prepare Directories and Configuration
Create two directories on the host machine for storing verification files and certificates.
1 | mkdir -p /mydata/certbot/www /mydata/certbot/ssl |
www/: Used to store Let's Encrypt verification files, needs to be mounted into the Nginx container.ssl/: Used to store the generated SSL certificate files.
2️⃣ Configure Nginx for Verification
You need to modify your Nginx container's configuration or startup parameters to ensure it can serve the verification files under the .well-known/acme-challenge path. Add the following server block to your Nginx configuration:
1 | server { |
3️⃣ Modify Nginx Startup Command: When starting the Nginx container, you must mount the host directory /mydata/certbot/www to the container path /var/www/certbot (or the path you specified in your configuration).
1 | docker run -d \ |
4️⃣ Run Certbot Container to Request Certificate
Use the following command to run a temporary Certbot container to obtain the certificate. Remember to replace your-domain.com with your actual domain.
1 | docker run --rm \ |
If successful, you will see a message like this:
1 | Saving debug log to /var/log/letsencrypt/letsencrypt.log |
Your certificate and private key files will be saved in the host directory /mydata/certbot/ssl/live/your-domain.com/.
5️⃣ Configure Nginx to Use the SSL Certificate
Now, add HTTPS configuration for your Nginx service. You need to create a server block listening on port 443 and reference the newly obtained certificates.
1 | server { |
6️⃣ Modify Nginx Startup Command: When starting the HTTPS-enabled Nginx container, in addition to mounting the verification directory, you must also mount the SSL certificate directory.
1 | docker run -d \ |
Miscellaneous Notes
-
The default Azure domain name itself is free. However, the virtual machine must be associated with a public IP address, and this IP resource incurs costs based on its type and allocation method.
-
Let's Encrypt certificates are valid for 90 days and must be renewed regularly. One common solution is to set up a cron job for this, though I don't currently have this requirement. The renewal command simply replaces
certonlyin Step 4️⃣ withrenew. -
Q: Does our Nginx need to keep serving the
/.well-known/acme-challengepath? Are there any security risks in doing so?A: To enable automatic renewal of Let's Encrypt certificates, persistently serving the
/.well-known/acme-challengepath is necessary and standard practice. The files under this path are public, temporary files used for verification and contain no sensitive information. You don't need to worry excessively about this. -
In Step 4️⃣, a container is started solely to execute a Certbot command, hence the
--rmparameter is used. There's no need to configure it in docker compose. -
Certbot uses ports 80/443 for verification and cannot use other custom ports.
-
The method we used to request the certificate is called HTTP-01 challenge, which is the most common approach. Other methods like DNS-01 challenge also exist; refer to the official documentation.
References
- LLM