Setup TLS for Google Domains using ACME & Certbot

date
Nov 25, 2023
slug
setup-tls-for-google-domains-using-acme-&-certbot
author
status
Public
tags
Notes
summary
Setup TLS for Google Domains using ACME & Certbot
type
Post
thumbnail
tls-ssl.webp
updatedAt
Feb 28, 2024 07:57 AM
Table of Contents:

Introduction

Google Domains will generate certificates automatically for us and automatically renew them helping cutdown certificate related outages. This guide assumes you already have access to the following: Google Cloud, Google Domains, a self hosted website that’s using NGINX to route the traffic. This guide is VM specific. In Kubernetes this would be done completely different, but given that this is for my personal website where costs are more important than reliability. Hence the vm. In order to generate a certificate from Google Domains that can be used by NGNIX, follow these steps 👇🏼

⛅ Google Cloud Setup: PublicCA Auth + Enable API

  1. The following will add the role External Account Key Creator to your user.
    1. gcloud projects add-iam-policy-binding <PROJECT_ID> \
        --member=user:<USER> \
        --role=roles/publicca.externalAccountKeyCreator
  1. Next, we need to enable the API publicca.googleapis.com for the account.
    1. gcloud services enable publicca.googleapis.com
 

🔑 Obtain EAB Key from Google Domain

  1. Navigate to Google Domains
  1. Head over to the Security tab.
  1. Look for SSL/TLS certificates for your domain and expland Google Trust Services.
  1. Click on Get EAB Key. Save those keys as we plan to use them. You won’t be able to review them again.
 

💻 Serverside Setup

  1. Install Certbot & NGNIX
    1. Follow these instructions to setup Certbot and NGNIX if you haven’t done so already. https://certbot.eff.org/instructions?ws=nginx&os=debianbuster
  1. Now, we need to register the ACME Account with Public CA.
    1. certbot register \
          --email "EMAIL_ADDRESS" \
          --no-eff-email \
          --server https://dv.acme-v02.api.pki.goog/directory \
          --eab-kid "<EAB_KEY_ID>" \
          --eab-hmac-key "<EAB_HMAC_KEY>"
      
  1. We are now able to manually generate certificates that can be used with NGNIX.
    1. certbot certonly \
          --manual \
          --preferred-challenges "dns-01" \
          --server https://dv.acme-v02.api.pki.goog/directory \
          --domains "<DOMAIN>"
  1. You should be prompted to create a TXT dns record in Google Domains similar to the following. After it’s created wait 2-3 mins for it to take effect and continue with prompts. _acme-challenge.<DOMAIN> —> TXT —> <VALUE>
  1. The certs will be stored in following locations 👇🏼
    1. /etc/letsencrypt/live/<DOMAIN>/fullchain.pem
      /etc/letsencrypt/live/<DOMAIN>/privkey.pem
  1. Finally, we just need to update our NGINX config and restart it.
    1. Update the nginx config: sudo vi /etc/nginx/nginx.conf (default location)
    2. Add the following under http
      1. ##
        # SSL Settings
        ##
        ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; 
        ssl_certificate /etc/letsencrypt/live/<DOMAIN>/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/<DOMAIN>/privkey.pem;
    3. Here’s a basic example that listens and forwards traffic from port 443. It also performs a redirect for any traffic coming as HTTP (port 80).
      1. nginx config example
        http {
        	##
        	# SSL Settings
        	##
        
        	ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; 
        	ssl_certificate /etc/letsencrypt/live/<DOMAIN>/fullchain.pem;
          ssl_certificate_key /etc/letsencrypt/live/<DOMAIN>/privkey.pem;
        
        	##
        	# Logging Settings
        	##
        
        	access_log /var/log/nginx/access.log;
        	error_log /var/log/nginx/error.log;
        
        	server {
            listen 443 ssl;
            listen [::]:443 ssl;
        
            server_name  <DOMAIN>;
        
         		location / {
              proxy_set_header    Host        $http_host;
        			proxy_set_header    Upgrade     $http_upgrade;
        			proxy_set_header    Connection  "upgrade";
        			add_header X-Frame-Options "" always;
        
              proxy_pass           http://localhost:<PORT>/;
            }
        	}
        	server {
        		# Redirect to HTTPS
            listen 80;
        		server_name <DOMAIN>;
        		return 302 https://$server_name$request_uri;
          }
        }
  1. Assuming the rest of your NGINX config is setup correctly, you should be able to restart NGINX and TLS should be configured automatically for your site.
    1. sudo systemctl restart nginx;
      sudo systemctl status nginx;

 🕰️ Renewing Certs:

  1. Store credentials in /etc/letsencrypt/cli.ini with credentials or pass them in as command line arguments.
    1. sudo vi /etc/letsencrypt/cli.ini 
      
      -- Insert the following items:
      email = <EMAIL>
      server = https://dv.acme-v02.api.pki.goog/directory 
      eab-kid = <EAB KID>
      eab-hmac-key = <EAB HMAC KEY>
  1. Renew cert & restart nginx.
    1. sudo certbot --text --agree-tos --email <EMAIL> -d <DOMAIN> \ 
      --manual --preferred-challenges dns --expand --renew-by-default \
      --manual-public-ip-logging-ok certonly

📚 Sources: