Community Tip - Want the oppurtunity to discuss enhancements to PTC products? Join a working group! X
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.
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.
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.
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.
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
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
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.
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!
Thanks for following up and summariziung this issue!
Hi,
Great article!
Got question - have you ever used/ tried to use keystores instead of certification files in configuration file ( config.json )?
I mean, does the platform even support this kind of configuration?
I'm aware that keystore is just wrapper for certification files, and there is no difference in use, but that kind of question I got from customer that consider certificates not enough safe for him.
Thanks.
Lukasz
Hi Lukaz,
I've only configured it with certificates, not keystores.
The Help Center entry on EMS High Security indicates that only .pem files are configurable at the moment no jks keystores. The .pem file itself is some kind of keystore itself, as it can hold either a certificate or a whole chain of trust.
Why is the certificate not considered secure enough? With a password secured private key in the .pem file and a tight OS permission system, the private key and its password are stored in a safe way.
Cheers,
/Michael
Hello,
Maybe it would be interesting to also refer to the following article to encrypt the appkey to be placed in config.json
How to encrypt and use an appKey through the EMS in ThingWorx
https://www.ptc.com/en/support/article?n=CS247813
I don't know if such encryption is also possilbe for the password for the http_server setting ?
Regards,
Tom
Thanks Tom, haven't seen this before.
Encrypting the passwords will definitely add another layer of security. I haven't tried it yet with the http_server setting though.