Pages

Thursday, December 21, 2017

How-to: Make MongoDB HIPAA compliant

Configuring encryption at rest

To enable encryption in MongoDB you should start mongod with --enableEncryption option.
Also, you need to decide where you are going to store the master key. You can store it either in external key manager which is the recommended way since this is necessary to meet HIPAA guidelines, or locally.
You will need to get an external key manager application that supports KMIP communication protocol. For example, this: https://www.townsendsecurity.com/products/centralized-encryption-key-management

To start mongodb with the new key use this command:
mongod --enableEncryption --kmipServerName <KMIP Server HostName> --kmipPort <KMIP server port> --kmipServerCAFile <ca file path> --kmipClientCertificateFile <certificate file path>
Now about the two last options:
--kmipServerCAFile <string>
Path to CA File. Used for validating secure client connection to KMIP server.
--kmipClientCertificateFile <string>
A string containing the path to the client certificate used for authenticating MongoDB to the KMIP server.

If the command succeeds then in the log file you will see the following messages:
[initandlisten] Created KMIP key with id: <UID>
[initandlisten] Encryption key manager initialized using master key with id: <UID>
If a key already exists, then use the following command to start mongodb:
mongod --enableEncryption --kmipServerName <KMIP Server HostName> --kmipPort <KMIP server port> --kmipServerCAFile <ca file path> --kmipClientCertificateFile <certificate file path> --kmipKeyIdentifier <UID>
To read the full article about mongodb encryption at rest, follow this link: https://docs.mongodb.com/manual/core/security-encryption-at-rest/

Transport encryption

On server side

Before you can use SSL, you must have a .pem file containing a public key certificate and its associated private key.
MongoDB can use any valid SSL certificate issued by a certificate authority, or a self-signed certificate. If you use a self-signed certificate, although the communications channel will be encrypted, there will be no validation of server identity.

Set Up mongod with SSL Certificate and Key

To use SSL in your MongoDB deployment, start mongod including following run-time options:
  • net.ssl.mode set to requireSSL. This setting restricts each server to use only SSL encrypted connections. You can also specify either the value allowSSL or preferSSL to set up the use of mixed SSL modes on a port.
  • PEMKeyfile with the .pem file that contains the SSL certificate and key.
Syntax should be following:
mongod --sslMode requireSSL --sslPEMKeyFile <pem> <additional options>
You may also specify these options in the configuration file, as in the following example:
net:
    ssl:
        mode: requireSSL
        PEMKeyFile: /etc/ssl/mongodb.pem

Set Up mongod with Certificate Validation

Along with options from the previous methods you should also set up CAFile with the name of the .pem file that contains the root certificate chain from the Certificate Authority.
Syntax:
mongod --sslMode requireSSL --sslPEMKeyFile <pem> --sslCAFile <ca> <additional options>
If you prefer using a configuration file, then:
net:
    ssl:
        mode: requireSSL
        PEMKeyFile: /etc/ssl/mongodb.pem
        CAFile: /etc/ssl/ca.pem

Disallow Protocols

To prevent MongoDB servers from accepting incoming connections that use specific protocols, including the --sslDisabledProtocols option, or if using the configuration file the net.ssl.disabledProtocols setting.
mongod --sslMode requireSSL --sslDisabledProtocols TLS1_0,TLS1_1 --sslPEMKeyFile /etc/ssl/mongodb.pem --sslCAFile /etc/ssl/ca.pem <additional options>
If you use config file:
net:
    ssl:
        mode: requireSSL
        PEMKeyFile: /etc/ssl/mongodb.pem
        CAFile: /etc/ssl/ca.pem
        disabledProtocols: TLS1_0,TLS1_1

SSL Certificate Passphrase

The PEM files for PEMKeyfile and ClusterFile may be encrypted. With encrypted PEM files, you must specify the passphrase at startup with a command-line or a configuration file option or enter the passphrase when prompted. To specify the passphrase in clear text on the command line or in a configuration file, use the PEMKeyPassword and/or the ClusterPassword option.

On client side

For C#:
To read a full article about mongodb transport encryption, follow this link: https://docs.mongodb.com/manual/core/security-transport-encryption/

Performance (of encryption at rest)

CPU: 3.06GHz Intel Xeon Westmere(X5675-Hexcore)
RAM: 6x16GB Kingston 16GB DDR3 2Rx4
OS: Ubuntu 14.04-64
Network Card: SuperMicro AOC-STGN-i2S
Motherboard: SuperMicro X8DTN+_R2
Document Size: 1KB
Workload: YCSB
Version: MongoDB 3.2
In such environment they've got following results:
In addition to throughput, latency is also a critical component of encryption overhead. From our benchmark, average latency overheads ranged between 6% to 30%. Though average latency overhead was slightly higher than throughput overhead, latencies were still very low—all under 1ms.

Average Latency (µs)
Unencrypted
Encrypted
% Overhead
Insert OnlyAverage Latency32.440.9-26.5%
Read Only
Working Set Fits In
Memory Avg Latency
230.5245.0-6.3%
Read Only
Working Set Exceeds
Memory Avg Latency
447.0565.8-26.6%
50% Insert / 50% Read
Working Set Fits In
Memory Avg Latency
276.1317.4-15.0%
50% Insert / 50% Read
Working Set Exceeds
Memory Avg Latency
722.3936.5-29.7

Thursday, August 17, 2017

WebRTC overview for using for server – client push notifications

Description

WebRTC is a free, open project that provides browsers and mobile applications with Real-Time Communications (RTC) capabilities via simple APIs.
Basically, it is intended for applications with peer-to-peer architecture and video and audio streaming.

As well as audio and video, WebRTC supports real-time communication for other types of data.
The RTCDataChannel API enables a peer-to-peer exchange of arbitrary data, with low latency and high throughput.
It can use reliable (TCP) or unreliable (UDP) messages.

Components diagrams (infrastructure):


There are the following components:
  1. Signaling server. Signaling is the process of coordinating communication. This signaling process needs a way for clients to pass messages back and forth. That mechanism is not implemented by the WebRTC APIs: you need to build it yourself. (see more https://www.html5rocks.com/en/tutorials/webrtc/infrastructure/#what-is-signaling);
  2. ICE technique. WebRTC apps can use the ICE framework to overcome the complexities of real-world networking. To enable this to happen, your application must pass ICE server URLs to RTCPeerConnection. ICE tries to find the best path to connect peers. It tries all possibilities in parallel and chooses the most efficient option that works. ICE first tries to make a connection using the host address obtained from a device's operating system and network card; if that fails (which it will for devices behind NATs) ICE obtains an external address using a STUN server, and if that fails, traffic is routed via a TURN relay server. (see more https://www.html5rocks.com/en/tutorials/webrtc/infrastructure/#after-signaling-using-ice-to-cope-with-nats-and-firewalls);
  3. A STUN server is used to get an external network address;
  4. TURN servers are used to relay traffic if direct (peer to peer) connection fails.

Minuses of using WebRTC for our goals:

  1. Basically, it is intended for applications with P2P architecture and video and audio streaming. Not for server and clients communications;
  2. IE and Safari don't support it protocol out of the box.
  3. Too complex deployment architecture. You need to set up a signal, STUN, TURN servers and other quite kind of complex infrastructure. It will take the additional cost from you;
  4. You don’t have out of the box library for .NET, for example (There are some repos in GitHub, but it does not look as very popular and often used). Although, you have ORTC (https://ortc.org/);
  5. You will need to develop and maintain own connection state manager on the server. If you want to detect online and offline users, and to catch the client's endpoints (IP, port);
  6. I have experience of using WebRTC in one of my projects. It is used for calling not more than two users. Some feedback about WebRTC:
  • We raised for this three separate servers (signal server which hosts NodeJS application SimpleWebRTC https://github.com/andyet/SimpleWebRTC), TURN and STUN servers which ran in Azure via “Free open source implementation of TURN and STUN Server” project Coturn (https://github.com/coturn/coturn);
  • On the client we use signalmaster framework (https://github.com/andyet/signalmaster);
  • Video communication does not work well with bad internet;
  • Customers have them on the IOS and Android. There are reviews that the application consumes the battery very much.

Some conclusion

You should consider using WebRTC only if:
  1. You have a goal to get rid of the 3rd party products that provide us with video/audio streaming and communication.
  2. You want to use it for its intended purpose (for peer-to-peer communications). In this case, you need to design the architecture specifically for these features or write a stand-alone unit, like now VUDYO.
If you will use WebRTC for just push notifications from the server to clients, it will be like a shot from a cannon on sparrows.                                                                                                                        

Some other links: