# LetsEncrypt DNS challenge in production

## LetsEncrypt DNS challenge in production

{% hint style="info" %}
Before you begin please make sure github environment was created using `yarn environment:init` script, check [https://github.com/opencrvs/documentation/blob/master/v2.0.0/setup/3.-installation/3.3-set-up-a-server-hosted-environment/4.3.1-create-a-github-environment](https://github.com/opencrvs/documentation/blob/master/v2.0.0/setup/3.-installation/3.3-set-up-a-server-hosted-environment/4.3.1-create-a-github-environment "mention")
{% endhint %}

If you are provisioning a **qa, staging** or **production** environment **behind a VPN** and wish to use LetsEncrypt there are 2 options depending on your DNS server provider.

1. Using Traefik supported DNS challenge APIs
2. Manually creating static LetsEncrypt certs and TXT records

If your DNS is cloud managed using a supported provider, Traefik can use an access token to automatically generate the TXT records required for LetsEncrypt to validate your domain.

#### Traefik supported DNS Challenge APIs

Traefik supports APIs for the following cloud DNS providers and the secrets required can be passed to the Traefik service as environment variables:

{% embed url="<https://doc.traefik.io/traefik/https/acme/#providers>" %}

#### Example configuration Traefik with Cloudflare as DNS provider

In this example, Cloudflare is the configured DNS provider. The environment secret CLOUDFLARE\_API\_KEY is stored as Kubernetes secret in traefik namespace.

1. Make sure you are connected to correct kubernetes cluster, you need to check your kubernetes context:

```
kubectl config current-context
```

Example output: In this output `bob` is your user name, `tmp-k8s-server` is master node name:

```
bob@public-k8s-tmp-k8s-server
```

2. Create a kubernetes secret in `traefik` namespace:

```
kubectl create secret generic cloudflare-api-token-secret --from-literal=api-token=<Cloudflare token> -n traefik
```

* `generic`: is special kubernetes secret type
* `cloudflare-api-token-secret`: : is kubernetes secret name
* `traefik`: is namespace

3. Verify the secret was created:

```
kubectl get secret -n traefik cloudflare-api-token-secret
```

Example output:

```
NAME                          TYPE     DATA   AGE
cloudflare-api-token-secret   Opaque   1      1m
```

4. Update traefik helm chart values by adding following code snippet to `environments/<env name>/traefik/values.yaml`

```yaml
ports:
  # ...
  websecure:
    # ...
    # 👇 Adjust this section at websecure entrypoint
    tls:
      enabled: true
      certResolver: cloudflare

# cloudflare DNS resolver configuration: Official documentation:
# https://doc.traefik.io/traefik/reference/install-configuration/tls/certificate-resolvers/acme/#dnschallenge
certificatesResolvers:
  cloudflare:
    acme:
      # 👇 Provide admin email address
      email: <admin email>
      storage: /certificates/acme.json
      dnsChallenge:
        provider: cloudflare
        delayBeforeCheck: 0
env:
  - name: CLOUDFLARE_API_KEY
    valueFrom:
      secretKeyRef:
        # Provide secret name from previous step
        name: cloudflare-api-token-secret
        # Provide key name inside secret
        key: api-token
  - name: CLOUDFLARE_EMAIL
    # 👇 Provide admin email address
    value: <admin email>
```

See full example at [examples/dev/traefik/values-dns-challenge.yaml](https://github.com/opencrvs/infrastructure/blob/develop/examples/dev/traefik/values-dns-challenge.yaml)

8. Commit and push changes
9. Run "Provision" workflow or deploy traefik manually

#### Manually creating static LetsEncrypt certs and TXT records

If you are not using one of Traefik's supported DNS providers, for example if you are hosting your own DNS server, then you can manually create the LetsEncrypt static files .crt and .key by using the **certbot** tool.

1. Install [certbot](https://certbot.eff.org/instructions) on your laptop
2. Run this command to generate a wildcard LetsEncrypt cert for each of your environment domains:

```
sudo certbot certonly --manual -d <your-domain> -d '*.<your-domain>'
```

The process after that is guided by the CLI. Running the command will give you the following prompt:

```
Please deploy a DNS TXT record under the name:

_acme-challenge.<your-domain>.

with the following value:

<TXT RECORD VALUE HERE>

Before continuing, verify the TXT record has been deployed. Depending on the DNS
provider, this may take some time, from a few seconds to multiple minutes. You can
check if it has finished deploying with aid of online tools, such as the Google
Admin Toolbox: https://toolbox.googleapps.com/apps/dig/#TXT/_acme-challenge.<your-domain>.
Look for one or more bolded line(s) below the line ';ANSWER'. It should show the
value(s) you've just added.
```

At this point you need to go to control panel of your DNS server and create the TXT record for the domains as instructed.

Once the process succeeds, it should write 2 certificate files `fullchain.pem` and `privkey.pem` to your local machine. The content of these files must be provided to the traefik service at runtime. The process required to implement this is equivalent to the next step: Static TLS certificates.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://documentation.opencrvs.org/v2.0/technical/guides/installation/advanced-topics/tls-ssl-configuration-for-traefik/letsencrypt-dns-challenge-in-production.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
