# Issue TLS Certificates using IONOS Cloud Certbot Plugin

Transport Layer Security(TLS), is a pivotal security protocol that ensures the encryption of data transmitted between web browsers like Chrome, Firefox, and web servers.

Employing TLS certificates for all hosted content and applications is imperative. It not only safeguards sensitive information but also fosters trust among users by guaranteeing secure communication channels.

{% hint style="info" %}
**Info:** To obtain a Let’s Encrypt certificate for your domain, verification of ownership is required. This can be achieved through various methods detailed in the [<mark style="color:blue;">Let’s Encrypt documentation</mark>](https://letsencrypt.org/docs/challenge-types/). One commonly used method is the DNS-01 challenge, which necessitates demonstrating control over the domain's DNS by generating a specific value in a TXT record. Utilizing the Certbot plugin facilitates the certificate issuance process by managing TXT records automatically, handling tasks such as creation, removal, renewal, and revocation. Further details on this process can be found in the [<mark style="color:blue;">Certbot documentation.</mark>](https://eff-certbot.readthedocs.io/en/stable). For more information on Cloud DNS Certbot plugin, see [<mark style="color:blue;">Cloud DNS Certbot GitHub</mark>](https://github.com/ionos-cloud/certbot-dns-ionos-cloud).
{% endhint %}

## Target audience

This tutorial is intended to help both developers and technical decision-makers.

## What you will learn

This tutorial will guide you on how to install and configure a simple web server, create an A record for that web server using IONOS Cloud [<mark style="color:blue;">Cloud DNS API</mark>](https://api.ionos.com/docs/dns/v1/), and create an TLS certificate for your web server using [<mark style="color:blue;">Cloud DNS Certbot</mark>](https://docs.ionos.com/sections-test/tutorials/network-services/cloud-dns/certbot). The steps we will follow are:

1. Reserve an IPv4 in your IONOS Cloud setup.
2. Set up a Web Server on Dedicated Core Server in IONOS Cloud.
3. Create an A record for your web server. For information on common record types, see [<mark style="color:blue;">Create records of other types</mark>](https://docs.ionos.com/cloud/network-services/cloud-dns/cloud-dns-faq#what-types-of-dns-records-does-cloud-dns-support).
4. Create an TLS certificate for your web server using IONOS Cloud Certbot Plugin.
5. Add TLS certificate to your web server configuration.
6. Test your TLS certificate.

## Before you begin

Ensure you have the following:

* An IONOS Cloud account. If you do not have an account, you can create one by visiting the IONOS Cloud website.
* A primary zone with IONOS Cloud DNS. If you do not have a primary zone, you can create one using the IONOS Cloud DNS API. For more information, see [<mark style="color:blue;">Create a Primary Zone using IONOS Cloud DNS API</mark>](https://docs.ionos.com/cloud/network-services/cloud-dns/api-how-tos/create-primary-zone). We will refer to this primary zone and primary zone name as `<your-primary-zone>` and `<your-primary-zone-name>`, respectively.
* Make sure to use your own `<zone_id>` and `<your_server_ip>` along with your `<authorization token>`.

## Procedure

{% stepper %}
{% step %}

#### Reserve an IPv4 address in IONOS Cloud

To reserve an IPv4 address in IONOS Cloud, follow these steps:

1\. In the **DCD**, go to **Menu** > **Network Services** > **IP Management**.

2\. In **IP Management**, click **Reserve IPs**, and a new pop-up window appears. Enter the following information:

* **Name:** Enter a suitable name.
* **Number of IPs:** Select the number of IP addresses to be reserved.
* **Region:** Select a region that is the same as the region of your Dedicated Core server. Click **Reserve IPs** to reserve the IP addresses and confirm the reservation by selecting **OK**.

![Reserve IP addresses](https://3040852435-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEpuEvuLJIyhyeRGhmrv1%2Fuploads%2Fgit-blob-9d7629478ea0bd65798a996dd223035f7bebf28a%2FrDNS-IP-reserve.png?alt=media)

3\. Exit the **IP Management** window and return to the IONOS Cloud Workspace.

{% hint style="success" %}
**Expected result:** The **IPv4** address is reserved.
{% endhint %}
{% endstep %}

{% step %}

#### Set up a Dedicated Core Server in IONOS Cloud

{% hint style="info" %}
**Note:**

* The user who creates the server has full root or administrator access rights. A server, once provisioned, retains all its settings (resources, drive allocation, password, and so on), even after server restart at the operating system level.
* The server will only be removed from your virtual data center once you delete it in the DCD.
  {% endhint %}

**1. Create a Dedicated Core server**

Create a Dedicated Core server and configure the server in the **Settings** tab by following the steps in [<mark style="color:blue;">Create a Dedicated Core Server</mark>](https://docs.ionos.com/cloud/compute-services/compute-engine/how-tos/set-up-dedicated-core#create-a-dedicated-core-server).

![Create a Dedicated Core Server](https://3040852435-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEpuEvuLJIyhyeRGhmrv1%2Fuploads%2Fgit-blob-804f0f70d76100c126e5270563f1e8c38654313a%2FrDNS-create-server-by-dragging.png?alt=media)

**2. Dedicated Core Server network settings**

In the [<mark style="color:blue;">DCD</mark>](https://docs.ionos.com/cloud/set-up-ionos-cloud/data-center-designer) > **Inspector** pane on the right, configure the following network details in the **Network** tab.

1\. **Name:** Choose a name unique to this [<mark style="color:blue;">Virtual Data Center (VDC)</mark>](https://docs.ionos.com/support/general-information/glossary-of-terms#virtual-data-center-vdc).

2\. **MAC:** It is automatically assigned during the VM creation.

3\. **LAN:** Select the LAN connection that is connected to the internet by default it is LAN 1.

4\. **Firewall:** By default, the firewall is disabled. To enable firewall rules, make sure that incoming and outgoing traffic is allowed on port 25 for UDP and TCP.

5\. In the IPv4 Configuration, click **Add IP** and select the same IP address that you used to create an A record.

![Dedicated Core Server Network settings](https://3040852435-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEpuEvuLJIyhyeRGhmrv1%2Fuploads%2Fgit-blob-8e1235b6c1aeddf00eeee414fc6960353a98e7b9%2FrDNSdns-vm-network-settings.png?alt=media)

{% hint style="success" %}
**Expected result:** The **Network** settings for a Dedicated Core server are configured.
{% endhint %}

**3. Dedicated Core Server storage settings**

{% hint style="warning" %}
**Warning:** The storage type cannot be changed after provisioning.
{% endhint %}

In the [<mark style="color:blue;">DCD</mark>](https://docs.ionos.com/cloud/set-up-ionos-cloud/data-center-designer) > **Inspector** pane on the right, configure the following storage details in the **Storage** tab.

1\. Click **SSD** and a new pop-up window **Create New Attached Storage** appears.

2\. Configure the following storage details:

* **Name:** Enter a name that is unique within your VDC.
* **Availability Zone:** By default, the value is set to "Auto".
* **Size in GB:** We recommend using **20** for the storage size.
* **Performance:** Select "Standard".

![Dedicated Core Server Storage settings](https://3040852435-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEpuEvuLJIyhyeRGhmrv1%2Fuploads%2Fgit-blob-ca0e45f535c7a123ed2520c2150865b07d4aa49f%2FrDNS-vm-storage-settings.png?alt=media)

* **Image:** You can select one of IONOS Cloud images or snapshots, or use your own. For this tutorial, we will use an Ubuntu server image from IONOS Cloud. To make the same choice, select **ubuntu-22.04-server-cloudimg-amd64** under IONOS Cloud Images.
* **Password:** Create a password for the "root" user of the server. You will need this password to SSH and make changes.
* **SSH Keys:** Select an SSH key stored in the SSH Key Manager.
* **Ad-hoc SSH Key:** If you have not created an SSH key, copy and paste the public part of your SSH key into this field.
* **Cloud-Init user data:** To install the Nginx web-server, Certbot, and Python3-pip tools, use the following Cloud-Init user data.

```bash
#cloud-config

packages:
  - nginx
  - certbot
  - python3-pip
  
runcmd:
  - pip3 install certbot-dns-ionos-cloud
```

* **Boot from Device:** Select this checkbox to make the SSD drive bootable.

![Dedicated Core Server Storage settings](https://3040852435-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEpuEvuLJIyhyeRGhmrv1%2Fuploads%2Fgit-blob-36601e9d2653605167d56c6ae32633acb365c7b9%2FrDNS-vm-storage-settings-continued.png?alt=media)

3\. Click **Create SSD Storage** to create the SSD storage.

{% hint style="success" %}
\*\*Expected result:\*\* The \*\*Storage\*\* settings for a Dedicated Core server are configured.
{% endhint %}

**4. Provision changes and start the Dedicated Core Server**

1\. Select the newly created Dedicated Core server.

2\. From the **Settings** tab in the Inspector pane, select **Power** > **Start**.

3\. Click **Provision Changes** in the lower right corner and click **Provision Now**.

{% hint style="success" %}
**Expected result:** The Dedicated Core server is provisioned and started.
{% endhint %}

**Next steps:** After your changes are provisioned and the server is started, select your Dedicated Core server, click the **Network** tab in the **Inspector** pane, and copy one of the IPv4 addresses.

![Dedicated Core Server Network settings IP](https://3040852435-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEpuEvuLJIyhyeRGhmrv1%2Fuploads%2Fgit-blob-65aab2a606167a52c5ba2a57c7c4c1a742bdcf44%2FrDNS-vm-network-settings-ip.png?alt=media)

{% hint style="success" %}
**Expected result:** A Dedicated Core Server is set up and started along with the configuration of **Settings**, **Network**, and **Storage** setup.
{% endhint %}
{% endstep %}

{% step %}

#### Create an A record for your web server

1\. To create an A record for your email server, follow these steps:

{% hint style="info" %}
**Prerequisite:** Make sure to use your own `<zone_id>` and `<your_server_ip>` along with your `<authorization token>`.
{% endhint %}

**Info:** We already own the primary zone `demo-ionos.cloud` and will use it for this tutorial. Previously, we created a primary zone `demo-ionos.cloud` using the IONOS \`[<mark style="color:blue;">Cloud DNS API</mark>](https://api.ionos.com/docs/dns/v1/). For more information on how to create a primary zone using IONOS [<mark style="color:blue;">Cloud DNS API</mark>](https://api.ionos.com/docs/dns/v1/), see [<mark style="color:blue;">Create a DNS Zone</mark>](https://docs.ionos.com/cloud/network-services/cloud-dns/api-how-tos/create-primary-zone). {% endhint %}

```bash
curl --location 'https://dns.de-fra.ionos.com/zones/<zone_id>/records' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <authorization_token>' \
--data '{
  "properties": {
    "name": "",
    "type": "A",
    "content": "<your_server_ip>",
    "ttl": 60,
    "priority": 0,
    "enabled": true
  }
}'
```

{% hint style="success" %}
**Expected result:** The **A** record for your web server is created.
{% endhint %}

{% hint style="info" %}
**Info:** For more information on how to create a record for a primary zone using IONOS [<mark style="color:blue;">Cloud DNS API</mark>](https://api.ionos.com/docs/dns/v1/), see [<mark style="color:blue;">Create a DNS Zone</mark>](https://docs.ionos.com/cloud/network-services/cloud-dns/api-how-tos/create-dns-record).
{% endhint %}
{% endstep %}

{% step %}

#### Create a TLS certificate for your web server using IONOS Cloud Certbot Plugin

1\. Create a `credentials.ini` file containing the IONOS Cloud API token. This file must contain `ionos_cloud_dns_token` key with the value of the access token:

```bash
vi credentials.ini
```

and add the following content:

```bash
dns_ionos_cloud_token=<your_ionos_cloud_api_token>
```

Save and exit the file.

2\. Restrict access to the `credentials.ini` file:

```bash
chmod 600 credentials.ini
```

3\. Create an TLS certificate for your web server using the IONOS Cloud Certbot Plugin:

```bash
certbot certonly \ 
  --authenticator dns-ionos \ 
  --dns-ionos-credentials /path/to/credentials.ini \ 
  --dns-ionos-propagation-seconds 60 \ 
  --agree-tos \ 
  --rsa-key-size 4096 \ 
  -d '<your-primary-zone-name>' \ 
  -d '*.<your-primary-zone-name>' 
```

| **Flag**                          | **Description**                                                                                          |
| --------------------------------- | -------------------------------------------------------------------------------------------------------- |
| `--authenticator dns-ionos`       | Specifies the authenticator plugin to be used.                                                           |
| `--dns-ionos-credentials`         | Specifies the path to the `credentials.ini` file.                                                        |
| `--dns-ionos-propagation-seconds` | Specifies the time to wait for DNS propagation.                                                          |
| `--agree-tos`                     | Agrees to the terms of service.                                                                          |
| `--rsa-key-size`                  | Specifies the size of the RSA key.                                                                       |
| `-d`                              | Specifies the domain name for which the certificate is issued. Provide the previously created zone name. |

4\. When prompted, enter the email address for urgent renewals and security notices.

5\. The Certbot plugin will automatically create a TXT record in your primary zone to verify the domain ownership.

6\. The Certbot plugin will issue the TLS certificate for your web server. On successful issuance, you will see the following message:

```bash
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/<your-primary-zone>/fullchain.pem
Key is saved at: /etc/letsencrypt/live/<your-primary-zone>/privkey.pem
This certificate expires on <expiration-date>.
These files will be updated when the certificate renews.
```

![Certbot Certificate Issuing](https://3040852435-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEpuEvuLJIyhyeRGhmrv1%2Fuploads%2Fgit-blob-4c83bb44a3f28d22e0e2a9b17211cc2a7df93a09%2Fcertbot-issue-cert.png?alt=media)

{% hint style="info" %}
**Note:** TLS Certificate and Key will be created in `/etc/letsencrypt/live/<your-primary-zone>/` folder. For the purpose of this tutorial we used primary zone `demo-ionos.cloud`, therefore TLS Certificate and Key are created in `/etc/letsencrypt/live/demo-ionos.cloud/` directory.
{% endhint %}

{% hint style="success" %}
**Expected result:** The TLS certificate for your web server is issued using the IONOS Cloud Certbot Plugin.
{% endhint %}
{% endstep %}

{% step %}

#### Add TLS certificate to your web server configuration

1\. Add the TLS certificate to your web server configuration by editing the Nginx configuration file:

```bash
vi /etc/nginx/sites-available/default
```

2\. At the beginning of `/etc/nginx/sites-available/default` file, uncomment the following lines:

```bash
         listen 443 ssl default_server;
         listen [::]:443 ssl default_server;
```

3\. Add the following lines to the bottom of the `server` block:

```bash
        ssl_certificate /etc/letsencrypt/live/<your-primary-zone>/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/<your-primary-zone>/privkey.pem;
```

4\. Your `/etc/nginx/sites-available/default` file should look like this:

```bash
##
# You should look at the following URL's in order to grasp a solid understanding
# of Nginx configuration files in order to fully unleash the power of Nginx.
# https://www.nginx.com/resources/wiki/start/
# https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/
# https://wiki.debian.org/Nginx/DirectoryStructure
#
# In most cases, administrators will remove this file from sites-enabled/ and
# leave it as reference inside of sites-available where it will continue to be
# updated by the nginx packaging team.
#
# This file will automatically load configuration files provided by other
# applications, such as Drupal or Wordpress. These applications will be made
# available underneath a path with that package name, such as /drupal8.
#
# Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples.
##

# Default server configuration
#
server {
	listen 80 default_server;
	listen [::]:80 default_server;

	# SSL configuration
	#
	 listen 443 ssl default_server;
	 listen [::]:443 ssl default_server;
	#
	# Note: You should disable gzip for SSL traffic.
	# See: https://bugs.debian.org/773332
	#
	# Read up on ssl_ciphers to ensure a secure configuration.
	# See: https://bugs.debian.org/765782
	#
	# Self signed certs generated by the ssl-cert package
	# Don't use them in a production server!
	#
	# include snippets/snakeoil.conf;

	root /var/www/html;

	# Add index.php to the list if you are using PHP
	index index.html index.htm index.nginx-debian.html;

	server_name _;

	location / {
		# First attempt to serve request as file, then
		# as directory, then fall back to displaying a 404.
		try_files $uri $uri/ =404;
	}

	# pass PHP scripts to FastCGI server
	#
	#location ~ \.php$ {
	#	include snippets/fastcgi-php.conf;
	#
	#	# With php-fpm (or other unix sockets):
	#	fastcgi_pass unix:/run/php/php7.4-fpm.sock;
	#	# With php-cgi (or other tcp sockets):
	#	fastcgi_pass 127.0.0.1:9000;
	#}

	# deny access to .htaccess files, if Apache's document root
	# concurs with nginx's one
	#
	#location ~ /\.ht {
	#	deny all;
	#}
	ssl_certificate /etc/letsencrypt/live/<your-primary-zone>/fullchain.pem;
	ssl_certificate_key /etc/letsencrypt/live/<your-primary-zone>/privkey.pem;

}


# Virtual Host configuration for example.com
#
# You can move that to a different file under sites-available/ and symlink that
# to sites-enabled/ to enable it.
#
#server {
#	listen 80;
#	listen [::]:80;
#
#	server_name example.com;
#
#	root /var/www/example.com;
#	index index.html;
#
#	location / {
#		try_files $uri $uri/ =404;
#	}
#}
```

5\. Save and exit the file.

6\. Restart the Nginx service:

```bash
systemctl restart nginx.service
```

7\. Verify the Nginx service status:

```bash
systemctl status nginx.service
```

{% hint style="success" %}
**Expected result:** The TLS certificate is added to your web server configuration.
{% endhint %}
{% endstep %}

{% step %}

#### Test your TLS certificate

1\. To test your TLS certificate, open a web browser and enter the URL `https://<your-primary-zone-name>`.

![Certbot Cloud DNS SSL](https://3040852435-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FEpuEvuLJIyhyeRGhmrv1%2Fuploads%2Fgit-blob-add8a88748cb150b43f41e45922a4faa256a7bf7%2Fcertbot-cloud-dns-ssl.png?alt=media)

{% hint style="success" %}
**Expected result:** The TLS certificate is successfully installed, and your web server is secure.
{% endhint %}
{% endstep %}

{% step %}

#### Renew your TLS certificate

Let's Encrypt certificates are valid for 90 days.

1\. To manually renew your TLS certificate using the IONOS Cloud Certbot Plugin, you can do it manually by issuing the following command:

```bash
certbot renew
```

2\. To automate the renewal process, you can set up a cron job to run the renewal command automatically. For more information on how to set up automated renewals, see the [<mark style="color:blue;">Certbot documentation</mark>](https://eff-certbot.readthedocs.io/en/stable/using.html#automated-renewals) page.

{% hint style="success" %}
**Expected result:** Your TLS certificate is renewed successfully.
{% endhint %}
{% endstep %}
{% endstepper %}

### Final result

By following this tutorial, you have successfully set up a secure web server with a TLS certificate issued using the IONOS Cloud Certbot Plugin. Your web server is now protected with HTTPS, ensuring encrypted communication for your users.

## Conclusion

This tutorial demonstrated how to securely configure a web server and issue a TLS certificate using the IONOS Cloud Certbot Plugin. You are now equipped to protect your web applications with automated certificate management and HTTPS encryption.
