Automate Let’s Encrypt Wildcard Certificate creation with Ionos DNS Rest API

Florian Storz
Apr 6 · 9 min read
Photo by Markus Spiske at Unsplash

At the end of the day, the goals are simple: safety and security. - Jodi Rell

The majority of page views on the Internet are using encrypted connections.


A website has to provide a certificate, issued by a trusted certification authority to establish those connections.

Until a few years ago, you only got such certificates with an annual fee for issuing from commercial companies like GeoTrust, DigiCert, etc.

With Let’s Encrypt, an open-source certification authority has been available since the end of 2015, which provides free certificates via a more automated protocol.

To avoid the effort of managing many subdomains and their associated certificates, there is the option of using so-called wildcard certificates. However, applying for such certificates is a bit more complicated and was previously only possible through manual interaction with the DNS provider Ionos in combination with Let’s Encrypt.

What are wildcard certificates?

Each certificate has a unique name (the so-called “CN — Common Name”), which represents the domain that is to be protected by the certificate.

For example, if a website is accessed under ``, the common name of the associated certificate must be ``. Now, if a website is provided under ``, it needs its own certificate with the common name ``. The website under the subdomain cannot be protected by the top-level domain (TLD) certificate.

If a company uses many subdomains, it can become much of administrative work to maintain all the certificates of the individual subdomains. For this reason there are the so-called wildcard certificates.

The name already implies the functionality of this special type. If the CN contains e.g. the value `CN=*`, the TLD and all direct subdomains of the TLD are automatically protected by this certificate.

What is Let’s Encrypt?

In contrast, since the end of 2015, there is an open-source certification authority called Let’s Encrypt. Let’s Encrypt is a free, automated and open certification authority provided by the Internet Security Research Group (ISRG).

Let’s Encrypt uses the Automated Certificate Management Environment (ACME) protocol, which was standardized in RFC 8555, to validate the ownership of a domain. Since March 2018, Let’s Encrypt also offers wildcard certificates using the ACMEv2 protocol (see also Let’s Encrypt blog post).

How to request a (wildcard) certificate at Let’s Encrypt?

With the DNS Challenge, validation is accomplished by setting dedicated DNS records. This means that during the process a TXT entry must be created, e.g. for the domain `` with a unique value defined by Let’s Encrypt. It then checks whether the specified value can be retrieved via the DNS system under the given domain, to ensure that the person making the request has access to the domain and is therefore authorized to carry out the process.

Workflow until now with Let’s Encrypt and Ionos DNS

The Let’s Encrypt certificates are only valid for 3 months. Therefore, this process must be performed regularly and manually.

The following steps are showing how the steps looked like so far.

  • In order to create or delete DNS entries, authentication at the web UI and navigation to the DNS management.
  • The validation process is started e.g. with Certbot by executing the following command (replace `<your.domain>` with the desired TLD)
certbot certonly \
-d *.<your.domain> \
— preferred-challenges dns \
— manual
  • During the DNS challenge protocol, the process is paused for a short time
    so that a TXT entry with a value defined by Let’s Encrypt (`<acme-challenge-value>`) can be entered in the DNS under a defined sub-domain (`_acme-challenge.<your.domain>`).
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator manual, Installer None
Obtaining a new certificate
Performing the following challenges:
dns-01 challenge for <your.domain>
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please deploy a DNS TXT record under the name
_acme-challenge.<your.domain> with the following value:
<acme-challenge-value> Before continuing, verify the record is deployed.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Press Enter to Continue
  • The values are entered and saved in the Ionos web UI.
  • When the DNS entries have been saved, the process can be continued. The certificate is stored in the filesystem after the DNS entries have been successfully validated.
Waiting for verification...
Cleaning up challenges

- Congratulations! Your certificate and chain have been saved at:
Your key file has been saved at:
Your cert will expire on 2019-08-01. To obtain a new or tweaked
version of this certificate in the future, simply run certbot
again. To non-interactively renew *all* of your certificates, run
"certbot renew"
- If you like Certbot, please consider supporting our work by:

Donating to ISRG / Let's Encrypt: <>
Donating to EFF: <>
  • After the DNS challenge has finished, the created DNS entries should be deleted again. The deletion of the entries needs to be done manually in the Ionos web UI.

The new Ionos DNS API

In the Developer Portal of Ionos you can find a section for the DNS API with a Swagger UI. For an easier start, a “Getting Started” is provided, which provides some details on how to use and register for the API.

In order to use the DNS API, a registration must be completed. On the page for retrieving the associated API keys, you will be directed to the contact page of Ionos for this purpose.

Hint: In our own experience, the registration can only be done via the support hotline, since the activation of the API is a free “order”!

After successful ordering, the “access key” can be requested in the Developer Portal via the “Create a new key” button. The key consists of a `publicprefix` and a `secret`. The secret is only displayed once and should be stored securely.

Automation Scripts

We want to show you such shell scripts, which can be used to create wildcard certificates with the DNS provider Ionos in an automated way and how the scripts can be used in combination with Certbot.

Auth Hook

Precondition: On the system, which executes the script, curl & python must be installed!

Execution note: To display debug logs, remove the `#` character before the command `set -x`.

Auth Hook Shell Script

In the next step, the identifier for the zone is requested from Ionos via the DNS API. This identifier is needed to create DNS entries in this zone via the API.

The TXT DNS entry is then created with the validation token under the subdomain expected by Let’s Encrypt (`_acme-challenge.<your.domain>`).

Finally, the identifier of the zone is written to a temporary file, which is later used for the cleanup.

#set -x


# Strip only the top domain to get the zone id
ZONE_NAME=$(expr match "$CERTBOT_DOMAIN" '.*\.\(.*\..*\)')
# When already the TLD then use it
if [ -z "$ZONE_NAME" ]; then

# Get the Ionos zone id
ZONE_RESPONSE=$(curl -s -X GET "$API_URL/zones" \
-H "Accept: application/json")
| python -c "import sys,json;response=json.load(sys.stdin);print(next((x for x in response if x['name']=='$ZONE_NAME'))['id'])")

# Create TXT record
RECORD_CREATE_RESPONSE=$(curl -s -X POST "$API_URL/zones/$ZONE_ID/records" \
-H "Content-Type: application/json" \
--data '[{"name": "'"$CREATE_DOMAIN"'", "type": "TXT", "content": "'"$CERTBOT_VALIDATION"'", "ttl": 3600, "prio": 100, "disabled": false}]')

# Save info for cleanup

# Sleep to make sure the change has time to propagate over to DNS
sleep 25

Cleanup Hook

Precondition: On the system, which executes the script, curl & python must be installed!

Execution note: To display debug logs, remove the `#` character before the command `set -x`.

Cleanup Hook Shell Script

If this exists, all identifiers of the DNS entries that were created for the validation of the domain are retrieved for this zone via the DNS API.

Finally, all DNS entries found are deleted using their identifiers via the DNS API.

#set -x


if [ -f /tmp/CERTBOT_$CERTBOT_DOMAIN ]; then

# request the created records
RECORD_GET_RESPONSE=$(curl -s -X GET "$API_URL/zones/$ZONE_ID?recordName=$CREATE_DOMAIN&recordType=TXT" \
-H "Accept: application/json")
| python -c "import sys,json;records=json.load(sys.stdin)['records'];print('\n'.join([x['id'] for x in records]))")

# Remove the challenge TXT record from the zone
if [ -n "$ZONE_ID" -a -n "$RECORD_IDS" ]; then
echo "$RECORD_IDS" \
| xargs -n1 -I {} curl -s -X DELETE "$API_URL/zones/$ZONE_ID/records/{}" \


  • A folder for the Let’s Encrypt certificate structure must be created. In our example this is located under `/opt/letsencrypt/cert`.
  • A folder where the scripts are located. In our example these are located under `/opt/letsencrypt/scripts` and are executable
    (`chmod +x /opt/letsencrypt/scripts/*.sh`) .
    -> `/opt/letsencrypt/scripts/`
    -> `/opt/letsencrypt/scripts/`
  • API access must have been requested (see above) and the `<publicprefix>` and `<secret>` must be set in the following code block.
    NOTE: A dot (.) must be placed between publicprefix and secret!
  • An email for expiration notifications and as identifier for a Let’s Encrypt account must be set in the following code block (`<email-address>`)
  • The domain for which the certificate is to be created must be set in the following code block (`<your.domain>`)

Execution note: Since the Certbot docker image does not have the tool curl installed, it has to be added additionally. The easiest way to do this is to add the `apk add curl` command in the auth hook script, e.g. in line 3. Alternatively, you could create your own Docker image, which installs the curl tool in the associated Dockerfile.

docker run -i --rm \
-v /opt/letsencrypt/cert:/etc/letsencrypt \
-v /opt/letsencrypt/scripts:/tmp/scripts \
-e "API_KEY=<publicprefix>.<secret>" \
certbot/certbot \
certonly \
--keep-until-expiring \
--preferred-challenges dns \
--non-interactive \
--agree-tos \
-m <email-address> \
--manual \
--manual-auth-hook /tmp/scripts/ \
--manual-cleanup-hook /tmp/scripts/ \
-d *.<your.domain>

After successful validation, the certificate, the complete certificate chain and the corresponding private key are located in the directory `/opt/letsencrypt/cert/live/<your.domain>`.


For example, the command shown above can be executed regularly using a cron job on a server. This prevents the certificate from expiring and the website visitors from receiving an error message/warning.

The implementation of a native plugin for the Certbot tool would be best, but until then, the scripts shown can be used 🙂

Florian Storz is writing for the devlix Blog at
This article was published first here (german):

Logo of devlix GmbH
devlix GmbH: quality, consulting, development

devlix Blog

About trends and best practices in software development

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store