Never Ending Security

It starts all here

Self Hosted CryptoCat – Secure self hosted multiuser webchat and SSL Certificate Setup

This is a guide on setting up a self hosted secure multiuser webchat service with CryptoCat. It covers the set up of ejabberd, nginx and the web interface for CryptoCat. It supports secure encrypted group chat, secure encrypted private chat and file and photo sharing.

There were/are some issues with the encryption provided by CryptoCat. These seem to be fixed now, but still, beware.

This tutorial is tested on Ubuntu 12.04.

Set up a DNS record

Make sure you set up two DNS A records to your chat server. One should be for example and the other is for the conferencing: You should contact your provider if you need help with this.

In the configuration files, you should replace with your own domain name.

Install required packages

First we install the required packages:

apt-get install ejabberd nginx vim git

ejabberd configuration

Edit the ejabberd configuratio file located:


And place the following contents in it, replacing with your own domain:

%% Hostname
{hosts, [""]}.

%% Logging
{loglevel, 0}.

  {5222, ejabberd_c2s, [
            {access, c2s},
            {shaper, c2s_shaper},
            {max_stanza_size, infinite},
            starttls, {certfile, "/etc/ejabberd/ejabberd.pem"}

  {5280, ejabberd_http, [

{s2s_use_starttls, true}.

{s2s_certfile, "/etc/ejabberd/ejabberd.pem"}.

{auth_method, internal}.
{auth_password_format, scram}.

{shaper, normal, {maxrate, 500000000}}.

{shaper, fast, {maxrate, 500000000}}.

{acl, local, {user_regexp, ""}}.

{access, max_user_sessions, [{10, all}]}.

{access, max_user_offline_messages, [{5000, admin}, {100, all}]}. 

{access, c2s, [{deny, blocked},
           {allow, all}]}.

{access, c2s_shaper, [{none, admin},
              {normal, all}]}.

{access, s2s_shaper, [{fast, all}]}.

{access, announce, [{allow, admin}]}.

{access, configure, [{allow, admin}]}.

{access, muc_admin, [{allow, admin}]}.

{access, muc, [{allow, all}]}.

{access, register, [{allow, all}]}.

{registration_timeout, infinity}.

{language, "en"}.

  {mod_privacy,  []},
  {mod_ping, []},
  {mod_private,  []},
  {mod_http_bind, []},
  {mod_admin_extra, []},
  {mod_muc,      [
          {host, "conference.@HOST@"},
          {access, muc},
          {access_create, muc},
          {access_persistent, muc},
          {access_admin, muc_admin},
          {max_users, 500},
          {default_room_options, [
            {allow_change_subj, false},
            {allow_private_messages, true},
            {allow_query_users, true},
            {allow_user_invites, false},
            {anonymous, true},
            {logging, false},
            {members_by_default, false},
            {members_only, false},
            {moderated, false},
            {password_protected, false},
            {persistent, false},
            {public, false},
            {public_list, true}
  {mod_register, [
          {welcome_message, {"Welcome!"}},
          {access, register}

NGINX Configuration

We need an SSL certificate for the web server. You can generate one yourself using the following command:

cd /etc/ssl/certs
openssl req -nodes -x509 -newkey rsa:4096 -keyout key.pem -out cert.crt -days 356

Or generate a CSR and let it sign by a “official” CA like verisign or digicert:

cd /etc/ssl/certs
openssl req -nodes -newkey rsa:4096 -keyout private.key -out CSR.csr 

When the certificate is in place you can continue to configure NGINX.

Edit the file or create a new virtual host.

vim /etc/nginx/sites-enabled/default

And place the following contents in it, replacing with your own domain:

server {
    listen 80;
    listen [::]:80 default ipv6only=on;

    rewrite     ^   https://$server_name$request_uri? permanent;

    add_header Strict-Transport-Security max-age=31536000;

    location / {
            root /var/www;
            index index.html index.htm;

# HTTPS server
server {
    listen 443;

    add_header Strict-Transport-Security max-age=31536000;

    ssl  on;
    ssl_certificate  /etc/ssl/certs/cert.crt;
    ssl_certificate_key  /etc/ssl/certs/key.pem;

    ssl_session_cache shared:SSL:10m;
    ssl_session_timeout 5m;

    ssl_protocols TLSv1.1 TLSv1.2;
            ssl_prefer_server_ciphers on;

    location / {
        root /var/www;
        index index.html index.htm;

    location /http-bind {
        proxy_buffering off;
        tcp_nodelay on;
        keepalive_timeout 55;

Save it and restart NGINX:

/etc/init.d/nginx restart

Cronjob for ejabberd

This is important, it cleans up unused ejabberd accounts. Create a new crontab like so:

crontab -e

And place the following in it:

1 1 * * * ejabberdctl delete-old-users 1

That way once every 24 hours the ejabberd server gets cleaned up.

Web Frontend

Note that you now already can use your own server with the CryptoCat frontend via: We are going to set up our own frontend on our webserver so we don’t need Crypto.Cat.

Setting up a web frontend is not recommended by the cryptocat developers. See the comment below, and read the full thread on this Reddit post

When you host Cryptocat as a website, this means that every time someone wants to use it, they technically will need to re-download the entire code by visiting the website. This means that every use needs a full re-download of the Cryptocat code. By centralizing the code redistribution in a "web front-end" and making it necessary for everyone to redownload the code every time, you create an opportunity for malicious code poisoning by the host, or code injection by a third party. This is why the only recommended Cryptocat download is the browser extension from the official website, which downloads only once as opposed to every time (just like a regular desktop application), and is authenticated by Cryptocat's development team as genuine.  
Kaepora - 12-11-2013 on Reddit

Take that into consideration when setting up the frontend. A use case could be an internal cryptocat chat service where people don’t need to change the default server address and such.

First get the source code:

cd /tmp
git clone

Then place it in the right folder;

cp -r cryptocat/src/core /var/www/

Edit the config file to use your own server:

cd /var/www
vim js/cryptocat.js

And place the following contents in it, replacing with your own domain:

/* Configuration */
// Domain name to connect to for XMPP.
var defaultDomain = ''
// Address of the XMPP MUC server.
var defaultConferenceServer = ''
// BOSH is served over an HTTPS proxy for better security and availability.
var defaultBOSH = ''

Now save the file.

You are finished now. Go to your website and test the chat out.

Ejabberd SSL Certificate

This tutorial shows you how to set up an SSL Certificate for use with Ejabberd. It covers both the creation of the Certificate Signing Request, the preparing of the certificate for use with Ejabberd and the installation of the certificate.

This tutorial assumes a working ejabberd installation. It is tested on Debian and Ubuntu, but should work on any ejabberd installation.

Steps and Explanation

To get an SSL certificate working on ejabberd we need to do a few things:

  • Create an Certificate Signing Request (CSR) and a Private Key
  • Submit the CSR to a Certificate Authority, let them sign it and give you a Certificate
  • Combine the certificate, private key (and chain) into a ejabberd compatible PEM file
  • Install the certificate in ejabberd

With a certificate we can secure our XMPP connection and conversations. This way it is much harder for others to spy on your conversations. Combined with OTR this enabled a super secure channel for conversation.

Creating the Certificate Signing Request

Create a folder to store all the files and cd to that:

mkdir -p ~/Certificates/xmpp cd ~/Certificates/xmpp

Now use OpenSSL to create both a Private Key and a CSR. The first command will do it interactively, the second command will do it non-interactive. Make sure to set the correct values, your Common Name (CN) should be your XMPP server URL:


openssl req -nodes -newkey rsa:2048 -keyout private.key -out CSR.csr


openssl req -nodes -newkey rsa:2048 -keyout private.key -out CSR.csr -subj “/C=NL/ST=State/L=City/O=Company Name/OU=Department/”

This will result in two files, CSR.csr and private.key. You now have to submit the CSR to a Certificate Authority. This can be any CA, I myself have good experiences with Xolphin, but there are others like Digicert and Verisign.

Once you have submitted your CSR and have gotten a Certificate you can continue.

Creating the ejabberd certificate

Once you have all the files (private key, certificate and certificate chain), put them all in a folder and continue. We are going to cat all the required files into a ejabberd.pem file.

This needs to happen in a specific order:

  • private key
  • certificate
  • chains

So adapt the following commands to your filenames and create the pem file:

cat private.key >> ejabberd.pem cat certificate.pem >> ejabberd.pem cat chain-1.pem >> ejabberd.pem cat chain-2.pem >> ejabberd.pem

If that all works out continue.

Installing the certificate in ejabberd

Copy the certificate to all your ejabberd servers:

scp ejabberd.pem

The place the certificate in the /etc/ejabberd folder:

cp ejabberd.pem /etc/ejabberd/ejabberd.pem

Now change the ejabberd config to point to the new certificate:

vim /etc/ejabberd/ejabberd.cfg

Check/change the following to point to the new certificate:

[…] {listen, [ {5222, ejabberdc2s, [ {access, c2s}, {shaper, c2sshaper}, {maxstanzasize, 65536}, starttls, {certfile, “/etc/ejabberd/ejabberd.pem”} ]}, […] {s2susestarttls, true}. {s2s_certfile, “/etc/ejabberd/ejabberd.pem”}. […]

Afterwards restart ejabberd:

/etc/init.d/ejabberd restart

You can now use any XMPP client to connect with SSL/TLS to see if it works.


Leave a Reply

Please log in using one of these methods to post your comment: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s