Secure Kuzzle using NGINX and SSL

 Version française


   Hello everyone! A few weeks ago this question has been posted a lot on our Gitter channel. So we decided to write a short blog post to help system administration beginners to set up a SSL proxy for Kuzzle properly. In this article, I'll assume that you with a Kuzzle running somewhere. If you're not, use our installation script available on the website or get the Docker Compose file.

Choose your proxy

    Once you get your Kuzzle server up and running, you'll need to choose the proxy you want to use with Kuzzle. Nginx and HAProxy are good choices. Note that NGINX reloading keeps active WebSocket connections alive. If you're on Linux you can easily install them using your favorite package manager. MacOS and Windows users should use them in Docker containers. There it is official NGINX and HAProxy images.

Generate the SSL certificate

    Whether you use NGINX, HAProxy or another proxy. You must first obtain an SSL certificate. For that purpose, you can generate your own (especially if you're still in the development phase) or just get a free one using Let's Encrypt. Let's assume that we are still in development and generate a self-signed certificate for localhost using OpenSSL:


~ $
openssl req -x509 -newkey rsa:4096 -keyout localhost.key -out localhost.crt -days 365 -nodes


It will prompt you a few question:


Generating a RSA private key
writing new private key to 'localhost.key'
----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. -----
Country Name (2 letter code) [AU]:FR State or Province Name (full name) [Some-State]:Occitanie Locality Name (eg, city) []:Montpellier Organization Name (eg, company) [Internet Widgits Pty Ltd]:Kuzzle Organizational Unit Name (eg, section) []:IT Common Name (e.g. server FQDN or YOUR name) []:localhost Email Address []


Not all of them are mandatory, since we're generating a development certificate. The Common Name need to match the FQDN you want to use for your Kuzzle stack. Keep these files aside, we will use them in the next steps. If you do not have OpenSSL installed on your host check this site. It will generate SSL key and certificate for a given domain name and give you files to download.

Proxy configuration

At this stage, you should have:

  • A Kuzzle stack running
  • A proxy service installed on your host or in a container.
  • The two SSL files we created in last step

It's time to configure your proxy to handle request and connections in front of Kuzzle. Here is how it can be done using NGINX:


$http_upgrade $connection_upgrade { default upgrade; '' close; } upstream kuzzle { server localhost:7512; } server { listen 17512 ssl; proxy_read_timeout 3600s; ssl_certificate /path/to/your/ssl/cert/localhost.crt; ssl_certificate_key /path/to/your/ssl/key/localhost.key; error_page 497 https://$host:17512$request_uri; location / { proxy_pass http://kuzzle; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $connection_upgrade; } }


This configuration file should be saved in /etc/nginx/sites-available and you need to create a symbolic link to it in the /etc/nginx/sites-enabled directory:


~ #
vim /etc/nginx/sites-available/kuzzle.conf
~ # ln -s /etc/nginx/sites-available/kuzzle.conf /etc/nginx/sites-enabled/kuzzle.conf
~ # systemctl reload nginx.service


If you're using NGINX in a Docker container check instructions on the Docker image description to know where to mount the configuration file and SSL files in it. After NGINX configuration reloading, your Kuzzle endpoint should be available at https://locahost:17512. Note that your web browser may show you an error message about security. If you created an self-signed certificate it is normal don't worry.


I hope this article answer your questions, do not hesitate to come join us on Discord. We're also available on website and documentation integrated chat.


Alexandre Bouthinon

Related posts