Let’s Encrypt

Scripting certbot renewals through a UPnP+NAT router

Here is a quick tip for self-hosting enthusiasts who host their own services services behind a NAT router for temporary allowing redirection/forwarding of ports required for Let’s Encrypt certificate issuance and renewals using UPnP.

You may be using a free-of-charge certificate from Let’s Encrypt for use with your email, chat, or other server that uses TLS on your domain but that isn’t normally web accessible. One of the ways you can obtain a certificate from Let’s Encrypt is by demonstrating that you have control over the A and AAAA domain records (IPv4 and IPv6) on port 80 and 443.

You can temporarily create port forwarding rules on your router to forward these port from the internet to the computer in question. Certificates from Let’s Encrypt has to be renewed every three months, so you’ll either have to leave the computer that requires certificate permanently exposed to the internet or come up with a better solution. This doesn’t scale if you have more than one computer you’d like to issue certificates for, or if you use a game console like the PlayStation 4 or Xbox One that temporarily wants control over port 80 for online multiplayer purposes.

Luckily, you can remote-control the port redirection/forwarding rules of most routers to create temporary rule-sets using the UPnP protocol. I’m assuming that your router has UPnP support, as almost all routers sold in the last decade has UPnP support enabled by default. You may need to double-check your router configuration to check whether you run in to any issues. The article assumes you’ll be using UPnP to renew certificates from Let’s Encrypt, but you can use it as a basis for anything that needs you to temporarily open a port on your router.

You’ll need to install the upnpc client program, which you’ll find in the package repostiroy of most Linux distributions under the name miniupnpc. After you’ve installed it you need to create a simple script that requests the ports you need through UPnP, performs the certificate renewal, and then releases the ports again. The following example script should do the job in most cases:

# Add temporary port redirection
upnpc -e "Certbot" -r 80 80 tcp
upnpc -e "Certbot" -r 443 443 tcp

# Update certificates with Certbot
certbot renew

# Remove port redirection
upnpc -d 80 tcp
upnpc -d 443 tcp

You’ll likely need to adjust the firewall on your server to temporarily allow incoming connections on port 80 and 443 as well. The following two examples shows the commands for adding and removing firewall rules for two popular front-ends to the Linux iptables firewall:

firewallctl zone "" add service "http" "https"
firewallctl zone "" remove service "http" "https"

FirewallD (Fedora)

ufw allow "http" "https"
ufw delete allow "http" "https"

Uncomplicated Firewall (Ubuntu)

Adjust your UPnP port redirecting script to include the firewall rules you need. Include the command for adding the rule before certbot renew and the command for removing it below it.

Save your script to a file, make it executable, and run it every week through cron or another task scheduler program.


Please note that some routers may not let you redirect privileged ports (ports below 1024). There may be an option you can toggle for this in your router’s administration interface. Some router firmware, like MikroTik RouterOS may not let you redirect ports used on the internal network for administrative interface services like port 80 and 443. Documentation around UPnP capabilities and limitation is usually hard to come by, so you’ll just have to try and experiment on your own if you run into any issues.

Sources

  • upnpc.c, commit ce2673118d, , miniupnp repository, GitHub
  • Renewing certificates, , User Guide, Certbot, Electronic Frontier Foundation