.. include:: /../getting_started/vars.rst .. _section-security: Security ******** *Observability Framework* can secure the telemetry data generated by |Connext| applications and stored in the telemetry backends. Data in transit is secured using the |RTI_SP| and BASIC-Auth over HTTPS. Data at rest is secured by the third-party telemetry backends. :numref:`FigureSecurityPromLoki` shows the *Observability Framework* security architecture when |COLLECTORSERVICE| is configured to store the telemetry data in Prometheus and Grafana Loki. .. figure:: static/rti_security_prom_loki.png :alt: Security Architecture of RTI Observability Framework when using Prometheus and Grafana Loki :name: FigureSecurityPromLoki :align: center :figwidth: 100% Security Architecture of RTI Observability Framework when using Prometheus and Grafana Loki To facilitate testing and evaluation, you can install *Observability Framework* using :ref:`section-docker-compose-prepackaged` to automatically run and deploy all the components shown in :numref:`FigureSecurityPromLoki` within a single host. :numref:`FigureSecurityOTel` shows the *Observability Framework* security architecture when |COLLECTORSERVICE| is configured to forward the telemetry data to an OpenTelemetry Collector. This diagram does not show the Grafana server because *Observability Dashboards* are only provided for the Prometheus and Grafana Loki telemetry backends. .. figure:: static/rti_security_otlp.png :alt: Security Architecture of the RTI Observability Framework when using OpenTelemetry Collector :name: FigureSecurityOTel :align: center :figwidth: 100% Security Architecture of RTI Observability Framework when using OpenTelemetry Collector To facilitate testing and evaluation, you can install *Observability Framework* using :ref:`section-docker-compose-prepackaged` to automatically run and deploy an OpenTelemetry Collector instance that stores the telemetry data in a local Prometheus and Grafana Loki as shown in :numref:`FigureSecurityOTelPromLoki`. .. figure:: static/rti_security_otlp_prom_loki.png :alt: Security Architecture of the RTI Observability Framework when using OpenTelemetry Collector, Prometheus and Grafana Loki :name: FigureSecurityOTelPromLoki :align: center :figwidth: 100% Security Architecture of the RTI Observability Framework when using OpenTelemetry Collector, Prometheus and Grafana Loki Secure Communication between Connext Applications and Collector Service ======================================================================= The exchange of telemetry data between a |Connext| application and |COLLECTORSERVICE| is secured by using the |RTI_SP|. For additional information on how to configure the *Security Plugins*, see the :link_connext_dds_secure_um:`Support for RTI Observability Framework ` section in the :link_connext_dds_secure_um:`RTI Security Plugins User's Manual `. If you install *Observability Framework* using the :ref:`section-docker-compose-prepackaged` option, the security artifacts required to configure the *Security Plugins* in |COLLECTORSERVICE| can be provided during the installation process. Use the highlighted parameters in your JSON configuration file: .. code-block:: JSON :emphasize-lines: 10-17 { "securityConfig": { "basicAuthUsername": "yourusername", "basicAuthPassword": "yourpassword", "httpsSecurity": { "caCertificate": "path/to/ca_cert.pem", "serverCertificate": "path/to/server_cert.pem", "serverKey": "path/to/server_key.pem" }, "ddsSecurity": { "identityCaCertificate": "path/to/identityCaCert.pem", "permissionsCaCertificate": "path/to/permissionsCaCert.pem", "identityCertificate": "path/to/identityCert.pem", "identityKey": "path/to/identityKey.pem", "signedPermissionsFile": "path/to/signedPermissions.p7s", "signedGovernanceFile": "path/to/signedGovernance.p7s" } } } If you run |COLLECTORSERVICE| using the :ref:`section-docker-compose-separate-deployment` option, the security artifacts required to configure the |RTI_SP| in |COLLECTORSERVICE| can be bind-mounted by providing the following options to the ``docker run`` command: .. code-block:: console -v path/to/identityCaCert.pem:/rti/security/dds/identity_ca.pem -v path/to/permissionsCaCert.pem:/rti/security/dds/permissions_ca.pem -v path/to/identityCert.pem:/rti/security/dds/identity_certificate.pem -v path/to/identityKey.pem:/rti/security/dds/private_key.pem -v path/to/signedPermissions.p7s:/rti/security/dds/permissions.p7s -v path/to/signedGovernance.p7s:/rti/security/dds/governance.p7s In addition, you need to set the ``CFG_NAME`` environment variable to one of the provided Docker image's built-in configurations that enable the |SP| in |COLLECTORSERVICE| (see :ref:`section-docker-compose-separate-deployment`). For additional details, see the |COLLECTORSERVICE| docker image `documentation `__. For details on how to generate the security artifacts see :ref:`section-generating-security-artifacts`. Secure Communication with Collector Service's HTTP Servers ========================================================== |COLLECTORSERVICE| can start two HTTP servers: one to receive remote commands and another one to expose the Prometheus metrics. The communication with these HTTP servers is secured using BASIC-Auth over HTTPS. |COLLECTORSERVICE| provides a REST API for receiving remote commands to control the collection and distribution of telemetry data from |Connext| Applications. In this release, the REST API can only be used from *Observability Dashboards*. |COLLECTORSERVICE| can be configured to store the telemetry data in a Prometheus backend. Prometheus collects metrics from targets by scraping metrics HTTP endpoints on these targets. To configure the security of the HTTP servers started by |COLLECTORSERVICE|, you can follow these steps. If you install *Observability Framework* using :ref:`section-docker-compose-prepackaged`, use the highlighted parameters in the installation JSON configuration file: .. code-block:: JSON :emphasize-lines: 3-5,7-9 { "securityConfig": { "basicAuthUsername": "yourusername", "basicAuthPassword": "yourpassword", "httpsSecurity": { "caCertificate": "path/to/ca_cert.pem", "serverCertificate": "path/to/server_cert.pem", "serverKey": "path/to/server_key.pem" }, "ddsSecurity": { "identityCaCertificate": "path/to/identityCaCert.pem", "permissionsCaCertificate": "path/to/permissionsCaCert.pem", "identityCertificate": "path/to/identityCert.pem", "identityKey": "path/to/identityKey.pem", "signedPermissionsFile": "path/to/signedPermissions.p7s", "signedGovernanceFile": "path/to/signedGovernance.p7s" } } } If you run |COLLECTORSERVICE| using :ref:`section-docker-compose-separate-deployment`, the security artifacts to configure the HTTP servers running in |COLLECTORSERVICE| can be bind-mounted by providing the following options to the ``docker run`` command: .. code-block:: console -v path/to/server.pem:/rti/security/https/server.pem -v path/to/htdigest:/rti/security/https/htdigest In addition, you need to set the ``CFG_NAME`` environment variable to one of the provided Docker image's built-in secure configurations (see :ref:`section-docker-compose-separate-deployment`). The *server.pem* file must contain both a valid server certificate (*server_cert.pem*) and the corresponding private key (*server_key.pem*). The *htdigest* is a password file that contains the username and password for BASIC-Auth. The *htdigest* file is a password file that contains the Apache ``htdigest``. For details on how to generate the *server.pem* file and the *htdigest* file, see :ref:`section-generating-security-artifacts`. .. important:: The configuration of the HTTP clients initiated by third-party components is out of the scope of this documentation. Please refer to the documentation of the third-party components for additional details. However, if you install *Observability Framework* using :ref:`section-docker-compose-prepackaged`, the third-party components will be configured to use the security artifacts provided in the installation JSON configuration file. You can take a look into the configuration files of the third-party components located in the directory ``/user_config/observability`` to see how the security artifacts are used. Secure Communication with Third-party Components' HTTP Servers ============================================================== *Observability Framework* can start three HTTP clients: one to send logs to *Grafana Loki*, one to send logs to *OpenTelemetry Collector*, and one to send metrics to *OpenTelemetry Collector*. The communication with these HTTP clients is secured using BASIC-Auth over HTTPS. To configure the security of the HTTP clients started by |COLLECTORSERVICE|: If you install *Observability Framework* using :ref:`section-docker-compose-prepackaged`, use the highlighted parameters in the installation JSON configuration file: .. code-block:: JSON :emphasize-lines: 3-4,5-6,9 { "securityConfig": { "basicAuthUsername": "yourusername", "basicAuthPassword": "yourpassword", "httpsSecurity": { "caCertificate": "path/to/ca_cert.pem", "serverCertificate": "path/to/server_cert.pem", "serverKey": "path/to/server_key.pem" }, "ddsSecurity": { "identityCaCertificate": "path/to/identityCaCert.pem", "permissionsCaCertificate": "path/to/permissionsCaCert.pem", "identityCertificate": "path/to/identityCert.pem", "identityKey": "path/to/identityKey.pem", "signedPermissionsFile": "path/to/signedPermissions.p7s", "signedGovernanceFile": "path/to/signedGovernance.p7s" } } } If you run |COLLECTORSERVICE| using :ref:`section-docker-compose-separate-deployment`, the security artifacts to configure the HTTP clients running in |COLLECTORSERVICE| can be provided by using the following options to the ``docker run`` command: .. code-block:: console -e OBSERVABILITY_BASIC_AUTH_USERNAME=yourusername -e OBSERVABILITY_BASIC_AUTH_PASSWORD=yourpassword -v path/to/ca_cert.pem:/rti/security/https/rootCA.crt In addition, you need to set the ``CFG_NAME`` environment variable to one of the provided Docker image's built-in secure configurations (see :ref:`section-docker-compose-separate-deployment`). .. important:: The configuration of the third-party components' HTTP servers is out of the scope of this documentation. Please refer to the documentation of the third-party components for additional details. However, if you install *Observability Framework* using :ref:`section-docker-compose-prepackaged`, the third-party components will be configured to use the security artifacts provided in the installation JSON configuration file. You can take a look into the configuration files of the third-party components located in the directory ``/user_config/observability`` to see how the security artifacts are used. .. _section-generating-security-artifacts: Generating the Observability Framework Security Artifacts =========================================================== This section describes how to generate the security artifacts required to secure *Observability Framework*. For an overview of the security architecture of the Observability Framework, see :ref:`section-security`. There are two sets of security artifacts: - DDS security artifacts secure the exchange of telemetry data with an application using |MONITORINGLIBRARY2|. - HTTPS security artifacts secure the exchange of telemetry data between |COLLECTORSERVICE| and the third-party observability backends as well as to send remote commands to |COLLECTORSERVICE|. Generating DDS Security Artifacts --------------------------------- The DDS security artifacts are used to secure the exchange of telemetry data between a |Connext| application and |COLLECTORSERVICE|. See :link_connext_dds_secure_um:`Support for RTI Observability Framework ` section in the :link_connext_dds_secure_um:`RTI Security Plugins User's Manual ` for details about how to secure the communication between a |Connext| application and |COLLECTORSERVICE|. For details on how to create/update DDS security artifacts, see :link_connext_dds_secure_gsg:`Generating and Revoking Your Own Certificates Using OpenSSL in Security Plugins Getting Started `. Generating HTTPS Security Artifacts ----------------------------------- The security artifacts needed to secure the communication between |COLLECTORSERVICE| and the third-party observability backends are: - A root CA certificate file - A server certificate file - A server key We will start by generating a self-signed Root CA, which will issue the *Server Certificate* used to secure the various HTTP servers in *Observability Framework*. This will require us to set up a minimal security infrastructure first. We will show an example for ECDSA as the public-key algorithm to generate the certificates. Note that you can use any public-key algorithm listed in :link_connext_dds_secure_um:`Supported Cryptographic Algorithms in the Security Plugins User's Manual `. .. note:: We will use the **OpenSSL CLI** to perform the security operations in the generation of the security artifacts. Make sure to include in the path your |OpenSSL| binary directory [#openssl_lm_path]_. The installation process is described in the :link_connext_dds_secure_ig:`RTI Security Plugins Installation Guide <>`. .. [#] Read the official `documentation `_ for more information on the OpenSSL configuration files. .. _section-sec-preliminary-steps: Preliminary Steps ^^^^^^^^^^^^^^^^^ Setting up a security infrastructure requires some preliminary configuration. We will cover a minimal setup here. #. The ``rti_workspace`` directory containing examples and user configuration files is automatically copied into the users' home or My Documents folder when the first RTI application is launched (e.g., RTI Launcher, rtiddsgen, rtipkginstall, or rtiobservability). In your ``rti_workspace`` directory you should have OpenSSL configuration files named :file:`/examples/dds_security/cert/ecdsa01/ca/ecdsa01RootCa.cnf` and :file:`/examples/dds_security/cert/ecdsa01/https/ecdsa01Https01.cnf`. Make copies of these files and call them :file:`observabilityRootCa.cnf` and :file:`observabilityServer.cnf` respectively. To better organize your project, save these copies in a new directory called :file:`cert/observability`: .. tabs:: .. group-tab:: Linux .. code-block:: console $ cd /examples/dds_security $ cp cert/ecdsa01/ca/ecdsa01RootCa.cnf cert/observability/ca/observabilityRootCa.cnf $ cp cert/ecdsa01/https/ecdsa01Https01.cnf cert/observability/https/observabilityServer.cnf #. Modify :file:`observabiltyRootCa.cnf` to redefine the ``name`` variable. Note that this configuration file uses this variable to derive some filenames, such as those used in the next section: .. code-block:: openssl ... # Variables defining this CA name = observabilityRootCa # Name desc = # Description ... .. _section-sec-initialize-openssl-ca-database: Initialize the OpenSSL CA Database """""""""""""""""""""""""""""""""" When using a CA to perform an operation, OpenSSL relies on special database files to keep track of the issued certificates, serial numbers, revoked certificates, etc. We need to create these database files to be able to use the :command:`openssl x509 -req` command: .. tabs:: .. group-tab:: Linux .. code-block:: console $ mkdir cert/observability/ca/database $ touch cert/observability/ca/database/observabilityRootCaIndex $ echo 01 > cert/observability/ca/database/observabilityRootCaSerial Limit the Access of the CA's Private Key """""""""""""""""""""""""""""""""""""""" It is also a good practice to store the CA's private key in a separate directory with more restrictive access rights, so only you can sign certificates. .. tabs:: .. group-tab:: Linux .. code-block:: console $ mkdir cert/observability/ca/private $ chmod 700 cert/observability/ca/private .. _section-sec-generating-new-root-ca: Generating a New Root CA ^^^^^^^^^^^^^^^^^^^^^^^^ #. Modify :file:`cert/observability/ca/observabilityRootCa.cnf` and specify the fields in the ``req_distinguished_name`` section. This information will be incorporated into your certificate: .. code-block:: openssl ... [ req_distinguished_name ] countryName = US stateOrProvinceName = CA localityName = Santa Clara 0.organizationName = Observing Organization commonName = Observability Root CA emailAddress = rootCa@observability.com ... #. Use the OpenSSL CLI to generate a self-signed certificate using the |RootCA|'s configuration. Run the following command from the :file:`cert/observability` directory: .. tabs:: .. group-tab:: ECDSA secp256r1 .. code-block:: console $ openssl req -nodes -x509 -days 1825 -text -sha256 -newkey ec -pkeyopt ec_paramgen_curve:prime256v1 -keyout ca/private/observabilityRootCaKey.pem -out ca/observabilityRootCaCert.pem -config ca/observabilityRootCa.cnf This will produce a new private key, ``observabilityRootCaKey.pem`` in the ``cert/observability/ca/private`` directory, and a new certificate, ``observabilityRootCaCert.pem``, in the ``cert/observability/ca`` directory. This certificate will be valid for 1825 days (5 years) starting today. .. _section-sec-generating-server-certificates: Generating Server Certificates ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |ServerCerts| are verified against the |RootCA| when authenticating servers over HTTPS. Therefore, in the simplest scenario, it is the |RootCA| that is responsible for issuing |ServerCerts|. We will create a certificate signing request (CSR) for the server localhost. Then we will use the new |RootCA| to issue the certificate requested by the CSR. #. Add the information you want to include in localhost's certificate in the file :file:`cert/observability/https/observabilityServer.cnf` that was previously created. You may want to use the following contents as a reference: .. code-block:: openssl :caption: Sample contents of observabilityServer.cnf prompt=no distinguished_name = req_distinguished_name [ req_distinguished_name ] countryName=US stateOrProvinceName=CA organizationName=Observing Organization emailAddress=server@observability.com commonName=localhost [ https_cert ] subjectAltName = @alt_names [ alt_names ] DNS.1 = localhost IP.1 = 127.0.0.1 You are free to modify any field except ``countryName``, ``stateOrProvinceName``, and ``organizationName``. These fields must match the ones of the |RootCA|; otherwise it will refuse to issue the requested certificate (note that a ``commonName`` is also required). These requirements are specified in :file:`observabilityRootCa.cnf`, in the ``policy_match`` section. |br| |br| #. Generate the new server's key and CSR. Run the following command from the :file:`cert/observability` directory: .. tabs:: .. group-tab:: ECDSA secp256r1 .. code-block:: console $ openssl req -nodes -new -newkey ec -pkeyopt ec_paramgen_curve:prime256v1 -config https/observabilityServer.cnf -keyout https/observabilityServerKey.pem -out https/observabilityServer.csr This will produce an RSA private key, :file:`observabilityServerKey.pem`, and a CSR based on that key, :file:`observabilityServer.csr`. Since CSRs have all the information and cryptographic material that a CA needs to issue a certificate, the server's private key must never be known to anyone but the creator. |br| |br| #. Use the new |RootCA|'s certificate and private key to issue a new |ServerCert|. Run the following command from the :file:`cert/observability` directory: .. tabs:: .. group-tab:: ECDSA secp256r1 .. code-block:: console $ openssl x509 -req -days 730 -text -CAserial ca/database/observabilityRootCaSerial -extfile https/observabilityServer.cnf -extensions https_cert -CA ca/observabilityRootCaCert.pem -CAkey ca/private/observabilityRootCaKey.pem -in https/observabilityServer.csr -out https/observabilityServerCert.pem The |RootCA| will issue the server's public certificate, :file:`observabilityServerCert.pem`, which will be valid for 730 days (2 years) starting today. #. |COLLECTORSERVICE| requires a server certificate file for HTTPS operation that contains both the server certificate and key. The following is an example of how to create this file using the server certificate and key generated in the previous step. Run the following command from the :file:`/examples/dds_security/cert/observability` directory: .. tabs:: .. group-tab:: Linux .. code-block:: console $ cp https/observabilityServerCert.pem observabilityServer.pem $ cat https/observabilityServerKey.pem >> observabilityServer.pem BASIC-Auth Password File ^^^^^^^^^^^^^^^^^^^^^^^^ The communication between |COLLECTORSERVICE| and the third-party observability backends is secured using BASIC-Auth over HTTPS. The HTTP servers started by |COLLECTORSERVICE| require a password file that contains the username and password for BASIC-Auth. This section describes how to create this file. .. note:: The creation of the equivalent password file for the third-party observability backends is out of the scope of this documentation. Please refer to the documentation of the third-party observability backends for additional details on how to create this file. |COLLECTORSERVICE| requires an htdigest formatted password file for basic authentication. The following example uses the Apache ``htdigest`` command to create this file. For more information on this command see `Apache - htdigest - manage user files for digest authentication `_ Here is an example of how to use the ``htdigest`` command: .. tabs:: .. group-tab:: Linux .. code-block:: console $ htdigest -c htdigest localhost user Adding password for user in realm localhost. New password: Re-type new password: The example uses the following arguments for the ``htdigest`` command. .. list-table:: htdigest Arguments :name: TableHtdigestArgumenets :widths: 10 80 10 :header-rows: 1 * - Parameter - Description - Value * - -c - Create the passwdfile. If passwdfile already exists, it is deleted first. - -c * - passwordfile - Name of the file to contain the username, realm, and password. If -c is given, this file is created if it does not already exist, or deleted and recreated if it does exist. - htdigest * - realm - The realm name to which the user name belongs. See http://tools.ietf.org/html/rfc2617#section-3.2.1 for more details. - hostname ("localhost") * - username - The user name to create or update in passwdfile. If username does not exist is this file, an entry is added. If it does exist, the password is changed. - user * - password - The password to create or update in passwdfile. If username does not exist is this file, an entry is added. If it does exist, the password is changed. - userpassword This will create an htdigest file with the following content: .. code-block:: text user:localhost:bbbb113a9f365f1b3787b6a944ccbc59