Effortless HTTPS with Caddy: Automatic TLS for Web Servers

Caddy is revolutionary as the first and only web server that implements HTTPS automatically and by default.

Automatic HTTPS simplifies web server security by provisioning TLS certificates for all your sites and ensuring their seamless renewal. It also takes care of HTTP to HTTPS redirection automatically! Caddy prioritizes secure and modern defaults, eliminating downtime, complex configurations, or the need for separate tools.

See it in action with this brief 28-second video:

Menu:

Overview

Out of the box, Caddy serves every site over HTTPS.

  • Caddy provides HTTPS for IP addresses and local/internal hostnames using self-signed certificates, automatically trusted locally where permitted.
    • Examples: localhost, 127.0.0.1
  • For public DNS names, Caddy leverages certificates from trusted public ACME Certificate Authorities (CAs) such as Let’s Encrypt or ZeroSSL to enable HTTPS.
    • Examples: example.com, sub.example.com, *.example.com

Caddy manages certificate renewals automatically and handles HTTP (default port 80) to HTTPS (default port 443) redirects for you.

Understanding Local HTTPS:

  • Caddy might request administrator privileges to install its unique root certificate into your system’s trust store. This is a one-time process per root CA and can be reversed at any time.
  • Clients that do not trust Caddy’s root CA certificate will encounter security warnings when accessing the site.

For Public Domain Names, Automatic HTTPS Requires:

  • Your domain’s A/AAAA DNS records must point to your server.
  • Ports 80 and 443 must be publicly accessible.
  • Caddy must be able to bind to ports 80 and 443 (or these ports are forwarded to Caddy).
  • The data directory must be writable and persistent for Caddy.
  • Your domain name must be correctly configured within Caddy’s configuration.

If these conditions are met, your sites will be served over HTTPS automatically with Caddy Https. No additional configuration is needed. It simply works!

Because HTTPS relies on a shared public infrastructure, understanding the details on this page is crucial for server administrators to prevent and troubleshoot potential issues, and to configure advanced deployments effectively.

Activation of Automatic HTTPS

Caddy intelligently activates automatic HTTPS when it detects a domain name (hostname) or IP address that it is configured to serve. There are various methods to inform Caddy about your domain or IP, depending on your setup and configuration approach:

Automatic HTTPS activation can be prevented in specific scenarios:

  • Explicitly disabling automatic HTTPS via JSON or Caddyfile configurations.
  • Not specifying any hostnames or IP addresses in the Caddy configuration.
  • Configuring Caddy to listen exclusively on the HTTP port.
  • Using the http:// prefix for the site address in the Caddyfile.
  • Manually loading certificates (unless ignore_loaded_certificates is enabled).

Special Cases to Consider:

How Automatic HTTPS Works: Effects and Mechanisms

When automatic HTTPS is enabled in Caddy, several key processes are initiated to secure your web server:

Automatic HTTPS in Caddy is designed to complement, not override, your explicit configurations. It intelligently augments your existing setup to ensure HTTPS is seamlessly integrated.

If you already have a server configured to listen on the HTTP port, Caddy will smartly insert HTTP-to-HTTPS redirect routes. These redirects are placed after your existing routes that have host matchers but before any user-defined catch-all routes. This ensures that existing HTTP configurations are respected while seamlessly adding HTTPS redirection.

Caddy provides flexibility to customize or disable automatic HTTPS as needed. For example, you can choose to skip automatic HTTPS for specific domain names or disable redirects. In Caddyfile configurations, these adjustments can be made using global options.

Hostname Requirements for Automatic HTTPS Certificates

To be eligible for fully-managed certificates through Caddy’s automatic HTTPS, hostnames (domain names) must adhere to specific criteria:

  • Must not be empty.
  • Must consist only of alphanumeric characters, hyphens, dots, and the wildcard symbol (*).
  • Must not start or end with a dot, as per RFC 1034.

Furthermore, to qualify for publicly-trusted certificates, hostnames must also meet these additional conditions:

  • Must not be localhost or any of its variations (including .localhost, .local, and .home.arpa TLDs).
  • Must not be an IP address.
  • Can contain only a single wildcard *, and it must be positioned as the leftmost label.

Local HTTPS for Development and Internal Networks

Caddy’s automatic HTTPS extends to internal and local hosts, ensuring secure connections even for non-public sites. This is particularly useful for development environments or internal networks where publicly-trusted certificates are not applicable or necessary.

For non-public sites, Caddy generates its own Certificate Authority (CA) to sign certificates, maintaining HTTPS encryption. This local CA setup includes a root and intermediate certificate, with leaf certificates for individual sites signed by the intermediate. These certificates are securely stored within Caddy’s data directory at pki/authorities/local.

Caddy’s local CA leverages Smallstep libraries for robust certificate management.

Local HTTPS operation in Caddy differs from public HTTPS as it does not involve ACME or DNS validation. Trust is established locally within your machine or network by trusting Caddy’s root certificate.

CA Root in Local HTTPS

The root CA’s private key is generated using cryptographically secure methods and stored with restricted permissions. It’s loaded into memory only for signing operations and then securely removed from memory.

While Caddy can be configured to sign directly with the root key for compatibility with older clients, this is disabled by default for enhanced security. The root key primarily signs intermediate certificates.

Upon its first use, Caddy attempts to install the root certificate into the system’s local trust store. If permissions are lacking, it will prompt for a password. This behavior can be disabled if desired. If installation fails due to insufficient privileges, the caddy trust command can be used to retry with elevated privileges.

Once installed, Caddy’s root CA appears as “Caddy Local Authority” in your trust store (customizable via configuration). It can be uninstalled at any time using the caddy untrust command.

Automatic installation into local trust stores is a convenience feature and may not always succeed, especially in containerized environments or when Caddy runs as an unprivileged service. Ultimately, managing trust for internal PKI is the system administrator’s responsibility, which is beyond the scope of the web server itself.

CA Intermediates in Local HTTPS

In addition to the root certificate, Caddy generates an intermediate certificate and key. This intermediate certificate is used to sign leaf certificates for individual sites.

Unlike the root certificate, intermediate certificates have shorter lifespans and are automatically renewed by Caddy as needed, ensuring continuous secure operation.

Testing Your Caddy HTTPS Configuration

When testing or experimenting with your Caddy configuration, it’s highly recommended to switch the ACME endpoint to a staging or development URL. This precaution prevents you from hitting rate limits, which could temporarily block HTTPS access for up to a week, depending on the specific rate limit exceeded.

Caddy’s default configuration includes Let’s Encrypt as a Certificate Authority. Let’s Encrypt provides a staging endpoint that is specifically designed for testing and is not subject to the same rate limits as their production endpoint.

To use the Let’s Encrypt staging environment, configure the ACME endpoint as follows:

https://acme-staging-v02.api.letsencrypt.org/directory

ACME Challenges: Validating Domain Ownership for Public Certificates

Obtaining publicly-trusted TLS certificates requires validation from a trusted third-party Certificate Authority (CA). This validation process is now automated using the ACME protocol . Caddy supports three types of ACME challenges to validate domain ownership: HTTP, TLS-ALPN, and DNS challenges.

The HTTP and TLS-ALPN challenges are enabled by default in Caddy. When multiple challenges are enabled, Caddy intelligently selects one at random for each certificate request to avoid relying on a single method. Over time, Caddy learns which challenge type is most reliable and will prioritize it, while still falling back to other enabled methods if necessary.

HTTP Challenge

The HTTP challenge verifies domain control by performing a DNS lookup for the hostname’s A/AAAA record. It then attempts to retrieve a temporary cryptographic resource over HTTP on port 80. If the CA successfully retrieves the expected resource, domain control is validated, and a certificate is issued.

For the HTTP challenge to work, port 80 must be publicly accessible to the internet. If Caddy is not directly listening on port 80, any traffic to port 80 must be forwarded to Caddy’s configured HTTP port.

The HTTP challenge is enabled by default in Caddy and requires no additional configuration to function.

TLS-ALPN Challenge

Similar to the HTTP challenge, the TLS-ALPN challenge starts with a DNS lookup for the hostname’s A/AAAA record. It then initiates a TLS handshake on port 443, including specific ServerName and ALPN values in the handshake. Successful retrieval of a temporary cryptographic resource by the CA over this TLS connection confirms domain control, leading to certificate issuance.

The TLS-ALPN challenge requires port 443 to be publicly accessible. If Caddy isn’t directly listening on port 443, traffic to port 443 must be forwarded to Caddy’s HTTPS port.

Like the HTTP challenge, TLS-ALPN is enabled by default and operates without requiring explicit configuration.

DNS Challenge

The DNS challenge offers an alternative validation method that does not require open ports on your server. It involves the CA querying the DNS system for TXT records associated with your domain. To pass the challenge, Caddy must be able to create a specific TXT record with a designated value in your domain’s DNS configuration. If the CA successfully finds this record, domain control is verified, and a certificate is issued.

The DNS challenge is unique as it does not require ports 80 or 443 to be open, and the server requesting the certificate does not need to be publicly accessible. However, it does require configuration. You must provide Caddy with the necessary credentials to access your domain’s DNS provider so it can automatically create and remove the required TXT records. When the DNS challenge is enabled, the HTTP and TLS-ALPN challenges are typically disabled by default to prioritize DNS validation.

ACME CAs adhere to DNS standards when looking up TXT records for DNS challenge verification. This allows for the use of CNAME records to delegate challenge responses to different DNS zones. This delegation can be configured to redirect the _acme-challenge subdomain to another DNS zone. This feature is particularly useful if your primary DNS provider lacks an API or is not supported by Caddy’s DNS plugin ecosystem.

Caddy’s DNS provider support is driven by community contributions. Explore our wiki to learn how to enable the DNS challenge for your specific provider.

On-Demand TLS: Certificates When You Need Them

Caddy pioneered On-Demand TLS, a groundbreaking feature that dynamically obtains TLS certificates during the initial TLS handshake when required. This eliminates the need to pre-configure domain names in your Caddy configuration.

On-demand TLS is invaluable for scenarios where:

  • Domain names are not known in advance when the server starts or reloads.
  • Domain names might not be immediately configured correctly (DNS propagation delays).
  • You do not control the domain names (e.g., serving customer domains).

With on-demand TLS enabled, you don’t need to list domain names in your Caddy configuration to get certificates. When a TLS handshake request arrives for a Server Name Indication (SNI) for which Caddy lacks a certificate, the handshake is temporarily paused. Caddy then dynamically obtains a certificate for that domain to complete the handshake. This initial handshake might take a few seconds, but subsequent handshakes are fast as certificates are cached, reused, and renewed in the background. While future handshakes might trigger background certificate maintenance for renewal, this happens seamlessly without interrupting service if the certificate is not yet expired.

Effective Use of On-Demand TLS

Enabling on-demand TLS requires both activation and restriction configurations to prevent potential abuse.

On-demand TLS is activated through TLS automation policies in JSON configurations or within site blocks using the tls directive in Caddyfile.

To safeguard against abuse, restrictions must be configured. These are set within the automation object in JSON or using the on_demand_tls global option in Caddyfile. Restrictions are global and not configurable per site or domain. A primary restriction method is the “ask” endpoint, where Caddy sends an HTTP request to verify permission to obtain and manage a certificate for the requested domain. This necessitates an internal backend service capable of, for example, querying a database to confirm if a customer is authorized for the requested domain.

Consider the certificate issuance speed of your CA. If issuance takes more than a few seconds, it can impact the initial user experience (for the first client only).

Given its deferred nature and the extra configuration required for abuse prevention, on-demand TLS is best suited for use cases where its dynamic certificate acquisition capabilities are genuinely needed.

Refer to our wiki article for in-depth guidance on effectively leveraging on-demand TLS.

Handling Certificate Management Errors in Caddy HTTPS

Caddy is designed to be resilient and continue operating even when certificate management errors occur.

By default, certificate management tasks are performed in the background. This ensures that certificate operations do not block server startup or slow down site performance. However, it also means that the server might be running even before all certificates are fully provisioned. Background processing enables Caddy to implement robust retry mechanisms with exponential backoff over extended periods.

Here’s a detailed breakdown of Caddy’s error handling process during certificate acquisition or renewal:

  1. Immediate Retry: Caddy first retries the certificate operation once after a brief pause to account for transient issues.
  2. Challenge Type Switch: After the initial retry, Caddy briefly pauses again and then switches to the next enabled ACME challenge type (e.g., from HTTP to TLS-ALPN).
  3. Issuer Fallback: If all enabled challenge types fail, Caddy attempts to use the next configured certificate issuer in its fallback list. By default, this list includes:
    • Let’s Encrypt
    • ZeroSSL
  4. Exponential Backoff: If all issuers are exhausted, Caddy initiates an exponential backoff retry strategy.
    • Retry attempts are spaced out, with a maximum interval of 1 day between attempts.
    • Retries continue for up to 30 days.

During retry attempts with Let’s Encrypt, Caddy intelligently switches to their staging environment to mitigate the risk of hitting rate limits on the production environment. While not a perfect solution, this strategy is generally effective in resolving temporary issues.

ACME challenges inherently take several seconds to complete, and Caddy employs internal rate limiting to prevent accidental abuse. In addition to any rate limits imposed by CAs or user configurations, Caddy implements its own internal rate limit of 10 attempts per ACME account per 10 seconds. This internal limit allows Caddy to efficiently manage certificate requests even for a large number of domains, obtaining certificates gradually but as quickly as possible within the constraints of rate limits.

To conserve resources, Caddy aborts any in-flight tasks, including ACME transactions, whenever the configuration is changed and reloaded. While Caddy is designed to handle frequent configuration reloads, it’s important to be mindful of operational considerations like this. Batching configuration changes can reduce the frequency of reloads and give Caddy sufficient time to complete certificate operations in the background.

Issuer Fallback: Ensuring Certificate Issuance Redundancy

Caddy is unique as the first web server to offer fully-redundant, automatic failover to alternative Certificate Authorities (CAs) if the primary CA fails to issue a certificate.

By default, Caddy is configured to use two ACME-compatible CAs: Let’s Encrypt and ZeroSSL . If Caddy encounters an issue obtaining a certificate from Let’s Encrypt, it automatically attempts to obtain one from ZeroSSL. If both attempts fail, Caddy will back off and retry the process later. You have the flexibility to customize the issuers Caddy uses, either globally or for specific domain names, through configuration.

Certificate and Key Storage in Caddy HTTPS

Caddy securely stores public certificates, private keys, and related assets within its configured storage facility. If no specific storage is configured, Caddy uses a default storage location (refer to the documentation link for details).

For default configurations, it’s crucial to ensure that the $HOME directory is writable and persistent. To aid in troubleshooting, Caddy can output its environment variables at startup if launched with the --environ flag.

Multiple Caddy instances configured to use the same storage automatically share certificate resources and coordinate certificate management as a cluster. This shared storage approach is essential for seamless operation in clustered environments.

Before initiating any ACME transactions, Caddy performs a storage test to verify write access and sufficient capacity. This proactive check helps prevent unnecessary lock contention and ensures smooth certificate operations.

Wildcard Certificates with Caddy HTTPS

Caddy fully supports obtaining and managing wildcard certificates when configured to serve a site with a qualifying wildcard domain name. A domain name is considered valid for a wildcard certificate if only its leftmost label is a wildcard character. For example, *.example.com is valid, while sub.*.example.com, foo*.example.com, *bar.example.com, and *.*.example.com are not.

In Caddyfile configurations, site names are treated literally regarding certificate subject names. A site defined as sub.example.com will prompt Caddy to manage a certificate specifically for sub.example.com, and a site defined as *.example.com will result in Caddy managing a wildcard certificate for *.example.com. You can see practical examples of this in our Common Caddyfile Patterns documentation. For more granular control over certificate subjects and site names (host matchers), the JSON configuration offers advanced options.

Wildcard certificates grant broad authority and should be used judiciously. They are most beneficial when managing a large number of subdomains, where individual certificate management could become complex and potentially lead to CA-enforced rate limits.

Important Note: Let’s Encrypt requires the DNS challenge to issue wildcard certificates. Therefore, when requesting wildcard certificates from Let’s Encrypt using Caddy, you must configure the DNS challenge.

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *