Secure Node-RED with Nginx and OpenSSL on Ubuntu 16.04

Nginx is a very popular and very light web server. In this tutorial, we will use Nginx to implement a secure proxy using an OpenSSL self-signed certificate. This tutorial has been developed on Ubuntu 16.04 LTS but the method remains similar for other distributions. To install Node-RED on an Ubuntu distribution, follow this previous tutorial.

Installation of Nginx

Nginx installs very simply using a simple apt-get command.

sudo apt-get update
sudo apt-get install nginx

Accept the installation of all the dependencies that are requested during installation.

Create an SSL certificate with openSSL

Let’s start by creating a directory in which the SLL certificate will be stored

sudo mkdir /etc/nginx/ssl

Now that we have a destination location, we can create the SSL certificate and key

sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/nginx/ssl/nginx.key -out /etc/nginx/ssl/nginx.crt

Some explanations :

  • Openssl: The command to create and manage certificates, keys, and other files
  • Req: the type of certificate you want. In this case X.509
  • -days 365: length of time the certificate is considered valid

Answer the questions

  • Country Name (2 letter code) [AU]: country code, eg FR
  • State or Province Name (full name) [Some-State]: department
  • Locality Name (eg, city) []: City
  • Organization Name (eg, company) [Internet Widgits Pty Ltd]: Company Name
  • Organizational Unit Name (eg, section) []: service
  • Common Name (e.g. server FQDN or YOUR name) []: name of your site, eg domain.com
  • Email Address []: contact email address
  • The openssl command generates 2 files from this information, nginx.crt and nginx.key

Configure Nginx to use an SSL connection

Now that we have a key and a certificate, we will create a configuration file. We can call it node-red.securise.com.

Open a new configuration file with nano

sudo nano /etc/nginx/sites-available/node-red.securise.com

Adapt the example below according to your needs and paste it into the file then save with CTRL+X then Y.

server {
    listen 80;
    listen 443 ssl http2;
    server_name node-red.securise.com;
    ssl_certificate /etc/nginx/ssl/nginx.crt;
    ssl_certificate_key /etc/nginx/ssl/nginx.key;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+$
    ssl_prefer_server_ciphers On;
    ssl_session_cache shared:SSL:128m;
    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 8.8.8.8;

    location / {
        if ($scheme = http) {
            return 301 https://$server_name$request_uri;
        }
        proxy_pass http://localhost:1880;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }

    location '/.well-known/acme-challenge' {
        root /var/www/html;
    }
}

Some explanations (fast)

  • The key server_name is used to define the name of the website by which you will get a secure connection via Nginx.
  • The ssl_certificate and ssl_certificate_key keys define the folder where the certificate and the previously created key are located.
  • The “if ($ scheme = http) {return 301 https: // $ server_name $ request_uri;}” block allows you to return all unsecured HTTP connections to an HTTPS
  • “Proxy_pass http: // localhost: 1880;” Allows you to point to the page of Node-RED

It remains to create a symbolic link to the sites-enabled folder to make the configuration active.

sudo ln -s /etc/nginx/sites-available/node-red.securise.com /etc/nginx/sites-enabled/

To make the URL accessible from a browser, you need to modify the hosts file. Retrieve the IP address of your PC with the ifconfig command and then edit the /etc/hosts  file

sudo nano /etc/hosts

and add for example

127.0.0.1       localhost
192.168.2.2     node-red.securise.com

Save

Firewall Configuration

We will now configure the firewall to prevent the connection through port 1880. Let’s first add a rule to allow HTTP and HTTPS connections from Nginx.

Let’s first check the available applications:

$ sudo ufw app list
Applications disponibles :
  CUPS
  Nginx Full
  Nginx HTTP
  Nginx HTTPS

Three Nginx profiles are available:

  • Nginx Full: This profile opens ports 80 (unencrypted traffic) and 443 (TLS / SSL encrypted traffic)
  • Nginx HTTP: only opens port 80 (not encrypted)
  • Nginx HTTPS: only opens port 443 encrypted

We activate the “Nginx Full” profile like this

sudo ufw allow 'Nginx FULL'

To find out if the firewall is started

$ sudo ufw status
Etat : inactif

If the firewall has not yet started, run

sudo ufw enable

Now check the firewall configuration

Status: active

To                         Action      From
--                         ------      ----
1880                       ALLOW       Anywhere                  
Nginx Full                 ALLOW       Anywhere                  
1880 (v6)                  ALLOW       Anywhere (v6)             
Nginx Full (v6)            ALLOW       Anywhere (v6)

At this point, Node-RED is still accessible at http://localhost: 1880. We will add a rule to forbid any connection from port 1880.

sudo ufw deny 1880

Re-check the firewall configuration

Status: active

To                         Action      From
--                         ------      ----
1880                       DENY       Anywhere                  
Nginx Full                 ALLOW      Anywhere                  
1880 (v6)                  DENY       Anywhere (v6)             
Nginx Full (v6)            ALLOW      Anywhere (v6)

Editing the Node-RED settings.js file

All we have to do now is add a password authentication to Node-RED. To do this, first add the node-red-admin module (unless it is already installed).

sudo npm install -g --unsafe-perm node-red-admin

Let’s now generate a hash of your password. Run the following command. Enter the password and confirm. In return, you will get the fingerprint of your password. Select it and right click and copy.

node-red-admin hash-pw

Open the configuration file

nano ~/.node-red/settings.js

Locate the adminAuth section and comment out the entire block

adminAuth: {
    type: "credentials",
    users: [{
        username: "admin",
        password: "%2a$08$Ab9prIr1M8a5a1LZx8.B9.uIOCPe.v90ZGuZc2kAATp6BHJ/WV5KS",
        permissions: "*"
    }]
},

Do not change the permissions. Change the user name if you want and paste the previously generated fingerprint. To paste it, place the cursor with the arrows then right click and paste between the quotation marks.

If you do not want Node-RED to be accessible from another computer on the network, uncomment the uihost line

uiHost: "127.0.0.1",

Start

Everything is ready. Let’s start by restarting Nginx

sudo systemctl reload nginx

Then, we restart Node-RED

sudo systemctl start node-red

All you have to do is connect with the new address http://node-red.securise.com.

At the first login, the browser (Firefox in this case) will refuse the connection and notify you that the certificate is invalid. As we have created a self-signed certificate using OpenSSL this is perfectly normal.

node-red nginx securise ss

Simply add an exception rule before proceeding.

node-red nginx securise ssl ajout exception

Enter your username and password

node-red nginx securise ssl page connexion

And here you are now connected to Node-RED in a more secure way.

 node-red nginx securise ssl page flows

Useful links

Subscribe to the weekly newsletter

No spam and no other use will be made of your email. You can unsubscribe anytime.

Tags:

We will be happy to hear your thoughts

Leave a Reply

DIY Projects
%d bloggers like this: