In this article, I show how to deploy a meteor app (Rocketchat) with tls/ssl encryption using self-signed certificates:

  • https between client and the app server
  • tls/ssl between the app server and mongodb

My setup:

  • docker
  • the server running docker is a debian server
  • the app server and mongodb can be running either on a single or different machines
  • the containers are in a virtual network running on a single machine
  • the certificates are self-signed
  • stud is used for https, other solutions can be used.

The steps are applicable to any framework and app using mongodb as a database.

The commands below are available in the git securingMeteorWithSSL.

Steps:

  • Install docker
  • Generate certificates
  • Create the docker images
  • Setup Mongodb
  • Setup the app server (RocketChat)

Install docker

My server runs Debian Jessie, so I install docker from the jessie repo:

export DEBIAN_FRONTEND=noninteractive ; \
apt-get update -y ;\
apt-get install -y -q apt-transport-https ;\
apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D ;\
echo "deb https://apt.dockerproject.org/repo debian-jessie main" > /etc/apt/sources.list.d/docker.list ;\
apt-get update -y -q;\
apt-get upgrade -y -q;\
apt-get install -y -q docker-engine

docker network create --subnet=172.18.0.0/16 intranet

The private virtual network is intranet 172.18.0.0/16.

Generate certificates

3 certificates are needed for this setup:

  • a Certificate Authority (CA) to sign the certificates
  • a certificate for the app server (https)
  • a certificate for mongodb

Creating a Certificate Authority (CA)

# create a private key file
openssl genrsa -out exampleCA.key 2048

# create the CA certificate
openssl req -x509 -sha256 -new -key exampleCA.key -out exampleCA.crt -days 1460 -subj /CN="Example Inc. CA"

Creating a certificate for the app server (https)

# create a private key
openssl genrsa -out app.key 2048

# create the CSR
openssl req -new -out app.req -key app.key -subj /CN=www2.mysite.com

# use the CSR to create the certificate
openssl x509 -req -sha256 -in app.req -out app.crt -CAkey exampleCA.key -CA exampleCA.crt -days 730 -CAcreateserial -CAserial serial

# create pem file
cat app.key app.crt > app.pem

The CN in the CSR can be any address in a private network.

Creating a certificate for mongodb

Same steps as before with 127.0.0.1 as CN (in my setup mongodb doesnt take the hostname I provide neither with docker nor with my dns server):

# create a private key
openssl genrsa -out mongodb.key 2048

# create the CSR
openssl req -new -out mongodb.req -key mongodb.key -subj /CN=127.0.0.1

# use the CSR to create the certificate
openssl x509 -req -sha256 -in mongodb.req -out mongodb.crt -CAkey exampleCA.key -CA exampleCA.crt -days 730 -CAcreateserial -CAserial serial

# create pem file
cat mongodb.key mongodb.crt > mongodb.pem

Create the docker images

  • Mongodb image

Copy CA and mongodb certificate to new mongodb image, the CA is then added to the truststore:

FROM mongo

COPY exampleCA.crt /
COPY mongodb.pem /

RUN export DEBIAN_FRONTEND=noninteractive ;\
    apt-get purge -y ca-certificates ;\
    apt-get update -y ;\
    mkdir -p /usr/share/ca-certificates/ ;\
    cp exampleCA.crt /usr/share/ca-certificates/exampleCA.crt ;\
    apt-get install -y ca-certificates
  • Rockerchat image

Add stud and run as root to connect to port 443:

FROM rocketchat/rocket.chat

# use root for stud to be able to connect to port 443
USER root

COPY nodeStart.sh /opt/

# --- stud SETUP ---
RUN mkdir -p /opt/stud ;\
    mkdir -p /opt/certs ;\
    useradd stud || : ;\
    mkdir -p /usr/local/share/man/man8 ;\
    apt-get update -y ;\
    apt-get -y install libev4 libev-dev libssl-dev

COPY stud /usr/local/bin/
COPY stud.8 /usr/local/share/man/man8/
COPY stud.conf /opt/stud/

COPY app.pem /opt/certs/ssl.pem

EXPOSE 443
#EXPOSE 3000


CMD ["bash","/opt/nodeStart.sh"]

Build the images with:

docker build -t example/mongo .

docker build -t example/rocketchat .

Setup Mongodb

mkdir -p mongochatdb
docker container run -v mongochatdb:/data/db -d --net intranet --ip 172.18.0.2 --name mongochat --restart=always example/mongo --smallfiles --auth --sslMode requireSSL --sslPEMKeyFile /mongodb.pem --sslCAFile /exampleCA.crt --sslAllowConnectionsWithoutCertificates

Create mongo admin and chatdb user with mongoCreateAdmin.js and mongoChatAccess.js (NOTE: change the passwords):

mongoCreateAdmin.js

m  = new Mongo();
db = m.getDB('admin');
db.createUser(
  {
    user: "admin",
    pwd: "qwerty",
    roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
  }
);

mongoChatAccess.js

m  = new Mongo();
db = m.getDB('admin');
db.auth('admin', 'qwerty');
db = m.getDB('chatdb');
db.dropUser('chat');
db.createUser(
  {
    user: 'chat',
    pwd: 'qwerty',
    roles: [ { role: 'dbOwner', db: 'chatdb' } ]
  }
);

Add the users in mongodb:

docker cp mongoCreateAdmin.js mongochat:/
docker cp mongoChatAccess.js mongochat:/
docker exec mongochat mongo --ssl admin /mongoCreateAdmin.js
docker exec mongochat mongo --ssl -u "admin" -p "qwerty" --authenticationDatabase "admin" /mongoChatAccess.js

Setup the app server (RocketChat)

By default, the chat container exposes the port 443 but I already have a server running at this port, so I change the port to 3443.

The ROOT_URL is: https://127.0.0.1:3443

On the MONGO_URL, we need to give the mongodb user and password for the chatdb database and ssl is enabled with ?ssl=true

The rocketchat container runs in the same network as the mongodb container: --net intranet --ip 172.18.0.3

docker container run -p 3443:443 -e ROOT_URL=https://127.0.0.1:3443 -e MONGO_URL=mongodb://chat:qwerty@172.18.0.2/chatdb?ssl=true --net intranet --ip 172.18.0.3 -d --name chat --restart=always example/rocketchat
  • Add the exampleCA.crt CA to your browser truststore:
FIREFOX
preferences
advanced
certificates
view certificates
authorities
import

CHROME
settings
show advanced settings...
HTTPS/SSL
manage certificates
authorities
import

Rocketchat is available at:

https://127.0.0.1:3443

test app