Setting up a Letsencrypt wildcard certificate on a private domain/IP

Shitij Goyal
Polar Tropics
4 min readJan 14, 2021

--

Recently, I was setting up a service on Nginx on Google Cloud Platform. My organisation has started using the google cloud and I wanted to setup an internal service (with a private IP). After setting it up, I realised that my service didn’t have https support as the domain for internal services on GCP was different than what was there previously, and thus I did not have a SSL certificate for it. Here I’ll share my experience of how I achieved HTTPS security for a private domain.

Searching for certificates

The first thing I had to do was obtain a certificate for my application on the domain (xyz.example.com). After searching for a bit, I came to know about LetsEncrypt which provides certificates for free (A great initiative and supported by the big orgs!). The client for generating LetsEncrypt certs is called Certbot (https://certbot.eff.org/).

The process for getting a certificate for an application hosted on a public IP is different from that of a private IP. For public domain name, as the domain is accessible from LetsEncrypt servers, there is no extra verification needed but for private domain name or a wildcard certificate request(only accessible within a company’s network), we have to take some extra steps.

The steps needed to obtain wildcard SSL certificates for a private domain are:-

  1. Install certbot on your machine. I used an ubuntu machine because my application is hosted on ubuntu. You can use any other platform. I followed the instructions here — https://certbot.eff.org/lets-encrypt/ubuntubionic-nginx . The main command is
sudo snap install --classic certbot

2. Now how certificate obtaining for private IP works is-

  • You request certificates.
  • Certificates are downloaded to your directory.
  • If not using a DNS provider
sudo certbot certonly -d *.xyz.example.com
  • You are given a TXT record to attach to your DNS provider. This is the additional step which needs to be done when creating wildcard certs or private domain certs. It’s there because in case of wildcard or private domain, LetsEncrypt cannot verify that the domain you will be using the cert is owned by you. What if you requested certificates for *.google.com? That would be bad (of course!) and the whole purpose of using SSL to trust an entity would be defeated. So after receiving this TXT record you create a DNS entry in your domain provider and then LetsEncrypt makes a call to that domain entry you created, verifies it matches with what it has issued and returns true or false.
  • The verification can be done either automatically through a DNS provider on which you host your domain or manually.
  • If using a DNS provider (Check the list of providers certbot supports— https://certbot.eff.org/docs/using.html#dns-plugins and obtain credentials)

Install the provider plugin

sudo snap install certbot-dns-<PLUGIN>

Obtain certificates and verify (Here the — dns-google flag and the credential file automates the above process of creating a TXT record using the DNS provider api. I can skip this flag if i want and do the process manually too)

sudo certbot certonly — dns-google — dns-google-credentials creds.json -d *.xyz.example.com
  • If it returns true, everything is hunkey dorey. If it return false, that means that either the TXT record was wrong or it did not find a TXT record for the domain that you want a certificate for. Hence it cannot verify that you that domain and fails to sign the certificate.

3. Once this is done, you should have your certificates and you can them anywhere you like (I’m using nginx as a front for my application).

4. You can verify your certificate using -

sudo certbot-auto certificates

Things to remember:

  • LetsEncrypt certificates expire after 3 months. This is to reduce the scope of disaster if the certificates are stolen. Hence, you will need to renew the certificates before 3 months. Certbot even gives a nifty command for it which you can run at schedule
sudo certbot renew
  • The certificate I generated was for *.xyz.example.com domain, which means I can use it only for subdomains like data.xyz.example.com and not one.data.xyz.example.com . Wildcard certificates from LetsEncrypt are limited to single level of nesting. (Caused me lots of pain to debug this)

Finally I can see the happy padlock in my browser :D

HTTPS works!
HTTPS works!

As an additional cookie, you can install docker and run -

sudo docker run --rm -ti  drwetter/testssl.sh <website>

Testssl.sh(https://github.com/drwetter/testssl.sh) is a great service and perfect for usecases where you can’t use online tools to check for your SSL. This will give a detailed report on the SSL setup for the website along with a proper nice rating. (A+ :D)

--

--