Generating SSL Certificates
Passkeys and several other Calagopus features require a valid SSL certificate for your Panel and Wings. This guide walks you through generating one.
This is also a prerequisite if you plan to set up a Reverse Proxy or want to add an SSL certificate directly to your Wings machine.
All methods below use Let's Encrypt, which issues free certificates valid for 90 days.
This is the most common method and works well if your server has port 80 open to the internet.
1. Install certbot
Commands below are for Debian-based distributions using APT. For other systems, see the official certbot website.
sudo apt update
sudo apt install -y certbot
# Only if you use Nginx
sudo apt install -y python3-certbot-nginx
# Only if you use Apache
sudo apt install -y python3-certbot-apache2. Generate the certificate
Replace example.com with the domain you're issuing a certificate for. To cover multiple domains, repeat the -d flag (e.g. -d example.com -d www.example.com).
# If using Nginx
sudo certbot certonly --nginx -d example.com
# If using Apache
sudo certbot certonly --apache -d example.com
# Standalone — use this if you don't run a webserver or the options above don't work.
# Stop any service already bound to port 80 first (nginx, apache etc.).
sudo certbot certonly --standalone -d example.comYou'll be prompted for an email address (used for renewal/expiry notices), then certbot issues the certificate automatically. Certificates are saved to /etc/letsencrypt/live/example.com/.
3. Renewal
Certbot installs a systemd timer (or cron job) that checks twice daily and renews when the certificate is close to expiry. If you used the --nginx or --apache plugin, that's all you need. The plugin reloads your webserver as part of the renewal itself.
If you used --standalone, or want Wings to also restart so it picks up a renewed certificate, add a deploy hook:
sudo nano /etc/letsencrypt/renewal-hooks/deploy/reload-services.sh#!/bin/bash
systemctl restart wings 2>/dev/nullsudo chmod +x /etc/letsencrypt/renewal-hooks/deploy/reload-services.shCertbot runs every script in renewal-hooks/deploy/ automatically after a successful renewal. Test the whole flow without waiting for actual expiry:
sudo certbot renew --dry-runTroubleshooting
An Insecure Connection or SSL/TLS error in the browser almost always means the certificate has expired. If certbot renew fails with something like:
Error: Attempting to renew cert (domain) from /etc/letsencrypt/renew/domain.conf produced an unexpected error
…it's usually because port 80 is already in use. Using the --nginx / --apache plugin flags (as above) avoids this. Otherwise, stop the webserver, renew, then start it again:
sudo systemctl stop nginx
sudo certbot renew
sudo systemctl start nginxIf Wings doesn't pick up the renewed certificate automatically, restart it manually:
sudo systemctl restart wingsWhich method should I use?
| Situation | Recommended method |
|---|---|
| Public webserver, port 80 open | Certbot (HTTP Challenge) |
| Internal/NAT'd node, using a provider with a certbot DNS plugin | Certbot (DNS Challenge) |
| Want a lighter, dependency-free tool? | acme.sh |