SetHttps
Quickstart · ~10 min

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

Free plan: 1 domain, 10 deploy nodes, unlimited renewals, no credit card. Your live quota is shown in the console.

Four steps

  1. 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 covering example.com and *.example.com.

    The console then shows a CNAME target for this domain, e.g. a1b2c3d4.sethttps.com.

  2. Publish one DNS record

    TypeNameValueTTL
    CNAME_acme-challengethe value shown in the console300

    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
  3. 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 nologin user, 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.
  4. 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

FileContentsUsed as
example.com_cert.pemleaf certificatedebugging only
example.com_full_chain.pemleaf + intermediatesssl_certificate
example.com_key.pemprivate keyssl_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

By design, SetHttps never executes commands on your server. It only uploads files over SFTP. Once the new certificate is on disk you need to reload the web server — manually, with an 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.