TLS Certificate Renewal Automation for NZ sites: Certbot, Let's Encrypt, DNS-01 and HTTP-01 challenges

Quick answer

A TLS certificate is what lets your site serve HTTPS, and it expires. Let's Encrypt certificates are free and last 90 days, so renewal has to be automated — by hand it will fail. Certbot is the most common automation tool on Linux servers; on most NZ hosting providers it can be installed in one or two commands and set to renew via a cron job or systemd timer. The two main challenge types are HTTP-01 (a file on your web server, works for plain domains) and DNS-01 (a TXT record on your DNS, works for wildcard certs and for hosts without an open HTTP port).

For the connection-security headers that depend on a valid certificate (HSTS in particular), see the HSTS Strict-Transport-Security Explained guide. For a ten-second check of your current cert expiry and chain, run the Free Website Security Check.

Why TLS renewal is not optional

Every TLS certificate has an expiry date baked into it. Browsers refuse to load a site whose certificate has expired; users see a full-page warning. For a school website, that warning is the difference between parents trusting the site and parents leaving (1).

Let's Encrypt, the dominant free certificate authority, issues certificates that last 90 days by design (2). This is deliberately short: short lifetimes limit the damage from a leaked private key, force operators to keep their automation working, and let the CA change algorithms or revoke compromised keys quickly. The trade-off is that renewal must be automated. Doing it by hand, even on a single site, will fail eventually.

The most common failure mode the NZAI scanner sees across New Zealand school and small-business sites:

  • A site is set up once with a cert that lasts one year. Renewal is forgotten.
  • The site works for 12 months. On month 13, browsers start showing "your connection is not private".
  • The site operator does not know why, and may not know who has the renewal credentials.
An expired certificate is functionally identical to having no certificate. The browser treats the site as not HTTPS at all. Set up automation on day one — every site that has not yet expired has only been lucky.

HTTP-01 vs DNS-01 — which challenge should you use

When you request a certificate from Let's Encrypt, the CA has to verify that you control the domain. There are two common challenge types; which one you use depends on your hosting setup.

HTTP-01 works by having Certbot spin up a temporary HTTP listener on port 80, write a challenge token at http://yourdomain/.well-known/acme-challenge/<token>, and the CA fetches that file over plain HTTP to confirm control (3). It is the simplest challenge and works for plain domains on any host where port 80 is open and reachable from the internet.

DNS-01 works by adding a TXT record to your DNS zone containing the challenge token. The CA looks up the TXT record at _acme-challenge.yourdomain.com (3). DNS-01 is the only way to get a wildcard certificate (*.yourdomain.nz), and it is the only way to issue a cert for a host that does not serve HTTP at all (an internal name, a host behind a firewall, a mail server).

Quick rule of thumb for NZ sites

  • Plain domain (e.g. yourschool.nz or www.yourschool.nz) and HTTP port 80 is reachable → use HTTP-01. It is faster, simpler, and does not depend on DNS automation.
  • Wildcard (*.yourschool.nz), a host behind a CDN, a host behind a firewall, or no reachable HTTP → use DNS-01. You will need DNS API access to automate the TXT-record writes.
  • Both → use HTTP-01 for plain hosts, DNS-01 for wildcards. Most school and small-business sites use HTTP-01.

A typical NZ school on shared hosting (Hostinger, Sitehost, MyHost, Webdrive) will use HTTP-01, because the control panel already exposes port 80 and the hosting provider has a Certbot integration. A school with Microsoft 365 + Azure DNS, or a school running its own DNS at a third-party DNS provider (Cloudflare, DNSimple, Route 53), can usually do both.

Certbot — the standard automation tool

Certbot is the EFF-maintained client for Let's Encrypt. It is free, open source, and packaged for every common Linux distribution (4). Most hosting providers also ship a Certbot integration or an equivalent; if you are on managed hosting, check the panel first.

Install on Ubuntu / Debian

sudo apt update
sudo apt install certbot

Install on RHEL / Rocky / Alma

sudo dnf install certbot

Obtain a certificate (HTTP-01, with nginx)

sudo certbot --nginx -d yourschool.nz -d www.yourschool.nz

Certbot will edit your nginx config to add the /.well-known/acme-challenge/ location block, request the certificate, install it, and reload nginx. The certificate is written to /etc/letsencrypt/live/yourschool.nz/ and symlinks in /etc/letsencrypt/live/ are updated on each renewal (4).

Obtain a certificate (DNS-01, wildcard)

For DNS-01, Certbot needs a DNS plugin. Common choices include certbot-dns-cloudflare, certbot-dns-route53, certbot-dns-google, and certbot-dns-azure. Once the plugin is installed, you provide an API token for the DNS provider and Certbot writes the TXT records automatically (3).

sudo apt install certbot python3-certbot-dns-cloudflare
echo "dns_cloudflare_api_token = YOUR_API_TOKEN" > /etc/letsencrypt/cloudflare.ini
sudo chmod 600 /etc/letsencrypt/cloudflare.ini
sudo certbot certonly --dns-cloudflare -d yourschool.nz -d "*.yourschool.nz"

The wildcard certificate now covers every first-level subdomain of yourschool.nz. The API token has to be kept secret — treat it like a password.

The renewal hook — how certificates get re-issued automatically

Certbot ships a renewal hook that runs certbot renew on a schedule and reloads any service that uses the certificate. The hook is usually a systemd timer on modern Linux (Ubuntu 20.04+, Debian 12+, Rocky 9+) and a cron job on older systems (4).

Check whether the timer is installed and active:

sudo systemctl list-timers | grep certbot

You should see an entry like Wed 2026-09-23 03:42:00 NZST 11h Wed 2026-09-23 03:17:01 certbot.timer. If you do not, the timer is not running and renewal is not automatic.

If you only have cron:

echo "0 3 * * * root certbot renew --quiet --deploy-hook 'systemctl reload nginx'" | sudo tee /etc/cron.d/certbot

The --deploy-hook runs only when a certificate is actually renewed, so nginx is reloaded at most once per day and only when a new cert exists.

Test the renewal without waiting 60 days

sudo certbot renew --dry-run

This runs the entire renewal pipeline without issuing or installing a certificate. If it succeeds, automation is healthy. Run this on every new install, then again on a quarterly schedule, to catch DNS, plugin, or API-token issues before they cause a real expiry (4).

TLS Certificate Renewal Automation for NZ sites — Certbot, Let's Encrypt and 90-day auto-renewal hooks

NZ hosting providers — practical differences

Most New Zealand school and small-business sites run on one of a handful of hosting providers. Each has slightly different support for Let's Encrypt and Certbot.

  • Hostinger, Sitehost, MyHost, Webdrive, Domains4Less — managed shared hosting. Most of these provide Let's Encrypt certificates directly from the control panel with one-click enable and no Certbot needed on your side. The hosting provider runs the renewal on its own infrastructure. This is the simplest path.
  • Vultr Auckland, MyRepublic, or a VPS-style provider — you manage your own server. Install Certbot yourself as above.
  • Microsoft Azure / Azure DNS — well-supported via certbot-dns-azure. Wildcards work cleanly through Azure DNS API.
  • Cloudflare in front of origin — Cloudflare issues its own edge certificates (15-year validity) and an origin certificate for the back-end. Most Cloudflare-fronted sites never need Certbot on the origin at all.
  • Self-hosted in a school server room — works but pay attention to firewall and NAT. HTTP-01 needs port 80 reachable from the internet.
If your hosting provider offers free Let's Encrypt in the control panel, use that. It is operationally simpler than running Certbot yourself and the provider handles renewal.

Mixed content — what to fix when the cert is renewed

A renewed certificate makes the connection to your site HTTPS. But it does not fix mixed content — the situation where the page itself loads images, scripts, or iframes over plain HTTP. Browsers will block the mixed-content resources, breaking the page (5).

This is a separate, related problem. The most common source of mixed content on an NZ site is a leftover hardcoded http:// URL — usually a logo, a tracking pixel, or an embedded video player — that nobody updated when the site moved to HTTPS years ago.

A free scan flags mixed content in seconds. For the full walkthrough of how to find and fix it on a typical NZ site, see HTTPS Everywhere: Fixing Mixed Content on NZ Sites.

What to do when renewal silently fails

The most common sign of a silent renewal failure is the timer or cron job running but reporting an error that nobody checks. Certbot's exit code is logged; on most systems it goes to /var/log/letsencrypt/letsencrypt.log (4). A few quick diagnostics:

  • Check the log first: sudo tail -50 /var/log/letsencrypt/letsencrypt.log
  • Confirm the timer is enabled: sudo systemctl is-enabled certbot.timer
  • Run a dry-run manually: sudo certbot renew --dry-run
  • If the failure is "connection refused" on port 80, your web server stopped accepting connections or a firewall started blocking. HTTP-01 requires port 80 reachable from the public internet.
  • If the failure is a DNS plugin error, your API token expired or got rotated. Regenerate the token and update /etc/letsencrypt/cloudflare.ini (or equivalent).
  • If the failure is "rate limit", you requested too many certificates too quickly. Let's Encrypt's rate limits are documented at letsencrypt.org/docs/rate-limits/. Wait an hour and try again.

Beyond Let's Encrypt — paid CAs and special cases

For most NZ sites, Let's Encrypt is the right choice: it is free, widely trusted, and has tooling for every common setup. There are a few reasons to choose a paid CA:

  • Extended Validation (EV) certificates used to show the company name in the browser address bar; modern browsers removed that visual treatment in 2019, so EV offers little extra trust today.
  • Longer validity — paid CAs offer 1-year or 2-year certificates. Most NZ security guidance now recommends shorter lifetimes because shorter lifetimes limit damage from key compromise.
  • Wildcards without DNS API access — some paid CAs issue wildcards based on file-upload or email verification. Slower and more expensive than DNS-01.
  • Government or regulated industries — some compliance regimes mandate a paid CA. Check before switching.

For NZ schools and small businesses, none of these generally apply. Use Let's Encrypt.

Common renewal mistakes to avoid

From running the free scanner across New Zealand school and small-business sites, the most frequent missteps are:

  • No automation at all. A cert issued once and never renewed will fail within 90 days (Let's Encrypt) or 12 months (paid CAs). Automation is not optional.
  • Automation exists but the timer is disabled. A systemctl disable certbot.timer left over from a debugging session will silently break renewal. Check the timer is enabled.
  • DNS-01 plugin uses an API token that expired. Most DNS providers let you scope tokens; a token scoped only to the specific zone with TXT-record write access is the safest option.
  • Reload hook missing. The certificate was re-issued but nginx was not reloaded, so the running nginx keeps serving the old cert. Check the --deploy-hook in your cron or the equivalent in the systemd unit.
  • Port 80 blocked after a firewall change. HTTP-01 requires port 80 reachable. If you have added a firewall rule that blocks port 80 (often done "to be more secure"), HTTP-01 renewal will fail. Either open port 80 or switch to DNS-01.
  • Cert was issued for the wrong domain. If you migrated from yourschool.nz to school.nz, you may have two certs — and only the older one is being renewed. Delete the old cert before issuing the new one.

Knowledge check

Test your understanding of TLS certificate renewal with these questions. Click or tap each card to flip it and see the answer.

Q1Your school site has been live for 14 months. The original Let's Encrypt certificate was issued with a one-year paid CA cert that is now expired. Visitors see "your connection is not private". What is the first thing to check?tap to flip
Answer: Confirm the certificate has actually expired, and which one is being served. From your laptop run curl -vI https://yourschool.nz 2>&1 | grep -E "expire date|subject|issuer" — the dates tell you the cert state. If the cert was a paid 12-month cert and you are now in month 14, the cert expired a month or two ago and the site has been quietly broken since. If you have not set up automation, do it now: install Certbot, run certbot --nginx -d yourschool.nz -d www.yourschool.nz, and confirm the systemd timer is active. If the cert is in fact still valid but the warning shows anyway, check the chain — the intermediate cert may have expired (this is the Let's Encrypt ISRG Root X1 / X2 rollover that hit a lot of older Android clients in 2021) (1)(2).
Q2Your school wants a single certificate that covers portal.yourschool.nz, mail.yourschool.nz, learn.yourschool.nz, and any future subdomain. Which challenge type do you need?tap to flip
Answer: DNS-01, because only DNS-01 can issue a wildcard certificate. The request would be certbot certonly --dns-cloudflare -d yourschool.nz -d "*.yourschool.nz" (or equivalent for your DNS provider). The wildcard cert covers every first-level subdomain of yourschool.nz — present and future — but only one level deep: learn.yourschool.nz is covered, portal.learn.yourschool.nz is not (3). For NZ schools, this typically means a wildcard via Cloudflare DNS, Azure DNS, or Route 53 — most NZ DNS providers expose an API that one of the Certbot DNS plugins supports.
Q3Certbot's systemd timer is enabled and the most recent certbot renew --dry-run passed cleanly. A week later the real renewal run fails. What changed?tap to flip
Answer: Almost certainly something changed between the dry-run and the real run. The most common causes are: (1) the DNS plugin's API token was rotated or revoked (regenerate it, update the credentials file, restart certbot); (2) port 80 was blocked at the firewall (HTTP-01 needs port 80 reachable); (3) nginx or apache was reloaded with a config that no longer serves the .well-known/acme-challenge/ location (check the vhost); (4) the CA's rate limit was hit (wait an hour). Check /var/log/letsencrypt/letsencrypt.log for the actual error and trace from there (4).

Sources and references

[1] CERT NZ. (2025). Critical controls for small organisations. https://www.cert.govt.nz/

[2] Internet Security Research Group. (2025). Let's Encrypt — How it works. https://letsencrypt.org/how-it-works/

[3] Internet Security Research Group. (2025). Let's Encrypt — Challenge types. https://letsencrypt.org/docs/challenge-types/

[4] Electronic Frontier Foundation. (2025). Certbot documentation. https://eff-certbot.readthedocs.io/

[5] Mozilla. (2025). MDN Web Docs — Mixed content. https://developer.mozilla.org/en-US/docs/Web/Security/Mixed_content

[6] New Zealand. Parliament. (2020). Privacy Act 2020. https://www.legislation.govt.nz/act/public/2020/0031/latest/whole.html

What to do next