Skip to content

Commit

Permalink
Merge pull request #2585 from didier-wenzek/docs/improve-auth-documen…
Browse files Browse the repository at this point in the history
…tation

Improve certificate related documentation
  • Loading branch information
didier-wenzek authored Jan 17, 2024
2 parents 5eb1219 + f79b243 commit caab654
Show file tree
Hide file tree
Showing 9 changed files with 701 additions and 166 deletions.
22 changes: 11 additions & 11 deletions crates/common/tedge_config/src/tedge_config_cli/tedge_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -351,9 +351,9 @@ define_tedge_config! {
#[tedge_config(reader(private))]
url: ConnectUrl,

/// The path where Cumulocity root certificate(s) are stared
#[tedge_config(note = "The value can be a directory path as well as the path of the direct certificate file.")]
#[tedge_config(example = "/etc/tedge/az-trusted-root-certificates.pem", default(variable = "DEFAULT_ROOT_CERT_PATH"))]
/// The path where Cumulocity root certificate(s) are stored
#[tedge_config(note = "The value can be a directory path as well as the path of the certificate file.")]
#[tedge_config(example = "/etc/tedge/c8y-trusted-root-certificates.pem", default(variable = "DEFAULT_ROOT_CERT_PATH"))]
#[doku(as = "PathBuf")]
root_cert_path: Utf8PathBuf,

Expand Down Expand Up @@ -420,12 +420,12 @@ define_tedge_config! {
port: u16,
},

/// The file that will be used as a the server certificate for the Cumulocity proxy
/// The file that will be used as the server certificate for the Cumulocity proxy
#[tedge_config(example = "/etc/tedge/device-certs/c8y_proxy_certificate.pem")]
#[doku(as = "PathBuf")]
cert_path: Utf8PathBuf,

/// The file that will be used as a the server private key for the Cumulocity proxy
/// The file that will be used as the server private key for the Cumulocity proxy
#[tedge_config(example = "/etc/tedge/device-certs/c8y_proxy_key.pem")]
#[doku(as = "PathBuf")]
key_path: Utf8PathBuf,
Expand Down Expand Up @@ -459,8 +459,8 @@ define_tedge_config! {
#[tedge_config(example = "myazure.azure-devices.net")]
url: ConnectUrl,

/// The path where Azure IoT root certificate(s) are stared
#[tedge_config(note = "The value can be a directory path as well as the path of the direct certificate file.")]
/// The path where Azure IoT root certificate(s) are stored
#[tedge_config(note = "The value can be a directory path as well as the path of the certificate file.")]
#[tedge_config(example = "/etc/tedge/az-trusted-root-certificates.pem", default(variable = "DEFAULT_ROOT_CERT_PATH"))]
#[doku(as = "PathBuf")]
root_cert_path: Utf8PathBuf,
Expand Down Expand Up @@ -489,8 +489,8 @@ define_tedge_config! {
#[tedge_config(example = "your-endpoint.amazonaws.com")]
url: ConnectUrl,

/// The path where AWS IoT root certificate(s) are stared
#[tedge_config(note = "The value can be a directory path as well as the path of the direct certificate file.")]
/// The path where AWS IoT root certificate(s) are stored
#[tedge_config(note = "The value can be a directory path as well as the path of the certificate file.")]
#[tedge_config(example = "/etc/tedge/aws-trusted-root-certificates.pem", default(variable = "DEFAULT_ROOT_CERT_PATH"))]
#[doku(as = "PathBuf")]
root_cert_path: Utf8PathBuf,
Expand Down Expand Up @@ -652,12 +652,12 @@ define_tedge_config! {
},
},

/// The file that will be used as a the server certificate for the File Transfer Service
/// The file that will be used as the server certificate for the File Transfer Service
#[tedge_config(example = "/etc/tedge/device-certs/file_transfer_certificate.pem")]
#[doku(as = "PathBuf")]
cert_path: Utf8PathBuf,

/// The file that will be used as a the server private key for the File Transfer Service
/// The file that will be used as the server private key for the File Transfer Service
#[tedge_config(example = "/etc/tedge/device-certs/file_transfer_key.pem")]
#[doku(as = "PathBuf")]
key_path: Utf8PathBuf,
Expand Down
68 changes: 0 additions & 68 deletions docs/src/operate/security/add_self_signed_trusted.md

This file was deleted.

92 changes: 92 additions & 0 deletions docs/src/operate/security/cloud_authentication.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
---
title: Cloud Authentication
tags: [Operate, Security]
sidebar_position: 3
---

When thin-edge connects a cloud, the cloud endpoint is authenticated using X.509 certificates.
For that to work, the signing certificate of the cloud certificate must be trusted by the device.
Usually, these certificates are stored in `/etc/ssl/certs` and nothing specific has to done on the device.

A specific configuration will be required only for cloud endpoints which CA is not trusted by the device OS default setting.

## Configuration

Several `tedge config` settings are used by thin-edge to locate the signing certificate of the cloud endpoint.

- `c8y.root_cert_path` The path where Cumulocity IoT root certificate(s) are stored (MQTT)
- `c8y.proxy.ca_path` The path where Cumulocity IoT root certificate(s) are stored (HTTP)
- `aws.root_cert_path` The path where AWS IoT root certificate(s) are stored (MQTT).
- `az.root_cert_path` The path where Azure IoT root certificate(s) are stored (MQTT).

All these paths can point to a directory where the trusted certificates are stored
as well as directly to file containing the certificate of the authority signing the cloud endpoint certificate.
Per default, all these paths are set to the system default: `/etc/ssl/certs`.

## Adding a Root Certificate

If the server you are trying to connect `thin-edge.io` to is presenting a certificate with a root that is not currently trusted,
then you can add the server's root certificate to the list of trusted root certificates.
For the most part the store will be filled with certificates from your TLS/SSL provider,
but if this is not the case you may need to update your local certificate store.

:::note
Updating the local certificate store is notably required to connect Cumulocity IoT Edge,
as this distribution of Cumulocity uses self-signed certificates to authenticate itself.
:::

Below are instructions on how to add new CA certificate and update the certificate store.

:::note
Provided instructions are for supported OSes and may not apply to the flavour you are running,
if you need help with other OS please consult appropriate documentation.
:::

### Debian/Ubuntu/RaspberryPi OS

If you do not have the `ca-certificates` package installed on your system, install it with your package manager.

```sh
sudo apt install ca-certificates
```

To add a self-signed certificate to the trusted certificate repository on thin-edge.io system:

Create a `/usr/local/share/ca-certificates/` directory if it does not exist on your computer:

```sh
sudo mkdir /usr/local/share/ca-certificates/
```

The directory should be owned by `root:root` and have `755` permissions set for it. The certificates files should be `644`.

Copy your root certificate (in `PEM` format with `.crt` extension) to the created directory:

```sh
sudo cp <full_path_to_the_certificate> /usr/local/share/ca-certificates/
```

Install the certificates:

```sh
sudo update-ca-certificates
```

```text title="Output"
Updating certificates in /etc/ssl/certs...
1 added, 0 removed; done.
Running hooks in /etc/ca-certificates/update.d...
done.
```

Check the certificate was correctly installed:

```sh
ls /etc/ssl/certs | grep <certificate_name>
```

Additionally, you can check correctness of the installed certificate:

```sh
cat /etc/ssl/certs/ca-certificates.crt | grep -f <full_path_to_the_certificate>
```
78 changes: 0 additions & 78 deletions docs/src/operate/security/connect_external_device.md

This file was deleted.

80 changes: 80 additions & 0 deletions docs/src/operate/security/device-certificate.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
---
title: Device Certificate Setting
tags: [Operate, Security, Cloud]
sidebar_position: 2
---

## Obtaining a Device Certificate

Obtaining a Device Certificate is a quite involved process:
- A private key and a certificate signing request has to be created on the device
- The certificate signing request is sent to the Certificate Authority (CA) chosen by the tenant for its fleet of devices
- The CA checks that the device issuing the signing request is actually allowed to connect the tenant
- The CA signs the signing request sending back the resulting certificate to the device
- The tenant adds the signing certificate of the CA to its trusted list of certificate

There are numerous variations notably on the contract between the tenant and the CA,
the chain of signing certificates and the checks to be performed before approving a signing request.
However, the outcome of the certificate signing process is always the same.
It consists in three files:
- The device private key - generated by the device and which must be kept secret as this the proof of ownership
- The device certificate - signed by the CA and shared by the device on-demand
- The signing certificate - the certificate used by the CA to sign the certificate and by the tenant to check device certificates

## Installing a Device Certificate

The device certificate must be installed on the gateway device,
i.e. on the same box as the MQTT broker establishing the MQTT connection to the cloud over a bridge.

```text title="ls -lh /etc/mosquitto/certs"
-r-------- 1 mosquitto root 1679 oct. 21 2022 demo-device-007.key
-r--r--r-- 1 mosquitto root 2095 oct. 21 2022 demo-device-007.pem
```

Note that *only* the MQTT broker should be able to read or write the private key, while the certificate itself is public.

Then thin-edge must be told where the certificate is stored.
Note that the device certificate file must contain not only the device certificate itself
but also the signing certificate
(so the cloud endpoint can check the chain, starting from a trusted root upto the device certificate).

```sh
# Create a new cert chain, which contains both the signing and device public cert
cat signing-cert.pem > demo-device-007.chain.pem
cat demo-device-007.pem >> demo-device-007.chain.pem

# Configure the cert chain file as the main cert to be used by thin-edge.io
tedge config set device.cert_path /etc/mosquitto/certs/demo-device-007.chain.pem
tedge config set device.key_path /etc/mosquitto/certs/demo-device-007.key
```

The `tedge cert show` command can be used to look at the content of the certificate.

```text title="tedge cert show""
Device certificate: /etc/mosquitto/certs/demo-device-007.chain.pem
Subject: O=Thin-Edge, OU=t398942, CN=demo-device-007
Issuer: C=DE, O=Software AG, CN=QA Thin-Edge CA G1
Valid from: Tue, 09 Nov 2021 14:38:41 +0000
Valid up to: Sat, 09 Nov 2024 14:38:41 +0000
Thumbprint: 1E0F9A074E6FE67A43EE948335E42EB729CB3974
```

## Cloud tenant setting

The last point is to make the cloud tenant trust the device certificate.
For that the certificate of the issuer - .i.e. "QA Thin-Edge CA G1" in the example case,
must be added to the list of trusted signing certificate.

This process is cloud dependent.
See the respective documentation of the cloud you're trying to connect to for details on how to add a new signing certificate:
- [Cumulocity IoT: Managing trusted certificates](https://cumulocity.com/guides/users-guide/device-management/#managing-trusted-certificates)
- [Understand how Azure IoT Edge uses certificates](https://learn.microsoft.com/en-us/azure/iot-edge/iot-edge-certs)
- [AWS IoT: X.509 client certificates](https://docs.aws.amazon.com/iot/latest/developerguide/x509-client-certs.html)

:::note
The command `tedge cert upload` is of no help here.

Indeed, the device does not have a copy of the signing certificate of the CA.
This certificate is given by the CA to the tenant owner or the device operator
in the context of the signing process.
:::
Loading

1 comment on commit caab654

@github-actions
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Robot Results

✅ Passed ❌ Failed ⏭️ Skipped Total Pass % ⏱️ Duration
380 0 3 380 100 52m12.923s

Please sign in to comment.