This blog post has been written in collaboration with nexiles GmbH, a PTC Software Partner
The Edge Micro Server (EMS) and the LUA Scripting Resource (LSR) allow for an easy connection of sensors and / or data to the ThingWorx Platform.
Connections are usually established through the HTTP protocol and a REST API which sends unencrypted data and user specific credentials or ThingWorx application keys. This could be fine for a non-production environment. However in a more secure environment or in production, encryption and authentication should be used wherever and whenever possible to ensure the safety and integrity of the data.
In this scenario a user, client machine or remote device can utilize the LUA endpoints via the REST APIs endpoints.
For this an authentication mechanism with credentials is required to only allow authenticated sessions. Invokation of services etc. are all protected and encrypted via HTTPS. A default HTTP connection would transfer the credentials as clear text which is most likely not desired.
The LSR then communicates via HTTPS to the EMS.
The EMS communicates to the ThingWorx platform via the AlwaysOn protocol using an encrypted websocket on the platform side.
Prerequisite
ThingWorx is already fully configured for HTTPS.
See Trust & Encryption Theory and Hands On for more information and examples
Securing the EMS
EMS to ThingWorx connection
The config.json holds information on the complete EMS configuration. To add a trusted and secure connection to the ThingWorx platform, the servers, connection type and certificates have to be adjusted.
Check the config.json.complete for more information and individual settings.
As an example the following configuration could be a rough outline.
Switch the websocket server port to 443 in ws_servers
Declare the connection to the websocket as SSL / TLS in wc_connection
Declare the certificate used by the ThingWorx platform in certificates
Validate the certificate
In case you're using a self-signed certificate, allow using it - otherwise just say "false"
If not using a self-signed certificate, but a certificate based on a chain of trust, point to the full chain of trust in the cert_chain parameter
I used the client certifcate in X509 (PEM) formatted .cer file
I used the client certificate's private key as PKCS #8 (PEM) and encrypted it with the super-secure password "changeme" (no really, change it!)
With this the EMS can connect securely to the ThingWorx platform websocket.
EMS as HTTP(S) server
To secure incoming connections to the EMS, it first of all needs to act as a HTTP server which is then configured to use a custom certificate.
In config.json add the http_server section
Define the host and port as well and set SSL to true
The full path of the certificate (.cer file) must be provided
With this the EMS can receive client requests from the LSR through a secure interface, protecting the (meta) data sent from the LSR to the EMS.
For my tests I'm using a self-signed certificate - created in the Keystore Explorer and exported as X509 (PEM) formatted .cer file. The private key is not required for this part.
Authentication
To further secure the connection to the EMS acting as HTTP(S) server, it's recommended to use user and password for authentication.
With this, only connections are accepted, that have the configured credentials in the HTTP header.
config.json
{
"ws_servers": [ { "host": "supersecretems.ptc.com", "port": 443 } ],
"appKey": "<#appKey>",
"http_server": {
"host": "localhost",
"port": 8000,
"ssl": true,
"certificate": "C:\\ThingWorx\\ems.cer",
"authenticate": true,
"user": "EMSAdmin",
"password": "EMSAdmin",
"content_read_timeout": 20000
},
"ws_connection": { "encryption": "ssl" },
"certificates": {
"validate": true,
"allow_self_signed": true,
"client_cert": "C:\\ThingWorx\\twx70.cer",
"key_file": "C:\\ThingWorx\\twx70.pkcs8",
"key_passphrase": "changeme"
}
}
Securing the LSR
LSR to EMS connection
All connections going from the LSR to the EMS are defined in the config.lua with the rap_ parameters.
To setup a secure connection to the EMS, we need to provide the server as defined in the config.json in the http_server section (e.g. the default localhost:8000). Define the usage of SSL / TLS as well as the certificate file.
Client to LSR connection
All connection going to the LSR from any client are defined in the config_lua witht the script_resource_ parameters.
To ensure that all requests are done via authenticated users, setup a userid and password.
Configure the usage of SSL / TLS to encrypt the connection between clients and the LSR.
A custom certificate is not necessarily required - the LSR provideds its own custom certificate by default.
Now opening https://localhost:8001 (default port for the LSR) in a browser will open an encrypted channel forcing authentication via the credentials defined above.
Of course this needs to be considered for other calls implementing e.g. a GET request to the LSR.
This GET request also needs to provide the credentials in its header.
Authentication
It's recommended to also configure the LSR for using a credential based authentication mechanism.
When setting up the LSR to only accept incoming requests with credentials in the header, the script_resource_userid and script_resource_password can be used for authentication.
When connecting to an EMS using authentication, the rap_userid and rap_password can be used to authenticate with the credentials configured in the config.json
config.lua
The following configuration can be posted anywhere in config.lua - best place would be just below the log_level configuration.
scripts.rap_host = "localhost"
scripts.rap_port = 8000
scripts.rap_ssl = true
scripts.rap_deny_selfsigned = false
scripts.rap_cert_file = "C:\ThingWorx\ems.cer"
scripts.rap_server_authenticate = true
scripts.rap_userid = "EMSAdmin"
scripts.rap_password = "EMSAdmin"
scripts.script_resource_userid = "admin"
scripts.script_resource_password = "admin"
scripts.script_resource_ssl = true
EMS specific configuration: rap
LSR specific configuration: script_resource
Other considerations
When configuring the EMS and LSR for authentication and encrypted traffic, the configuration files hold information that not everyone should have access to.
Therefore the config.json and config.lua must be also protected from an Operating System point of view.
Permissions should only be granted to the (process) user that is calling the EMS / LSR. Ensure that no one else can read / access the properties and certificates to avoid password-snooping on an OS level.
It's best to grant restricted access to the whole microserver directory, so that only privileged users can gain access.
You're next...
This blog should have given some insight on what's required and how it's configured to achieve a more secure and safer EMS / LSR integration in a real-life production environment. Of course it always depends on the actual implementation, but use these steps as a guideline to secure and protect your (Internet of) Things!
View full tip