Community Tip - Your Friends List is a way to easily have access to the community members that you interact with the most! X
This is a follow-up post on my initial document about Edge Microserver (EMS) and Lua Script Resource (LSR) security.
While the first part deals with fundamentals on secure configurations, this second part will give some more practical tips and tricks on how to implement these security measurements.
For more information it's also recommended to read through the Setting Up Secure Communications for WS EMS and LSR chapter in the ThingWorx Help Center.
See also Trust & Encryption Theory and Hands On for more information and examples - especially around the concept of the Chain of Trust, which will be an important factor for this post as well.
In this post I will only reference the High Security options for both, the EMS and the LSR.
Note that all commands and directories are Linux based - Windows equivalents might slightly differ.
Note - some of the configuration options are color coded for easy recognition: LSR resources / EMS resources
It's recommended to encrypt all passwords and keys, so that they are not stored as cleartext in the config.lua / config.json files.
And of course it's also recommended, to use a more meaningful password than what I use as an example - which also means: do not use any password I mentioned here for your systems, they might too easy to guess now 🙂
The luaScriptResource script can be used for encryption:
./luaScriptResource -encrypt "pword123" ############ Encrypted String AES:A26fBYKHJq+eMu0Fm2FlDw== ############
The wsems script can be used for encryption:
./wsems -encrypt "pword123" ############ Encrypted String AES:A26fBYKHJq+eMu0Fm2FlDw== ############
Note that the encryption for both scripts will result in the same encrypted string.
This means, either the wsems or luaScriptResource scripts can be used to retrieve the same results.
The string to encrypt can be provided with or without quotation marks. It is however recommended to quote the string, especially when the string contains blanks or spaces. Otherwise unexpected results might occur as blanks will be considered as delimiter symbols.
In the config.lua there are two sections to be configured:
HTTP Server Authentication will require a username and password for accessing the LSR REST API.
scripts.script_resource_authenticate = true scripts.script_resource_userid = "luauser" scripts.script_resource_password = "pword123"
The password should be encrypted (see above) and the configuration should then be updated to
scripts.script_resource_password = "AES:A26fBYKHJq+eMu0Fm2FlDw=="
Configuration
HTTP Server TLS configuration will enable TLS and https for secure and encrypted communication channels from and to the LSR.
To enable TLS and https, the following configuration is required:
scripts.script_resource_ssl = true scripts.script_resource_certificate_chain = "/pathToLSR/lsrcertificate.pem" scripts.script_resource_private_key = "/pathToLSR/key.pem" scripts.script_resource_passphrase = "keyForLSR"
It's also encouraged to not use the default certificate, but custom certificates instead. To explicitly set this, the following configuration can be added:
scripts.script_resource_use_default_certificate = false
Certificates, keys and encryption
The passphrase for the private key should be encrypted (see above) and the configuration should then be updated to
scripts.script_resource_passphrase = "AES:A+Uv/xvRWENWUzourErTZQ=="
The private_key should be available as .pem file and starts and ends with the following lines:
-----BEGIN ENCRYPTED PRIVATE KEY----- -----END ENCRYPTED PRIVATE KEY-----
As it's highly recommended to encrypt the private_key, the LSR needs to know the password for how to encrypt and use the key. This is done via the passphrase configuration. Naturally the passphrase should be encrypted in the config.lua to not allow spoofing the actual cleartext passphrase.
The certificate_chain holds the Chain of Trust of the LSR Server Certificate in a .pem file. It holds multiple entries for the the Root, Intermediate and Server Specific certificate starting and ending with the following line for each individual certificate and Certificate Authority (CA):
-----BEGIN CERTIFICATE----- -----END CERTIFICATE-----
After configuring TLS and https, the LSR REST API has to be called via https://lsrserver:8001 (instead of http).
Authentication
To secure the connection to the EMS, the LSR must know the certificates and authentication details for the EMS:
scripts.rap_server_authenticate = true scripts.rap_userid = "emsuser" scripts.rap_password = "AES:A26fBYKHJq+eMu0Fm2FlDw=="
Supply the authentication credentials as defined in the EMS's config.json - as for any other configuration the password can be used in cleartext or encrypted. It's recommended to encrypt it here as well.
HTTPS and TLS
Use the following configuration establish the https connection and using certificates
scripts.rap_ssl = true scripts.rap_cert_file = "/pathToLSR/emscertificate.pem" scripts.rap_deny_selfsigned = true scripts.rap_validate = true
This forces the certificate to be validated and also denies selfsigned certificates.
In case selfsigned certificates are used, you might want to adjust above values.
The cert_file is the full Chain of Trust as configured in the EMS' config.json http_server.certificate options.
It needs to match exactly, so that the LSR can actually verify and trust the connections from and to the EMS.
In the config.lua there are two sections to be configured:
HTTP Server Authentication will require a username and password for accessing the EMS REST API.
HTTP Server TLS configuration will enable TLS and https for secure and encrypted communication channels from and to the EMS.
To enable both the following configuration can be used:
"http_server": { "host": "<emsHostName>", "port": 8000, "ssl": true, "certificate": "/pathToEMS/emscertificate.pem", "private_key": "/pathToEMS/key.pem", "passphrase": "keyForEMS", "authenticate": true, "user": "emsuser", "password": "pword123" }
The passphrase as well as the password should be encrypted (see above) and the configuration should then be updated to
"passphrase": "AES:D6sgxAEwWWdD5ZCcDwq4eg==", "password": "AES:A26fBYKHJq+eMu0Fm2FlDw=="
See LSR configuration for comments on the certificate and the private_key. The same principals apply here.
Note that the certificate must hold the full Chain of Trust in a .pem file for the server hosting the EMS.
After configuring TLS and https, the EMS REST API has to be called via https://emsserver:8000 (instead of http).
The certificates configuration hold all certificates that the EMS will need to validate.
If ThingWorx is configured for HTTPS and the ws_connection.encryption is set to "ssl" the Chain of Trust for the ThingWorx Platform Server Certificate must be present in the .pem file.
If the LSR is configured for HTTPS the Chain of Trust for the LSR Server Certificate must be present in the .pem file.
"certificates": { "validate": true, "allow_self_signed": false, "cert_chain" : "/pathToEMS/listOfCertificates.pem" }
The listOfCertificates.pem is basicially a copy of the lsrcertificate.pem with the added ThingWorx certificates and CAs.
Note that all certificates to be validated as well as their full Chain of Trust must be present in this one .pem file.
Multiple files cannot be configured.
When binding to the LSR via the auto_bind configuration, the following settings must be configured:
"auto_bind": [{ "name": "<ThingName>", "host": "<lsrHostName>", "port": 8001, "protocol": "https", "user": "luauser", "password": "AES:A26fBYKHJq+eMu0Fm2FlDw==" }]
This will ensure that the EMS connects to the LSR via https and proper authentication.
Export PEM data from KeyStore Explorer