Wildcard TLS, end to end
SetHttps issues a Let's Encrypt wildcard certificate over DNS-01, uploads it to every server you register, and renews it before expiry. One CNAME record, no port 80, no DNS provider API keys.
Before you start
- A domain whose DNS you control, e.g.
example.com - A Linux server reachable over SSH (root or sudo)
- Nginx, Apache, OpenResty or anything else that reads a cert file and can reload
Free plan: 1 domain, 10 deploy nodes, unlimited renewals, no credit card. Your live quota is shown in the console.
Four steps
-
Add the domain
In the console, open Domains → New and enter the apex domain, e.g.
example.com. Do not enter*.example.com— the platform always issues a wildcard certificate coveringexample.comand*.example.com.The console then shows a CNAME target for this domain, e.g.
a1b2c3d4.sethttps.com. -
Publish one DNS record
Type Name Value TTL CNAME _acme-challengethe value shown in the console 300 This delegates the ACME DNS-01 challenge to SetHttps, so your server never has to answer on port 80. If the domain is on Cloudflare, set the record to DNS only (grey cloud).
Wait 1–5 minutes, then click Verify. You can confirm from your own shell:
dig _acme-challenge.example.com CNAME +short -
Create the restricted deploy user
Copy the setup script from Deploy nodes and run it once on the target server as root. It creates a
nologinuser, chroots it to the certificate directory, keeps SFTP only (no port forwarding, no X11), and optionally grants one passwordless sudo command for reloads. You can preview the whole script in the console before running it.The script is public. Read it before you run it: github.com/jenawant-rgb/sethttps-agent — it supports--dry-run(prints every change) and--uninstall. -
Register the node and issue
Add a deploy node with host, port, the SFTP user and password, the target directory (e.g.
/etc/nginx/ssl/example.com) and an optional reload command. Passwords are encrypted at rest and never returned by the API.Then click Issue on the domain. Issuance takes seconds; if the domain is bound to a node, the certificate is uploaded right after it is issued.
What lands on your server
| File | Contents | Used as |
|---|---|---|
example.com_cert.pem | leaf certificate | debugging only |
example.com_full_chain.pem | leaf + intermediates | ssl_certificate |
example.com_key.pem | private key | ssl_certificate_key |
server {
listen 443 ssl;
http2 on;
server_name example.com *.example.com;
ssl_certificate /etc/nginx/ssl/example.com/example.com_full_chain.pem;
ssl_certificate_key /etc/nginx/ssl/example.com/example.com_key.pem;
ssl_protocols TLSv1.2 TLSv1.3;
add_header Strict-Transport-Security "max-age=31536000" always;
}
Reload is yours
inotifywait watcher, or from a systemd timer. Copy-paste scripts for all three are in
Nginx deployment.
Verify what is actually being served:
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null \
| openssl x509 -noout -subject -issuer -dates
Renewals
Certificates are checked daily at 03:00 and renewed when they are within 10 days of expiry, then re-uploaded to every node bound to that domain. Renewals do not consume quota.
FAQ
Can I use SSH keys instead of a password?
Not yet — the current deploy path uses password authentication over SFTP. The setup script still restricts what that account can do: chrooted directory, SFTP only, no shell.
Do you support HTTP-01?
No. DNS-01 is what makes wildcard certificates possible without exposing port 80, and it is the only challenge type the platform implements.
Kubernetes / Docker Compose?
This is built for plain Nginx/Apache on VPSes. If you are on Kubernetes, cert-manager is the better answer; for Caddy or Traefik, their built-in ACME is simpler.