How to Set Up Client SSL Certificate Authentication for Rocket.Chat

Are you looking to add an extra layer of security to access Rocket.Chat? One way to do this is by implementing client SSL certificate authentication. This authentication method requires clients to present a valid SSL certificate to authenticate themselves to the server.

In this post, we will walk through the steps to set up client SSL certificate authentication using Nginx.

Prerequisites

Step 1: Install Docker

Lets do a quick and easy install of Docker if you haven't already.

curl -L https://get.docker.com | sh

Now Lets add your user to the docker group so you don't have to use sudo before every docker command.

sudo usermod -aG docker $USER

Normally here we'd say logout and back in.. but I don't want to mess with it so I use:

newgrp docker

Step 2: Install Rocket.Chat

Now that we have Docker installed lets get Rocket.Chat up and running.

Start off with creating a rocketchat directory and grabbing the docker-compose file:

mkdir rocketchat && cd "$_"
curl -L https://go.rocket.chat/i/docker-compose.yml -O

Next lets fire it up.

docker compose up -d

If impatient or only came here to install Rocket.Chat you could access on port 3000 if your firewall is open. But I suspect you came here for seeing how to do client SSL. So lets carry on!

Step 3: Install Nginx

sudo apt install -y nginx

Step 4: Install Certbot

To help us get a valid certificate we are going to use letsencrypt but using a tool called certbot. This will help us make sure to keep the certificate valid as well.

sudo snap install --classic certbot

Now use certbot to generate and plug everything up for letsencrypt and nginx:

sudo certbot --nginx

You’ll be asked to provide a valid email and the domain set.

Step 5: Generate Certificate Authority (CA) Certificates

In order to do client SSL Authentication we’re going to need a CA.

Generate a key for your CA:

openssl genrsa -des3 -out ca.key 4096

Generate a certificate for your CA:

openssl req -new -x509 -days 365 -key ca.key -out ca.crt
openssl x509 -in ca.crt -noout -text

Move CA cert

To: /etc/ssl/private/client-cert-ca.crt

Update Nginx config

We need to add CA cert, turn on client ssl authentication and add location block:

ssl_client_certificate /etc/ssl/private/client-cert-ca.crt;
ssl_verify_client optional;

location / {
   if ($ssl_client_verify != SUCCESS) {
     return 403;
   }

    proxy_pass http://localhost:3000;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto https;
    proxy_set_header X-Nginx-Proxy true;
    proxy_redirect off;
  }

Step 6: Issue Client SSL Certificates for users

You can have your users perform most of these steps if you want. But the following are the steps needed to create a certificate to present as client authentication.

Generate key for user

openssl genrsa -des3 -out user.key 4096

Generate a CSR

openssl req -new -key user.key -out user.csr

Sign CSR with CA

As the admin, take the CSR given to you or generated by you and sign the CSR and create valid certificate:

openssl x509 -req -days 365 -in user.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out user.crt

Return Certificate

The signed certificate (user.crt) can now be sent back to the user along with the CA cert(ca.crt).

To be able to use in browsers and mobile generate a pkcs #12 using the user cert and key along with the Ca:

openssl pkcs12 -export -out user.pfx -inkey user.key -in user.crt -certfile ca.crt

Beware if you intend to install on Mac or iOS, you may need to use an older version of OpenSSL. More info here: https://developer.apple.com/forums/thread/697030?answerId=710429022#710429022

Step 7: Access Rocket.Chat using Client SSL Certificate

To access your application with client certificate authentication:

On iOS:

On Android:

On Firefox:

Congratulations! You have successfully set up client SSL certificate authentication for Rocket.Chat using Nginx.

Extremely useful Reference: https://fardog.io/blog/2017/12/30/client-side-certificate-authentication-with-nginx/