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
Password Encryption
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.
LSR Configuration
In the config.lua there are two sections to be configured:
scripts.script_resource which deals with the configuration of the LSR itself
scripts.rap which deals with the connection to the EMS
HTTP Server Authentication
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=="
HTTP Server TLS Configuration
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).
Connection to the EMS
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.
EMS Configuration
In the config.lua there are two sections to be configured:
http_server which enables the HTTP Server capabilities for the EMS
certificates which holds all certificates that the EMS must verify in order to communicate with other servers (ThingWorx Platform, LSR)
HTTP Server Authentication and TLS Configuration
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).
Certificates Configuration
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.
Binding to the LSR
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.
Tips
Do not use quotation marks (") as part of the strings to be encrypted. This could result in unexpected behavior when running the encryption script.
Do not use a semicolon (:) as part of any username. Authentication tokens are passed from browsers as "username:password" and a semicolon in a username could result in unexpected authentication behavior leading to failed authentication requests.
In the Server Specific certificates, the CN must match the actual server name and also must match the name of the http_server.host (EMS) or script_resource_host (LSR)
In the .pem files first store Server Specific certificates, then all required Intermediate CAs and finally all required Root CAs - any other order could affect the consistency of the files and the certificate might not be fully readable by the scripts and processes.
If the EMS is configured with certifcates, the LSR must connect via a secure channel as well and needs to be configured to do so.
If the LSR is configured with certifcates, the EMS must connect via a secure channel as well and needs to be configured to do so.
For testing REST API calls with resources that require encryptions and authentcation, see also How to run REST API calls with Postman on the Edge Microserver (EMS) and Lua Script Resource (LSR)
Export PEM data from KeyStore Explorer
To generate a .pem file I usually use the KeyStore Explorer for Windows - in which I have created my certificates and manage my keystores.
In the keystore, select a certificate and view its details
Each certificate and CA in the chain can be viewed: Root, Intermediate and Server Specific
Select each certificate and CA and use the "PEM" button on the bottom of the interface to view the actual PEM content
Copy to clipboard and paste into .pem file
To generate a .pem file for the private key,
Right-click the certificate > Export > Export Private Key
Choose "PKCS #8"
Check "Encrypted" and use the default algorithm; define an "Encryption Password"; check the "PEM" checkbox and export it as .pkcs8 file
The .pkcs8 file can then be renamed and used as .pem file
The password set during the export process will be the scripts.script_resource_passphrase (LSR) or the http_server.passphrase (EMS)
After generating the .pem files I copy them over to my Linux systems where they will need 644 permissions (-rw-r--r--)
View full tip