# Automatic TLS

> Source: https://ferron.sh/docs/use-cases/https/automatic-tls

Ferron supports automatic TLS via ACME-compatible Certificate Authorities such as Let's Encrypt. It supports three challenge types:

- **HTTP-01** (default): serves a token at `/.well-known/acme-challenge/`
- **TLS-ALPN-01**: responds with a self-signed cert during the TLS handshake
- **DNS-01**: creates a TXT record at `_acme-challenge.<domain>` (required for wildcard domains)

Ferron caches certificates and renews them automatically before expiration.

Below is the example Ferron configuration for automatic TLS with the production ACME directory:

```ferron
example.com {
    tls {
        provider acme
        challenge http-01
        contact admin@example.com
    }

    root /var/www/html
}
```

Or simply (Ferron enables automatic TLS via ACME by default for public hosts):

```ferron
example.com {
    # Automatic TLS is enabled by default, no explicit TLS directive needed

    root /var/www/html
}
```

> [!important]
> Keep `cache` on persistent storage and make sure Ferron can read/write it, otherwise certificate renewals may fail or repeat unnecessarily.

## Note about Cloudflare proxies (and other HTTPS proxies)

Ferron uses the HTTP-01 ACME challenge by default. The challenge requires the server to be reachable on port 80. If your website is behind a TLS-terminating proxy, the HTTP-01 challenge may not work unless port 80 is accessible. Cloudflare in proxy mode is such a case.

You can use the TLS-ALPN-01 challenge instead. It works at the TLS handshake level and only requires port 443:

```ferron
example.com {
    tls {
        provider acme
        challenge tls-alpn-01
        contact admin@example.com
    }

    root /var/www/html
}
```

## Using Ferron as an ACME client for other servers

If you run other servers alongside Ferron that support TLS but not automatic TLS, use Ferron as an ACME client. It gets TLS certificates for those servers:

```ferron
example.com {
    tls {
        provider acme
        challenge http-01
        contact admin@example.com

        save /tmp/server.crt /tmp/server.key

        # Optionally, run a command after obtaining the certificate:
        # post_obtain_command "/etc/reload-server.sh"
    }

    root /var/www/html
}
```

If you give only one path for `save`, the key path defaults to the certificate path with a `.key` extension. After Ferron gets a certificate, it writes the private key with `0600` permissions on Unix.

## Automatic TLS on demand

Ferron can also get certificates on demand after a client accesses a hostname for the first time (`on_demand`). This helps multi-tenant setups where hostnames are not fully known in advance.

When enabling on-demand issuance, configure `on_demand_ask` to avoid abuse. Ferron calls the configured URL with the `domain` query parameter, and your endpoint should allow or deny issuance for that domain.

```ferron
*.example.com {
    tls {
        provider acme
        challenge http-01
        contact admin@example.com

        on_demand
        on_demand_ask https://auth.example.com/check-cert
    }

    root /var/www/html
}
```

## DNS providers (DNS-01 challenge)

Ferron supports the DNS-01 ACME challenge for automatic TLS. Wildcard certificates require this challenge. The DNS-01 challenge needs a DNS provider inside the `tls` block.

Below is an example configuration for DNS-01 with Cloudflare:

```ferron
*.example.com {
    tls {
        provider acme
        challenge dns-01
        contact admin@example.com

        dns {
            provider cloudflare
            api_key "EXAMPLE_API_KEY"
        }
    }

    root /var/www/html
}
```

> [!important]
> Before you request certificates, make sure your public DNS records point to the Ferron server. The ACME challenges fail if traffic goes elsewhere.

> [!info]
> For the DNS providers Ferron supports and their configuration properties, see the [configuration reference](https://ferron.sh/docs/configuration/security/acme.md).

## Certificate caching

Ferron caches certificates both in-memory and on disk (when you configure a `cache` path). This makes sure certificates survive restarts and renew automatically.

```ferron
example.com {
    tls {
        provider acme
        challenge http-01
        contact admin@example.com
        cache /var/cache/ferron-acme
    }
}
```