Cloud Edge Provisioning#
Introduction#
What you’ll learn
In this module, you’ll use a Connext Cloud Edge Provisioning Service to secure a Connext system without generating or distributing a single certificate by hand.
You will do the following:
Run an edge Connext system without security enabled and see how a simulated attacker can read its data
Create a Connext Cloud Edge Provisioning Service
Provision each DomainParticipant with its security artifacts and enable the Security Plugins
Revoke one DomainParticipant from the cloud and watch it lose access
By default, a Connext domain is not encrypted. Any application on the same network that speaks DDS can discover your Topics and read your data, without any credentials.
On an unsecured domain, an attacker can eavesdrop on the data.#
The RTI Security Plugins solve this issue, but they require a set of security artifacts. Some artifacts are unique to each secured DomainParticipant: its Identity Certificate, Private Key, and Permissions Document. Others are shared across the system: the Identity CA and Permissions CA certificates, Governance Document, Pre-Shared Key, and Certificate Revocation List. While not every system requires all of these artifacts, you’ll configure each one in this module.
Manually generating, distributing, and renewing these files before they expire is traditionally a challenge. An Edge Provisioning Service does these tasks for you: an agent on each node automatically requests its required artifacts and keeps them up to date.
Each node runs an agent that requests its security artifacts from the Edge Provisioning Service and keeps them up to date.#
The commands in this module use the home automation publisher and subscriber from the Publish-Subscribe module, but the same steps apply to any Connext system.
How to complete this module#
To complete this module, you’ll need the following:
A free Connext Cloud account.
An rticloud CLI installation. Remember to run
rticloud configureand chooseus-east-2.A Connext 7.7.0 or newer installation on the edge machine. If Connext is not installed, the
rticloud gatewaycan help you install it. You can also follow the Installation guide.A clone of the
rticonnextdds-examplesGitHub repository on the edge machine.
Cloning the GitHub repository
Clone the GitHub repository with the following command:
$ git clone --recurse-submodule https://github.com/rticommunity/rticonnextdds-examples.git
The code for this module is located in the tutorials/publish_subscribe
directory. See the README.md files for additional instructions.
This guide is designed for Connext 7.7.0 or newer. For Connext 7.3.1, checkout the branch release/7.3.1.
It’s recommended to have completed the Publish-Subscribe module, but not required.
1. Run the edge applications#
Start a Connext system on the edge machine you want to secure. This edge machine can be your own computer.
You will run two applications, and each one needs its own directory: later in
this module, every application gets its own security artifacts and QoS
profile. Set up one directory named window-01 for the publisher and another
named alert-system for the subscriber. The examples use domain ID 0 by
default.
Install the Connext Python package with pip install rti.connext
if you haven’t already. See Python installation.
Create one directory per application:
$ cd rticonnextdds-examples/tutorials/publish_subscribe
$ cp -r py window-01
$ cp -r py alert-system
In the first terminal, run the subscriber (the alert system):
$ cd alert-system
$ python home_automation_subscriber.py
In the second terminal, run the publisher (the window sensor):
$ cd window-01
$ python home_automation_publisher.py Window-01 LivingRoom
Build the applications, then create one directory per application:
$ cd rticonnextdds-examples/tutorials/publish_subscribe/c++11
$ mkdir -p build
$ cd build
$ cmake -DBUILD_SHARED_LIBS=ON ..
$ cmake --build .
$ cd ..
$ cp -r build window-01
$ cp -r build alert-system
In the first terminal, run the subscriber (the alert system):
$ cd alert-system
$ ./home_automation_subscriber
In the second terminal, run the publisher (the window sensor):
$ cd window-01
$ ./home_automation_publisher Window-01 LivingRoom
The full instructions, including other programming languages, are in the Publish-Subscribe module.
The subscriber should print warnings like this:
WARNING: Window-01 in LivingRoom is open!
Keep both applications running for the rest of this module.
Now play the attacker. In a third terminal, run RTI DDS Spy, a tool included with your Connext installation that subscribes to everything it finds on the domain:
$ rtiddsspy -mode USER
DDS Spy prints the “WindowStatus” data as it is published:
RTI DDS Spy built with RTI Connext version: 7.7.0
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
rtiddsspy is listening for data, press CTRL+C to stop it.
16:54:41 New data from 172.22.81.6 : topic="WindowStatus" type="DeviceStatus"
sensor_name: "Window-01"
room_name: "LivingRoom"
is_open: false
16:54:43 Modified instance from 172.22.81.6 : topic="WindowStatus" type="DeviceStatus"
sensor_name: "Window-01"
room_name: "LivingRoom"
is_open: true
Nothing stopped the attack; a process that you never authorized is reading your data.
Stop DDS Spy with CTRL+C and let’s fix that.
2. Create an Edge Provisioning Service#
Create the Edge Provisioning Service in the Connext Cloud dashboard:
Open the Connext Cloud dashboard.
Go to Edge Provisioning.
Select Create Edge Provisioning.
Name the service
home-automation-eps.Keep the default settings.
Review the settings and create the service.
Wait until the service shows the Active status before continuing.
3. Secure the domain#
The Edge Provisioning Service issues a set of security artifacts for each DomainParticipant. Once you configure the participants to use them, the domain is authenticated and encrypted, and the attacker is locked out.
Each DomainParticipant gets its security artifacts from the Edge Provisioning Service and communicates securely within the domain.#
Start the edge-sync agent#
The rticloud edge-sync agent command enrolls a DomainParticipant with the
service, downloads its security artifacts, and renews them before they expire.
Open a new terminal in the window-01 directory and another one in the
alert-system directory, then start one agent in each terminal:
# In the window-01 directory
$ rticloud edge-sync agent --deployment-name window-01 --connext-dir connext-artifacts
# In the alert-system directory
$ rticloud edge-sync agent --deployment-name alert-system --connext-dir connext-artifacts
Follow the interactive prompts:
Select My Connext Cloud account (operator login).
Select
home-automation-epsif you are asked for a service.
The agent enrolls with the identity you passed in --deployment-name and picks the
default domain ID 0 and the default participant template. It then
downloads the artifacts into the connext-artifacts directory and shows them
in a terminal UI, where you can also renew any of them manually.
Note
Keep both agents running while you continue the tutorial. If you stop an
agent, run rticloud edge-sync agent again from the same directory to
restart it. Use rticloud edge-sync agent reset to reset the
configuration if you want to start over.
Enable the Security Plugins in the QoS profile#
Now we have the security artifacts, but they aren’t being used yet. Point
each DomainParticipant at its own artifacts by editing its
USER_QOS_PROFILES.xml. In window-01/USER_QOS_PROFILES.xml and
alert-system/USER_QOS_PROFILES.xml, replace this block:
<base_name>
<element>BuiltinQosLib::Generic.StrictReliable</element>
</base_name>
with the following configuration. The only difference between the two files is the deployment name in the last three paths, so use the tab that matches the directory you are editing:
<base_name>
<element>BuiltinQosSnippetLib::Feature.Security.Enable</element>
</base_name>
<participant_factory_qos>
<monitoring>
<enable>false</enable>
</monitoring>
</participant_factory_qos>
<domain_participant_qos>
<property>
<value>
<element>
<name>dds.sec.auth.identity_ca</name>
<value>file:connext-artifacts/0/identity_ca.crt</value>
</element>
<element>
<name>dds.sec.access.permissions_ca</name>
<value>file:connext-artifacts/0/permissions_ca.crt</value>
</element>
<element>
<name>dds.sec.crypto.rtps_psk_secret_passphrase</name>
<value>file:connext-artifacts/0/psk_secret.key</value>
</element>
<element>
<name>dds.sec.crypto.rtps_psk_secret_passphrase_extra</name>
<value>file:connext-artifacts/0/psk_secret_extra.key</value>
</element>
<element>
<name>dds.sec.auth.crl</name>
<value>file:connext-artifacts/0/crl.pem</value>
</element>
<element>
<name>dds.sec.access.governance</name>
<value>file:connext-artifacts/0/governance.p7s</value>
</element>
<element>
<name>dds.sec.auth.identity_certificate</name>
<value>file:connext-artifacts/0/window-01/default-participant-template/identity.crt</value>
</element>
<element>
<name>dds.sec.auth.private_key</name>
<value>file:connext-artifacts/0/window-01/default-participant-template/identity.key</value>
</element>
<element>
<name>dds.sec.access.permissions</name>
<value>file:connext-artifacts/0/window-01/default-participant-template/permissions.p7s</value>
</element>
</value>
</property>
</domain_participant_qos>
<base_name>
<element>BuiltinQosSnippetLib::Feature.Security.Enable</element>
</base_name>
<participant_factory_qos>
<monitoring>
<enable>false</enable>
</monitoring>
</participant_factory_qos>
<domain_participant_qos>
<property>
<value>
<element>
<name>dds.sec.auth.identity_ca</name>
<value>file:connext-artifacts/0/identity_ca.crt</value>
</element>
<element>
<name>dds.sec.access.permissions_ca</name>
<value>file:connext-artifacts/0/permissions_ca.crt</value>
</element>
<element>
<name>dds.sec.crypto.rtps_psk_secret_passphrase</name>
<value>file:connext-artifacts/0/psk_secret.key</value>
</element>
<element>
<name>dds.sec.crypto.rtps_psk_secret_passphrase_extra</name>
<value>file:connext-artifacts/0/psk_secret_extra.key</value>
</element>
<element>
<name>dds.sec.auth.crl</name>
<value>file:connext-artifacts/0/crl.pem</value>
</element>
<element>
<name>dds.sec.access.governance</name>
<value>file:connext-artifacts/0/governance.p7s</value>
</element>
<element>
<name>dds.sec.auth.identity_certificate</name>
<value>file:connext-artifacts/0/alert-system/default-participant-template/identity.crt</value>
</element>
<element>
<name>dds.sec.auth.private_key</name>
<value>file:connext-artifacts/0/alert-system/default-participant-template/identity.key</value>
</element>
<element>
<name>dds.sec.access.permissions</name>
<value>file:connext-artifacts/0/alert-system/default-participant-template/permissions.p7s</value>
</element>
</value>
</property>
</domain_participant_qos>
Here is what you just configured:
BuiltinQosSnippetLib::Feature.Security.Enableloads the Security Plugins into the DomainParticipant.The
identity_ca(Identity CA) andpermissions_ca(Permissions CA) certificates are the trust anchors: a DomainParticipant only talks to peers whose credentials were issued by these authorities.The
identity_certificateandprivate_keyare this DomainParticipant’s own Identity Certificate and Private Key. These artifacts enablewindow-01to verify its identity.The Permissions Document (
permissions) states which Topics this DomainParticipant is allowed to publish and subscribe to, and the Governance Document (governance) defines the protection rules for the Domain and its Topics (what gets signed and encrypted).The
crlis the Certificate Revocation List (CRL), the list of credentials that are no longer trusted. You’ll use it in the next section.The two
rtps_psk_secret_passphraseproperties enable RTPS Pre-Shared Key (PSK) protection, which encrypts RTPS traffic, including discovery, so an outsider can’t even see which Topics exist. The_extraproperty holds a second passphrase, which lets you rotate keys without interrupting communication.
For the full reference on these properties, see the Security Plugins User’s Manual .
Run the applications on a secured domain#
Stop the publisher and subscriber with CTRL+C. Then restart
them from their respective directories, following the same procedure as in
step 1.
In the alert system terminal:
$ python home_automation_subscriber.py
In the window sensor terminal:
$ python home_automation_publisher.py Window-01 LivingRoom
In the alert system terminal:
$ ./home_automation_subscriber
In the window sensor terminal:
$ ./home_automation_publisher Window-01 LivingRoom
The applications continue communicating as before, and the alert system still prints its warnings.
Now run the simulated attacker again:
$ rtiddsspy -mode USER
This time it prints nothing. DDS Spy has no Identity Certificate and no PSK passphrase, so it can’t even discover the applications, let alone read their data.
4. Revoke an application#
Suppose you discover that one of your nodes has been compromised and you want to cut it off. You don’t need to touch the edge machine: revoke it from the cloud.
Revoking window-01 adds its certificate to the revocation list, which the
alert-system agent downloads and applies.#
Open the Connext Cloud dashboard and go to Edge Provisioning.
Open
home-automation-eps.Go to the Fleet tab and the Participants sub-tab.
Find the
window-01row and select at the end of the row to open its actions menu.Select Revoke Participant.
Look at the alert system: it may still be receiving data from window-01.
This is expected. Revocation takes effect once the other applications
download the updated CRL, which the agent does automatically on its own
schedule.
To see it right away, switch to the terminal UI of the alert-system agent,
select the crl row, and press ENTER to renew it.
The alert system stops printing warnings and logs a security error instead:
ERROR [...|VALIDATE REMOTE PARTICIPANT IDENTITY|CHECK STATUS|LC:Security]
RTI_Security_CertHelper_verifyCertificate: ...
"m":"X509_verify_cert returned 0 with error 23: certificate revoked
subject name: /O=ces-home-automation-eps-.../DC=0/OU=default-participant-template/CN=window-01
ERROR [...|VALIDATE REMOTE PARTICIPANT IDENTITY|CHECK STATUS|LC:Security]
RTI_Security_Authentication_validateCertificateChain: ...
"m":"Identity verification failed. Make sure it was signed by the right authority."
This error is the expected result, not a problem with your setup. Reading it from the inside out:
CN=window-01in the subject name identifies the DomainParticipant being rejected.error 23: certificate revokedis the reason the check failed.VALIDATE REMOTE PARTICIPANT IDENTITYmeans the alert system is rejecting a remote DomainParticipant, not complaining about its own credentials.
window-01 is still running and still writing samples, but nothing on the
domain authenticates it anymore, so its data goes nowhere. The alert system
logs this error each time window-01 retries authentication.
Switch to the terminal UI of the window-01 agent and try to renew any
artifact. The renewal fails: the agent shows a message indicating that this
DomainParticipant has been revoked and its credentials are rejected by the
server.
Congratulations! You secured a Connext domain with artifacts provisioned from the cloud, and you revoked a compromised application without touching the edge machine.
Learn more#
This module used the default domain and participant templates and enrolled each DomainParticipant with your operator login. For a real fleet, you would define your own governance and permissions templates and enroll DomainParticipants with enrollment tokens instead of operator credentials, so no human has to log in on each node.
Next Steps
To learn what the Security Plugins do under the hood, and to configure authentication, access control, and cryptography yourself, see the Securing your applications module.
More information about Security Plugins: