Automatic HTTPS
Caddy automatically enables HTTPS for all your sites, given that some reasonable criteria are met:
- The hostname:
- is not empty
- is not localhost
- is not an IP address
- has no more than 1 wildcard (
*
) - wildcard must be left-most label
- The port is not explicitly 80
- The scheme is not explicitly http
- TLS is not turned off in site's definition
- Certificates and keys are not provided by you
- Caddy is able to bind to ports 80 and 443 (unless you use the DNS challenge)
Caddy will also redirect all HTTP requests to their HTTPS equivalent if the plaintext variant of the hostname is not defined in the Caddyfile.
All pertinent assets are fully managed, including renewals—no action is required by you. Here's a 28-second video showing how it works:
Topics:
- Things to Know / FAQ
- DNS Challenge
- On-Demand TLS
- Obtaining Certificates
- Renewing Certificates
- Revoking Certificates
- OCSP Stapling
- HTTP Strict Transport Security
Things to Know / FAQ
In order to fully enjoy this flagship feature, please read the following.
Ports 80 and 443 must be externally open
By default, Caddy will bind to ports 80 and 443 to serve HTTPS and redirect HTTP to HTTPS. This usually requires privilege escalation. On Linux systems, you can give Caddy permission to bind to port 80 and 443 without being root using setcap, like so: setcap cap_net_bind_service=+ep caddy
. Don't forget to configure all relevant firewalls to allow Caddy to use these ports for incoming and outgoing connections! Caddy must have claim on at least one of these ports to obtain certificates unless you enable the DNS challenge OR forward ports 80 and 443 to different ports internally (in which case you can change the HTTP and HTTPS ports using CLI flags). Although technically only one of these ports is absolutely required, unavailability of one port may result in temporarily-degraded certificate management results unless the associated ACME challenge is disabled, but should not ultimately affect uptime.
The .caddy folder
Caddy will create a folder in your home directory called .caddy
. It uses this to store and manage cryptographic assets required to serve your site privately over HTTPS. Your sites' certificates and private keys are stored here. Take care to back up and protect this folder. If there is no home folder, the .caddy folder is created in the current working directory unless $CADDYPATH
is set. The home folder is learned from the environment ($HOME
or %HOMEPATH%
). Multiple Caddy instances can use or mount the acme
subfolder as a disk and Caddy will automatically share the certificates and coordinate maintenance between them.
Testing, developing, and advanced setups
To test or experiment with your Caddy configuration, make sure you use the -ca
flag to change the ACME endpoint to a staging or development URL, otherwise you are likely to hit rate limits which can block your access to HTTPS for up to a week. This is especially common when using process managers or containers. Caddy's default CA is Let's Encrypt, which has a staging endpoint that is not subject to the same rate limits.
Behind a load balancer or proxy
If Caddy is behind other infrastructure like a load balancer, it may have trouble obtaining certificates. It is your responsibility, then, to ensure SSL certificates are obtained and properly set up on all machines. In most cases like these, we recommend using the DNS challenge (described below) to obtain certificates. It's not used by default, but it's very easy to configure. If you have a fleet of Caddy instances, they will automatically coordinate certificate management as long as they share (mount) the same $CADDYPATH/acme folder.
Sharing certificates between multiple Caddy instances
As of version 0.10.12, Caddy supports using automatic HTTPS in a fleet/cluster configuration. As of version 0.11.2, this is done via clustering plugins. For example, Caddy can join a cluster by using the file system, Amazon S3, Consul, and others through these plugins. Simply build Caddy with your desired clustering plugin and set the CADDY_CLUSTERING
environment variable. See the docs for your clustering plugin to learn how to configure it. Also see which storage backends Caddy supports for TLS assets.
Wildcard certificates
Caddy can obtain and manage wildcard certificates when it is configured to serve a site with a qualifying wildcard name. A site name qualifies for a wildcard if only its left-most domain label is a wildcard. For example, *.example.com
qualifies, but these do not: sub.*.example.com
, foo*.example.com
, *bar.example.com
, *.*.example.com
, etc. To get a wildcard, you simply need to enable the DNS challenge (described below; it's very easy). We recommend using wildcards only when you have so many subdomains that you would encounter CA rate limits trying to obtain certificates for them all. If you have many subdomains configured differently in your Caddyfile, you can also force a wildcard for them by using the wildcard
subdirective of the tls directive.
Transparency reports
When Caddy obtains a certificate from a CA that publishes certificate transparency logs, it is requisite that your domain name and/or IP address will be included in those logs, as they are not considered private information. (Let's Encrypt is one such CA.) This is a good thing; certificate transparency reports keep the CAs accountable.
DNS Challenge
There are multiple challenge types by which Caddy can obtain certificates. Caddy uses all but one of them without any configuration; another one—the DNS challenge—requires configuration and can be used when the other challenge types would fail. Caddy supports many DNS providers.
To use the DNS challenge, you must do three things. 1) Download Caddy with your provider plugged in. 2) Tell Caddy which provider to use; this is done in the Caddyfile. 3) Give Caddy credentials to access your account to solve the challenge; this is done with environment variables.
Enabling the DNS Challenge
In your Caddyfile, you will use the tls directive with the dns keyword like so:
tls {
dns provider
}
Replace "provider" with the name of your DNS provider (in the table below). You will also need to set environment variables with your account credentials:
Provider | Name to Use in Caddyfile |
Environment Variables to Set |
---|---|---|
Aurora DNS by PCExtreme | auroradns | AURORA_USER_ID AURORA_KEY AURORA_ENDPOINT (optional) |
Azure DNS | azure | AZURE_CLIENT_ID AZURE_CLIENT_SECRET AZURE_SUBSCRIPTION_ID AZURE_TENANT_ID |
Cloudflare | cloudflare | CLOUDFLARE_EMAIL CLOUDFLARE_API_KEY |
CloudXNS | cloudxns | CLOUDXNS_API_KEY CLOUDXNS_SECRET_KEY |
DigitalOcean | digitalocean | DO_AUTH_TOKEN |
DNSimple | dnsimple | DNSIMPLE_EMAIL DNSIMPLE_OAUTH_TOKEN |
DNS Made Easy | dnsmadeeasy | DNSMADEEASY_API_KEY DNSMADEEASY_API_SECRET DNSMADEEASY_SANDBOX (true/false) |
DNSPod | dnspod | DNSPOD_API_KEY |
DynDNS | dyn | DYN_CUSTOMER_NAME DYN_USER_NAME DYN_PASSWORD |
Gandi | gandi / gandiv5 | GANDI_API_KEY / GANDIV5_API_KEY |
GoDaddy | godaddy | GODADDY_API_KEY GODADDY_API_SECRET |
Google Cloud DNS | googlecloud | GCE_PROJECT GCE_DOMAIN GOOGLE_APPLICATION_CREDENTIALS (or GCE_SERVICE_ACCOUNT_FILE) |
Lightsail by AWS | lightsail | AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN (optional) DNS_ZONE (optional) |
Linode | linode | LINODE_API_KEY |
Namecheap | namecheap | NAMECHEAP_API_USER NAMECHEAP_API_KEY |
NS1. | ns1 | NS1_API_KEY |
Name.com | namedotcom | NAMECOM_USERNAME NAMECOM_API_TOKEN |
OVH | ovh | OVH_ENDPOINT OVH_APPLICATION_KEY OVH_APPLICATION_SECRET OVH_CONSUMER_KEY |
Open Telekom Cloud Managed DNS |
otc | OTC_DOMAIN_NAME OTC_USER_NAME OTC_PASSWORD OTC_PROJECT_NAME OTC_IDENTITY_ENDPOINT (optional) |
PowerDNS | pdns | PDNS_API_URL PDNS_API_KEY |
Rackspace | rackspace | RACKSPACE_USER RACKSPACE_API_KEY |
rfc2136 | RFC2136_NAMESERVER RFC2136_TSIG_ALGORITHM RFC2136_TSIG_KEY RFC2136_TSIG_SECRET |
|
Route53 by AWS | route53 | AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY |
Vultr | vultr | VULTR_API_KEY |
When you configure the DNS challenge, Caddy will use that challenge type exclusively. Note that some providers may be slow to apply changes (on the order of minutes).
On-Demand TLS
Caddy pilots a new technology called On-Demand TLS. This means Caddy can obtain a certificate for your site during the first TLS handshake for a hostname that does not yet have a certificate.
To enable on-demand TLS, use the tls
directive with either max_certs
or ask
. For example, your Caddyfile might look like this:
*.example.com
proxy / localhost:4001 localhost:4002
tls {
max_certs 10
}
This Caddyfile will proxy all requests on subdomains to example.com
to your backends for the first 10 unique hostnames. This means you can dynamically provision new DNS records, and they will just start working with HTTPS. Unlike wildcard certificates, on-demand certificates are not limited to subdomains.
You could also use ask
to query a local backend whether a hostname should be allowed to get a certificate:
tls {
ask http://localhost:9005/allowed
}
If the HTTP request returns 200, a certificate will be requested, on-demand, from the CA. At least one of max_certs
or ask
is required for On-Demand TLS.
On-Demand TLS is a special kind of managed TLS, so all the requirements above still apply except for the one about not providing your own certificate and key: you may supplement on-demand TLS with your own certificates. And like regular managed TLS, HTTP will be redirected to HTTPS.
Future support: This feature relies on the CA issuing certificates without delay. If instantaneous issuance becomes uncommon among ACME CAs, we may discontinue this feature in Caddy.Once a certificate is obtained on-demand, it is stored on disk just like any other managed certificates. It is also stored in memory for quick retrieval during future handshakes.
On-Demand TLS is subject to these rate limits:
- At most one certificate challenge happens at a time.
- After 10 certificates are successfully obtained, new certificate challenges will not happen until 10 minutes after the last successful challenge.
- A name that fails a challenge will not be allowed to be attempted again for 5 minutes.
Note that rate limits are reset when the process exits. Using the -log
flag is recommended, since all certificate challenges are logged. Note that these built-in rate limits do not apply if an ask URL is specified in the configuration. When using ask, your endpoint must return a 200 status code for the name in order for a certificate validation to be performed.
The rest of this page explains more details about automatic HTTPS, but it is not required knowledge for using Caddy.
Obtaining Certificates
To serve a site over HTTPS, a valid SSL certificate is required from a trusted certificate authority (CA). When Caddy starts, it obtains certificates for eligible sites from Let's Encrypt. The following process is nearly entirely automatic and on by default.
If necessary, Caddy creates an account on the CA's server with (or without) your email address. Caddy may have to prompt you for an email address if it is not able to find one from the Caddyfile, in the command line flags, or on disk from a previous run. Use the -agree
flag along with providing an email address to ensure you are not prompted to agree to terms, when using in automated environments. But that should only be needed the first time automatic HTTPS is used.
Once the formalities are taken care of, Caddy generates a private key and a Certificate Signing Request (CSR) for each site. The private keys never leave the server and are safely stored on your file system.
Caddy establishes a link with the CA's server. A brief cryptographic transaction takes place to prove that Caddy really is serving the sites it says it is. Once the CA server verifies this, it sends the certificate for that site over the wire to Caddy, which tucks it neatly away in the .caddy folder.
This process usually takes a few seconds per domain, so once a certificate has been obtained for a site, it is simply loaded from disk and reused the next time Caddy is run. In other words, this delayed startup is a one-time event. If an existing certificate needs to be renewed, Caddy takes care of it right away.
Caddy synchronizes the obtaining of certificates between multiple instances as long as they share the same .caddy/acme folder on disk. This means multiple instances requiring the same certificate will not both request one from the CA, and they will share the same copy from disk.
Renewing Certificates
Certificates are only valid for a limited time, so Caddy checks each certificate on a regular basis and automatically renews certificates that expire soon (30 days). If renewal fails, Caddy will keep trying.
Once Caddy gets the new certificate, it swaps out the old certificate with the new one. This replacement incurs zero downtime.
As with obtaining certificates, Caddy coordinates renewals when used in a cluster, as long as the instances share the same .caddy/acme folder. Only one instance will actually perform the renewal, then the others will reload the updated certificate.
Revoking Certificates
Caddy does not automatically revoke a certificate, but you can do this with the -revoke
option, specifying the domain name. This is only necessary if your site's private key or the certificate authority was compromised. Upon revocation, Caddy deletes the certificate file from disk to prevent it from being used at next run.
OCSP Stapling
Caddy staples OCSP information of all certificates containing an OCSP link to protect the privacy of your sites' clients and reduce stress on OCSP servers. The cached OCSP status is checked on a regular basis, and if there is a change, the server will staple the new response.
When new OCSP responses are obtained, Caddy persists the staple to disk so that it can weather long OCSP responder outages. Like certificates, persisted OCSP responses are fully maintained within the .caddy folder.
HTTP Strict Transport Security
HTTP Strict Transport Security (HSTS) is a web security policy mechanism which helps to protect websites against protocol downgrade attacks and cookie hijacking. Enabling HSTS declares that web browsers should only interact with the server using a secure HTTPS connection, and never via an insecure HTTP connection. The policy specifies a period of time during which the server must be accessed in a secure fashion.
Caddy does not enable HSTS by default, because if you wish to use the domain without HTTPS, HSTS having been enabled and remembered by a browser means the browser will not allow connections to your server. HSTS should only be enabled in a production environment when you know that you won't want to disable HTTPS in the future. It can easily be enabled by adding the header below to your Caddyfile.
header / Strict-Transport-Security "max-age=31536000;"