How to Manually Create and Install Let's Encrypt SSL Certificates

Most Let’s Encrypt tutorials focus on automated certificate renewal using certbot’s built-in web server or plugins. That works great if you have a simple setup with a single server running a standard web server. But what if your infrastructure is more complex? Maybe you’re running multiple servers behind a load balancer. Or you need a wildcard certificate that covers all subdomains. Or your application uses a non-standard port configuration that doesn’t play nicely with certbot’s automation.

In these situations, manual certificate creation gives you complete control. You generate the certificate using DNS or HTTP validation, then install it wherever you need it. This guide shows you how to create both wildcard and single-domain certificates manually using Let’s Encrypt.

Prerequisites

  • A Linux server with certbot installed
  • DNS access to create TXT records (for wildcard certificates)
  • SSH/root access to your web server
  • A domain pointing to your server

Installing Certbot

If certbot isn’t already installed on your server, install it using your package manager:

apt update
apt install certbot

For other Linux distributions or installation methods, visit the official certbot instructions.

Creating a Wildcard Certificate

Wildcard certificates cover your main domain and all subdomains using a single certificate. For example, a wildcard cert for *.example.net covers www.example.net, api.example.net, mail.example.net, and any other subdomain you create.

Step 1: Run Certbot with DNS Validation

Switch to root and run certbot with manual DNS challenge:

sudo su - root
certbot certonly --manual --preferred-challenges=dns -d example.net -d *.example.net

Here's what each option does:

  • certonly: Create a certificate without installing it
  • --manual: Perform manual verification instead of automatic validation
  • --preferred-challenges=dns: Use DNS validation (TXT records) for the challenge
  • -d example.net: Add the root domain to the certificate
  • -d *.example.net: Add a wildcard for all subdomains

Replace example.net with your actual domain. The command requests a certificate that covers both the root domain and all subdomains.

Step 2: Create the DNS TXT Record

Certbot will pause and display instructions for creating a DNS TXT record. The output looks like this:

Please deploy a DNS TXT record under the name:

_acme-challenge.example.net

with the following value:

Kx9mP3nQ2rS8tU5vW7xY9zA1bC3dE4fG6hI8jK0lM2n

Log into your DNS provider and create a new TXT record:

  • Name: _acme-challenge.example.net (or just _acme-challenge depending on your DNS interface)
  • Type: TXT
  • Value: The string provided by certbot

Step 3: Verify DNS Propagation

Before pressing Enter to continue in certbot, verify the TXT record is visible. The best way is to query your DNS provider’s authoritative nameserver directly, which bypasses any DNS caching.

Option 1: Using dig (command line)

First, find your authoritative nameserver:

dig +short ns example.net

This returns something like ns1.dnshost.com. Then query that nameserver directly:

dig @ns1.dnshost.com TXT _acme-challenge.example.net

Look for the TXT record in the answer section. The value should match what certbot gave you:

;; ANSWER SECTION:
_acme-challenge.example.net. 300 IN TXT "Kx9mP3nQ2rS8tU5vW7xY9zA1bC3dE4fG6hI8jK0lM2n"

Option 2: Using Google DNS Tool (web-based)

If dig isn’t installed or you prefer a web interface, use the Google DNS tool:

https://toolbox.googleapps.com/apps/dig/#TXT/_acme-challenge.example.net

Replace example.net with your domain. Enter the DNS name in the query field and select TXT as the record type. This tool queries Google’s public DNS, so results may lag behind due to TTL caching, but it’s convenient for quick checks.

Once confirmed, return to the certbot prompt and press Enter to continue. Certbot will verify the DNS record and issue your certificate.

Step 4: Locate Your Certificates

Certbot stores the generated certificates in /etc/letsencrypt/live/yourdomain/:

ls -l /etc/letsencrypt/live/example.net/

You’ll see four files:

  • cert.pem: Your domain certificate
  • chain.pem: The Let’s Encrypt intermediate certificate
  • fullchain.pem: Your certificate plus the chain (used by most web servers)
  • privkey.pem: Your private key

Creating a Single-Domain Certificate

For a single subdomain certificate without wildcard coverage, you can use HTTP validation instead of DNS. This is simpler because certbot can automatically place the validation file on your web server.

Important: If you’re behind a load balancer, make sure traffic is only being sent to the server where you’re running certbot. Otherwise, the validation request might get routed to a different backend server that doesn’t have the validation file.

Run certbot with HTTP validation:

sudo su - root
certbot certonly --manual --preferred-challenges=http -d app.example.net

Certbot will ask you to create a file at a specific URL on your web server. Follow the instructions, verify the file is accessible at the URL, then press Enter to continue.

Once issued, you can use the same process as the wildcard certificate to locate your certificate files in /etc/letsencrypt/live/.

Verify the Certificate

After installation, verify your certificate is working correctly. You can use any of these methods:

SSL Labs: Get a detailed security analysis of your certificate and SSL/TLS configuration:

https://www.ssllabs.com/ssltest/analyze.html?d=example.net

sslscan: Check certificate details and SSL/TLS configuration from the command line:

apt install sslscan
sslscan example.net

This scans your certificate and reports any issues with cipher suites, protocols, or certificate chain problems.

OpenSSL command: Check certificate expiration dates:

openssl s_client -connect example.net:443 -servername example.net < /dev/null 2>/dev/null | openssl x509 -noout -dates

Certbot: List all certificates on the server:

certbot certificates

Browser: Visit your site via HTTPS and click the padlock icon to view certificate details.

Renewal

Let’s Encrypt certificates expire after 90 days. For manual certificates, you’ll need to repeat the creation process before expiration. Set a calendar reminder for 60 days from now to renew the certificate, which gives you a 30-day buffer.

If you need to renew an existing certificate, run the same certbot command you used initially. Certbot may skip the DNS verification step if the validation is still cached, but be prepared to update DNS records again if prompted.

When to Use Manual vs. Automated

Manual certificate creation is useful when: - You need a wildcard certificate covering all subdomains - Your infrastructure uses load balancers or non-standard configurations - You want to generate a certificate on one server and deploy it to multiple servers - Automated renewal isn’t working due to firewall or network restrictions

For simple single-server setups, automated renewal with certbot’s built-in renewal hooks is usually the better choice. But when your infrastructure demands more flexibility, manual creation gives you the control you need while still getting free SSL certificates from Let’s Encrypt.