Yunohost Let's Encrypt automation: design, boundaries, and checks
Yunohost automates Let's Encrypt certificates for public domains, but HTTP-01 validation, DNS limits, and fallback certificates create operational boundaries.
20 Aug 2025, 05:35 UTC

Problem and takeaway
Yunohost can automate Let's Encrypt certificates for web services on Debian, but the automation only works when the server can prove control of a public domain. If DNS, port 80, or the DNS provider does not match the validation method, Yunohost may fall back to a self-signed certificate and browsers will show trust errors. Use public domain names with reachable validation paths, verify the renewal timer, and treat internal-only names as outside this automation.
Requirements before certificate automation
ACME is the Automated Certificate Management Environment protocol used by Let's Encrypt to validate domain ownership. For the common HTTP-01 challenge, these conditions must be true:
- The domain resolves publicly to the Yunohost server's public IP address.
- Port 80 is reachable from the internet through the firewall and is not blocked by the ISP.
- The Yunohost admin has an email address configured for expiry notifications.
- For wildcard names such as *.example.com, DNS-01 validation is required and Yunohost must support the DNS provider.
Internal names such as internal.example.local cannot obtain a public Let's Encrypt certificate because Let's Encrypt cannot reach them for validation.
Smallest suitable design
Run Yunohost on Debian and request a certificate for each public domain. The design has four parts:
- Certificate request through the Yunohost CLI, which invokes the ACME client for the domain list.
- ACME validation using HTTP-01 on port 80 or DNS-01 through a supported DNS provider.
- Automatic nginx configuration for SSL termination and HTTP-to-HTTPS redirect.
- A systemd timer that checks renewal on a schedule.
This keeps the trust boundary clear: only Let's Encrypt-signed certificates are trusted by browsers, and nginx terminates TLS for domains with valid certificates.
Trust and data boundaries
- Certificate authority trust: Let's Encrypt must be trusted by the operating system trust store, which is standard on Debian.
- Private key protection: certificate private keys live under /etc/letsencrypt/live/ with restricted access.
- Service isolation: certificates are per domain or per certificate request; one compromised private key does not automatically invalidate other domains.
- Admin email scope: expiry notifications go to the configured Yunohost admin address only.
Operational checks
Run these commands on the Yunohost host as root or with sudo. Replace example.com with your actual domain.
yunohost tools cert --help
View supported options for your installed Yunohost version. Option names can change between releases.
ls -la /etc/letsencrypt/live/
Expected after successful issuance: a directory for the domain containing cert.pem, chain.pem, fullchain.pem, and privkey.pem.
grep -R ssl_certificate /etc/nginx/sites-available/
Expected: each public domain has an nginx block referencing its Let's Encrypt fullchain and private key, plus a redirect from port 80 to HTTPS.
systemctl list-timers | grep yunohost
Expected: a Yunohost timer row related to certificate renewal is listed. If no row appears, automatic renewal may not be scheduled.
From a device outside the server, open https://example.com/ and inspect the certificate. A successful result shows Let's Encrypt as the issuer and example.com as a covered name. A trust error usually means a self-signed fallback is in use.
Failure modes and conditions
- Rate limiting: Let's Encrypt enforces duplicate certificate and renewal limits per registered domain. Repeated requests can cause temporary blocks.
- DNS provider change: wildcard certificates stop renewing until Yunohost is configured with a supported DNS provider for DNS-01.
- Self-signed fallback: if ACME validation fails, Yunohost may use a self-signed certificate, causing browser warnings.
- Blocked port 80: HTTP-01 fails if a firewall or ISP blocks inbound port 80.
- Internal domains: names without public DNS records cannot use this automation.
| Validation method | How it proves control | Suitable case |
|---|---|---|
| HTTP-01 | Serve an ACME token from the Yunohost server on port 80 | Public domain with port 80 reachable |
| DNS-01 | Publish a DNS TXT record through the DNS provider | Wildcard certificates or blocked port 80, only for supported providers |
When the design changes
- You need HTTPS for internal services without public DNS: use a private CA and distribute the root trust to clients, or accept self-signed certificates with manual trust exceptions.
- Your DNS provider is not supported for wildcard certificates: request individual non-wildcard certificates or move DNS hosting to a supported provider.
- You hit Let's Encrypt rate limits: wait for the limit window to reset and avoid repeated certificate requests.
- Port 80 cannot be opened: use DNS-01 if supported; otherwise public HTTPS automation is not viable for that domain.
Limitations and practical result check
This automation does not manage certificates for internal-only names, does not replace manual trust configuration for private CAs, and depends on systemd and nginx remaining in their Yunohost-managed state. Do not manually edit /etc/letsencrypt/ or nginx SSL directives, because Yunohost may overwrite them.
Practical check: after issuance or renewal, confirm the directory exists, nginx references the Let's Encrypt certificate, the renewal timer is listed, and an external browser shows a valid Let's Encrypt certificate for the domain. If any check fails, fix DNS or port 80 reachability before requesting more certificates.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.