# Secure connections to targets

> TLS setup for AWS IoT Core, MQTT, Sparkplug B, Kafka, RabbitMQ, Redis, ClickHouse, HTTP and SQL targets, using certificates from the Certificate Store.

Source: https://proxus.io/docs/connect/secure-target-connections

At the end of this guide, an outbound target sends its data over TLS: the target checks the server it connects to,
and, where the server asks for it, proves who it is with a client certificate. You set this up once per target. The
certificates live in the [Certificate Store](https://proxus.io/docs/administer/certificates), so renewing one there needs no change on
the target.

## Before you start

- The target exists. [Outbound targets](https://proxus.io/docs/connect/outbound-targets) shows how to create one.
- You can open **Security > Certificate Store**.
- You have the files your server's administrator or cloud service gave you: usually a CA certificate, and for a
  client certificate the certificate and its private key, in PEM format (`.pem`, `.crt`, `.key`) or as a `.pfx`.

## The two certificates of a target

| Field | What it is | When you need it |
| --- | --- | --- |
| **Trusted Server Certificate** | The CA that signed the server's certificate. The target accepts the server only if its certificate chains to this CA and matches the address you entered. | When the server's certificate comes from your own or a private CA. Leave it empty for a server with a certificate from a public CA: the operating system's trusted roots are used. |
| **Client Certificate** | The certificate and private key the target presents to the server. | When the server requires client certificates (mutual TLS), for example AWS IoT Core. |

There are two ways to put the certificates in place:

1. **On the target page**: select **Certificates** and choose the client certificate, its private key and, if you
   have it, the CA certificate, all at once. Proxus finds out which file is which: the certificate that matches the
   private key becomes the client certificate, and another certificate among the files becomes the trusted server
   certificate. Both go into the Certificate Store and the target refers to them.
2. **In the Certificate Store**: select **Upload** and choose the files. A certificate without a key (a CA) is stored
   as a public certificate. Then pick the certificates on the target:
   - For **MQTT**, **AWS IoT Core** and **SparkplugB**, select **Edit Parameters** and choose them in **Client
     Certificate** and **Trusted Server Certificate**.
   - For the other types, add the parameter `ServerCertificateThumbprint` (and `CertificateThumbprint` for a client
     certificate) to the target. The value is the certificate's **Thumbprint**: open the certificate in the store to
     copy it.

After any change, open the target, select **Check**, choose in **Run Probe On** the gateway that sends the data, and
select **Test Connection**. It uses the same certificates and the same checks as real deliveries.

## AWS IoT Core

AWS IoT Core always uses mutual TLS on port `8883`: the target needs the thing's device certificate and its key.

### In the AWS console

1. Open **AWS IoT Core > Manage > All devices > Things** and select **Create things**. Create a single thing, for
   example `proxus-line-1`.
2. In the certificate step, select **Auto-generate a new certificate**.
3. Attach a policy that lets the thing connect and publish. A minimal policy for a client ID equal to the thing name
   and the topic `proxus_device_data`:

   ```json
   {
     "Version": "2012-10-17",
     "Statement": [
       { "Effect": "Allow", "Action": "iot:Connect",
         "Resource": "arn:aws:iot:<region>:<account>:client/proxus-line-1" },
       { "Effect": "Allow", "Action": "iot:Publish",
         "Resource": "arn:aws:iot:<region>:<account>:topic/proxus_device_data" }
     ]
   }
   ```

4. Download the three files AWS offers: the device certificate (`…-certificate.pem.crt`), the private key
   (`…-private.pem.key`) and **Amazon Root CA 1** (`AmazonRootCA1.pem`). The private key can be downloaded only on
   this page.
5. Open **Settings** and copy the **Device data endpoint**, for example
   `a1b2c3d4e5-ats.iot.eu-central-1.amazonaws.com`.

### In Proxus

1. Open the AWS IoT Core target (clone the **AWS IoT Core** sample if you have none) and save it once.
2. Select **Certificates** and choose the three files together. The device certificate is stored with its key and
   becomes the **Client Certificate**; Amazon Root CA 1 becomes the **Trusted Server Certificate**.
   If you choose only the certificate and the key, Proxus downloads Amazon Root CA 1 itself. Without internet access
   from the hub, the operating system's trusted roots check AWS instead.
3. Select **Edit Parameters** and fill in:
   - **Endpoint**: the device data endpoint from step 5.
   - **Client Id**: the client ID the policy allows, here `proxus-line-1`.
   - **Port** `8883` and **Use TLS** on (both are the defaults).
   - **Topic**: a topic the policy allows.

   **Client Certificate** and **Trusted Server Certificate** are already filled in.
4. Save, select **Check**, choose the sending gateway in **Run Probe On** and select **Test Connection**.

> **Note:**
AWS IoT Core closes a connection without giving a reason when the policy does not allow the client ID or the topic,
or when the certificate is inactive. If **Test Connection** connects and then drops, check the policy and that the
certificate is **Active** in the AWS console.

## MQTT brokers (Mosquitto, EMQX, HiveMQ and others)

1. Find out the broker's TLS port (usually `8883`) and who signed its certificate.
2. If the broker's certificate comes from your own CA, upload the CA certificate to the Certificate Store. If it comes
   from a public CA, skip this step.
3. If the broker requires client certificates (`require_certificate true` in Mosquitto), get a client certificate
   and key from the broker's administrator and upload them with **Certificates** on the target.
4. On the target, select **Edit Parameters**:
   - **Broker Host**: the name in the broker's certificate. An IP address works only if the certificate contains it.
   - **Broker Port** `8883`, **Use TLS** on, **Tls Version** `Tls12` (or `Tls13` if the broker supports it).
   - **Trusted Server Certificate**: the CA from step 2, or empty for a public CA.
   - **Client Certificate**: the certificate from step 3, or empty.
5. Save and run **Test Connection**.

To send to the MQTT broker of another Proxus gateway, choose **Proxus Platform CA** as the trusted server certificate:
every gateway's broker certificate is issued by it.

**SparkplugB** targets have the same fields and work the same way.

## Kafka

Add these parameters to the target:

| Parameter | Value |
| --- | --- |
| `BootstrapServers` | The brokers' TLS listeners, for example `kafka1:9093,kafka2:9093`. |
| `SecurityProtocol` | `Ssl` for TLS, or `SaslSsl` for TLS with a user name and password (`SaslMechanism`, `SaslUsername`, `SaslPassword`). |
| `ServerCertificateThumbprint` | The thumbprint of the cluster's CA in the Certificate Store. Leave it out for a public CA. |
| `CertificateThumbprint` | The client certificate's thumbprint, if the cluster requires client certificates. |

The broker's host name is checked against its certificate.

## RabbitMQ

| Parameter | Value |
| --- | --- |
| `UseTls` | `true` |
| `Port` | `5671` (the default when `UseTls` is `true`). |
| `ServerCertificateThumbprint` | The server's CA, for a private CA. |
| `CertificateThumbprint` | The client certificate, if RabbitMQ requires one (`ssl_options.fail_if_no_peer_cert`). |

## Redis

| Parameter | Value |
| --- | --- |
| `UseTls` | `true` |
| `Host` | The name in the server's certificate. |
| `Port` | The server's TLS port. Many servers use `6380` for TLS; the default is `6379`. |
| `ServerCertificateThumbprint`, `CertificateThumbprint` | As for RabbitMQ. |

## ClickHouse

Set `UseTls` to `true`. The target then uses HTTPS on port `8443` unless you set `Port`. Add
`ServerCertificateThumbprint` for a private CA and `CertificateThumbprint` if the server requires a client
certificate.

## REST API, InfluxDB and Splunk

A URL that starts with `https://` is TLS; the server's certificate is checked against it. Nothing else is needed for
a server with a public CA certificate. For a private CA, add `ServerCertificateThumbprint`; for a client certificate,
add `CertificateThumbprint`.

For Splunk, enter the HTTP Event Collector address with `https://`, for example `https://splunk.example.com:8088`.
The older `UseSSL` parameter has no effect.

## PostgreSQL and MySQL

| Parameter | Value |
| --- | --- |
| `SslMode` | `VerifyFull` (recommended): encrypts and checks the server's certificate and name. `VerifyCA` checks the certificate but not the name. `Prefer` (PostgreSQL) and `Preferred` (MySQL) encrypt without checking the server. |
| `ServerCertificateThumbprint` | The database server's CA, for `VerifyCA` and `VerifyFull`. |

When `SslMode` is not set, the database driver's default applies, which encrypts when the server offers it but does
not check the server. Client certificates are not supported for these two databases.

## Azure IoT Hub

The connection always uses TLS on port `8883`. The hub is checked against the operating system's trusted roots, and
the device signs in with its **SharedAccessKey**. No certificate is needed. X.509 device authentication is not
supported in this version.

## Targets that do not use the Certificate Store

| Type | TLS |
| --- | --- |
| **TDengine** | `UseTls` turns TLS on; the server is checked against the operating system's trusted roots. |
| **SQL Server** | `Encrypt` turns TLS on. `TrustServerCertificate` skips the server check: use it only for tests. |
| **Azure Data Lake Gen2** | Always HTTPS, checked against the operating system's trusted roots. |

## When the connection fails

| What you see | Cause | What to do |
| --- | --- | --- |
| **Test Connection** says the certificate does not match the host. | The address on the target is not a name in the server's certificate. | Enter the name the certificate was issued for, or ask for a certificate that includes your address. |
| **Test Connection** says the certificate is not trusted. | The server's CA is not the trusted server certificate and is not a public CA. | Upload the CA to the Certificate Store and choose it as **Trusted Server Certificate**. |
| **Certificates** says the private key belongs to none of the chosen certificates. | The key and the certificate are from different pairs. | Choose the certificate that was issued with this key. |
| AWS IoT Core connects and drops at once. | The policy does not allow the client ID or topic, or the certificate is inactive. | See the note in [AWS IoT Core](#aws-iot-core). |
| The test works from the hub but not from the gateway. | The gateway's network cannot reach the server, or reaches it under another name. | Run the test from the gateway that sends, and check its firewall and DNS. |

## What's next

- [Outbound targets](https://proxus.io/docs/connect/outbound-targets): transport strategy, checking a target, choosing devices.
- [Certificate Store](https://proxus.io/docs/administer/certificates): renewing, replacing and removing certificates.
- [Outbound targets reference](https://proxus.io/docs/reference/outbound-targets): every parameter of every target type.
