Securing node-red

1,379 views
Skip to first unread message

Dan Hoover

unread,
May 2, 2017, 1:29:08 PM5/2/17
to Node-RED
I'm trying to secure node-red/node-red-dashboard for the first time, but no matter what I put in, I get login failed.  

I was originally trying to use a password (As evidenced by my hashes in the lower part of the file), but even when I just put password as "" I get login failed. 

Here's my settings.js.  What am I missing?

    // Securing Node-RED
    // -----------------
    // To password protect the Node-RED editor and admin API, the following
    // property can be used. See http://nodered.org/docs/security.html for details.
adminAuth: {
    type: "credentials",
    users: [{
        username: "admin",
        password: "",
          permissions: "*"
       }]
   },

    // To password protect the node-defined HTTP endpoints (httpNodeRoot), or
    // the static content (httpStatic), the following properties can be used.
    // The pass field is a bcrypt hash of the password.
//    httpNodeAuth: {user:"admin",pass:"$2a$08$iygYDs4lHODd8t30n/a7NOTPAvt/FWO7W4crC/QVXitmkjJbckPC2"},
//    httpStaticAuth: {user:"admin",pass:"$2a$08$iygYDs4lHODd8t30n/a7NOTPAvt/FWO7W4crC/QVXitmkjJbckPC2"},

    // The following property can be used to enable HTTPS
    // for details on its contents.
    // See the comment at the top of this file on how to load the `fs` module used by
    // this setting.
    //
    //https: {
    //    key: fs.readFileSync('privatekey.pem'),
    //    cert: fs.readFileSync('certificate.pem')

Julian Knight

unread,
May 2, 2017, 3:25:06 PM5/2/17
to Node-RED
The password has to be a crypto hash. As per the docs. http://nodered.org/docs/security

Running this will generate a hash:

node -e "console.log(require('bcryptjs').hashSync(process.argv[1], 8));" your-password-here

Dan Hoover

unread,
May 2, 2017, 6:14:37 PM5/2/17
to Node-RED
I ran one and copied it....it's actually in those lower two password fields, but regardless, I can't login to node-red. hmm. 

Nick O'Leary

unread,
May 2, 2017, 7:28:19 PM5/2/17
to Node-RED

One thing at a time.

adminAuth does not accept blank passwords.

First, just try hashing a password of 'password', set that in adminAuth and share exactly how you have configured it.

Nick


On Tue, 2 May 2017, 23:14 Dan Hoover, <mud...@gmail.com> wrote:
I ran one and copied it....it's actually in those lower two password fields, but regardless, I can't login to node-red. hmm. 

--
http://nodered.org
 
Join us on Slack to continue the conversation: http://nodered.org/slack
---
You received this message because you are subscribed to the Google Groups "Node-RED" group.
To unsubscribe from this group and stop receiving emails from it, send an email to node-red+u...@googlegroups.com.
To post to this group, send email to node...@googlegroups.com.
Visit this group at https://groups.google.com/group/node-red.
To view this discussion on the web, visit https://groups.google.com/d/msgid/node-red/dad37200-c6fc-4b15-8ed6-906b89972a2c%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Dan Hoover

unread,
May 2, 2017, 7:39:34 PM5/2/17
to Node-RED
Now it keeps telling me it can't find bcrypt.js.  I know it was there because I hashed my first password.  Hmm.

Dan Hoover

unread,
May 2, 2017, 11:11:21 PM5/2/17
to Node-RED
I just don't understand. I've been at this all day. 

I'm on my 10th server of the day.  I'm all the way up to the point of securing it and now I've done my settings.js and it's not prompting me for a password.  Any ideas?

I've set

var fs = require("fs");

module.exports = {
    // the tcp port that the Node-RED web server is listening on
    uiPort: process.env.PORT || 1880,

and 

adminAuth: {
   type: "credentials",
   users: [{
        username: "admin",
        password: "$2a$myhash.",
        permissions: "*"
/    }]
},

    // To password protect the node-defined HTTP endpoints (httpNodeRoot), or
    // the static content (httpStatic), the following properties can be used.
    // The pass field is a bcrypt hash of the password.
httpNodeAuth: {user:"admin",pass:"$2a$myhash."},
httpStaticAuth: {user:"admin",pass:"$2a$myhash."},

    // The following property can be used to enable HTTPS

But no prompt for password on the live server...

Please help. 

Julian Knight

unread,
May 3, 2017, 2:17:25 AM5/3/17
to Node-RED
That string doesn't look like a hash to me. Did you try node-red-admin hash-pw
instead?

If you can't require bcrypt, you are in a different folder and it can't find it. You could always globally install it with npm

npm -g install bcryptjs

Dan Hoover

unread,
May 3, 2017, 7:57:28 AM5/3/17
to Node-RED
Thanks for taking the time to respond. Sorry for the dejected tone. Yesterday was a day in linux command line hell. I'd spin up a new server. Get 95% of the way to my goal, only to have one thing just fail.

Here's where I'm at... I can generate a hash with node-red-admin hash-pw. For instance, the hash for password comes back as

$2a$08$1y/ZciRPyKD44zkQ0Oelk.MldAGpUaEuCj.v.T2xBF/lz5MKWl1mi

If I try to run the alternative 

node -e "console.log(require('bcryptjs').hashSync(process.argv[1], 8));" your-password-here

I get module.js:328
    throw err;
    ^

Error: Cannot find module 'bcryptjs'
    at Function.Module._resolveFilename (module.js:326:15)
    at Function.Module._load (module.js:277:25)
    at Module.require (module.js:354:17)
    at require (internal/module.js:12:17)
    at [eval]:1:13
    at Object.exports.runInThisContext (vm.js:54:17)
    at Object.<anonymous> ([eval]-wrapper:6:22)
    at Module._compile (module.js:410:26)
    at node.js:578:27
    at nextTickCallbackWith0Args (node.js:419:9)

I've done npm -g install bcryptjs (and about a thousand other things) and it looks like bcrypt installs, but I don't think it does. 

Regardless, if I enter the hash from the first method into the settings.js file as described a few posts up, I'm not getting a password prompt.


Dan Hoover

unread,
May 3, 2017, 8:56:45 AM5/3/17
to Node-RED
Ok. Something has to be going on here. I did the exact same things to one of my own centos installs and I get the password prompt and it works perfectly.

So where I'm at right now 

CentOS 7 prompts for a password. Will not autostart to save my life and constantly flashes 
[warn] Communication send error: Error: not opened
in the putty console.

Ubuntu autostarts has ssl and won't prompt me for a password to save my life.


Julian Knight

unread,
May 3, 2017, 9:42:29 AM5/3/17
to Node-RED
Are you using the NR UI from the same device? What browser are you using? Currently, security is provided by Basic Authentication and so will be cached by the browser. Maybe try a different browser perhaps on a different device even.

Also worth noting that you can generate the hash on any platform and just copy/paste.

Dan Hoover

unread,
May 3, 2017, 10:08:26 AM5/3/17
to Node-RED
First of all. Thanks for sticking with me. I think I lost a few years off my life.

I built a 12th server and now it popped up.  The settings.js is a copy/paste of the other ubuntu one, but this one works for some reason. That's pretty much my experience with linux. haha.

I did try it from a different device for both server 11 and 12. 12 works. 11 Doesn't.  I don't get it. 

So I have one last issue with it (that' I've had with pretty much all of them).  I'm using nginx to do my redirects. I followed this guide...


The redirect issue is covered here...

open a new Nginx configuration for the site.

Copy and paste the following, changing the server name and certificate paths:

/etc/nginx/sites-enabled/node-red.example.com
server {
    listen 80;
    listen 443 ssl http2;
    server_name node-red.example.com;
    ssl_certificate /etc/letsencrypt/live/node-red.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/node-red.example.com/privkey.pem;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
    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;
    }
}

Save and close the file.


I changed the paths accordingly, but I cannot access node-red over https:

If I do my ip:1880  it works

http://mydomain.com redirects to https://mydomain.com as it should

mydomain.com:1880 doesn't work at all. Just hangs.


If I get through this, I might be at a place where I can actually start answering questions instead of asking them all the time. haha

Julian Knight

unread,
May 3, 2017, 3:57:41 PM5/3/17
to Node-RED
Phew! steep learning curve for sure.

In regard to your settings. If I've read it right, you have set up NGINX to FORWARD from port 443 to port 1880 so you should simply be using https://mydomain.com which should connect assuming port 443 is open in IPTABLES/ufw. 

The part in the tutorial you are following that says to do "sudo ufw allow 1880" is wrong, you shouldn't be allowing access to port 1880 because you want NGINX to only allow access to 443 (which is normally already defined in IPTABLES I think but worth checking). Ah, actually I can now see he undoes that setting towards the end of the tutorial.

If you want to allow access to 1880 from your internal network, you should be a bit more specific in the firewall rule - probably to only allow access from whatever internal IP addresses are in your routers DHCP pool (definitely not from the router itself).

One other thing you should be aware of that I don't think he explains and that is what these lines are for:

        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

They are the lines that allow a websocket connection to form. Details are here: https://www.nginx.com/blog/websocket-nginx/
Note that if you get websocket timeout issues, check the end of this: http://nginx.org/en/docs/http/websocket.html

Finally, if you haven't already done so, I recommend reading this: https://github.com/node-red/cookbook.nodered.org/wiki/How-to-safely-expose-Node-RED-to-the-Internet
which explains more about the ins and outs of Node-RED security and the current limitations & issues you might get.

Sean Inglis

unread,
May 4, 2017, 4:09:56 AM5/4/17
to Node-RED
Apologies for diving in, but I'm seeing similar behaviour simply trying to change the default adminAuth password on a standalone rPi install.

In my case, the first thing I did was to generate a hash for "password" using node-red-admin, and saw that the newly generated hash and existing commented out hash differed.

Then I tried the node / console approach and saw the same error trying to resolve the reference to bcrypt.js. I haven't attempted to install bcrypt yet as I'm wary of throwing installs in before I've correctly understood what's going on, and  your own testing seems to indicate it isn't a panacea.

I've settled for editing the default admin username into something cryptic, but that just discourages the laziest of drive-by mischief.

I'd be very interested to know if you get to a point where the two hashes are aligned.

Nick O'Leary

unread,
May 4, 2017, 4:30:48 AM5/4/17
to Node-RED Mailing List
In my case, the first thing I did was to generate a hash for "password" using node-red-admin, and saw that the newly generated hash and existing commented out hash differed.

The bcrypt hashing algorithm will generate different hashes for the same input - that is one of the reasons it is more secure than other more simple hashing algorithms; it prevents a simple reverse dictionary attack.

So given that, have you tried pasting in the password hash into adminAuth, restarting node-red and tried logging in with it?

Nick

--
http://nodered.org
 
Join us on Slack to continue the conversation: http://nodered.org/slack
---
You received this message because you are subscribed to the Google Groups "Node-RED" group.
To unsubscribe from this group and stop receiving emails from it, send an email to node-red+unsubscribe@googlegroups.com.

To post to this group, send email to node...@googlegroups.com.
Visit this group at https://groups.google.com/group/node-red.

Sean Inglis

unread,
May 4, 2017, 5:15:44 AM5/4/17
to Node-RED
I tried it with my password of choice, pasted the hash in, restarted, and couldn't access. But I'll repeat the process both with the default of password and chosen password to make sure it isn't just finger trouble.
To unsubscribe from this group and stop receiving emails from it, send an email to node-red+u...@googlegroups.com.

To post to this group, send email to node...@googlegroups.com.
Visit this group at https://groups.google.com/group/node-red.

Sean Inglis

unread,
May 4, 2017, 5:38:14 AM5/4/17
to Node-RED
Hi Nick,

A combination of things; the successful test I was trying via VNC / Chrome on the rPi itself. The unsuccessful tests I was attempting remotely but using Brave. Brave in it's secure mode is blocking the response necessary to persist the session, but if I relax security for the rPi URL and refresh, it all behaves as expected. 

Thanks for the pointers

Sean

On Thursday, 4 May 2017 09:30:48 UTC+1, Nick O'Leary wrote:
To unsubscribe from this group and stop receiving emails from it, send an email to node-red+u...@googlegroups.com.

To post to this group, send email to node...@googlegroups.com.
Visit this group at https://groups.google.com/group/node-red.

Dan Hoover

unread,
May 4, 2017, 9:27:17 AM5/4/17
to Node-RED
Julian. Thanks for the detailed response. I'm have tried to just go to https://mydomain.com and I'm just getting This site can't be reached in Chrome, so I'll have to keep tinkering. I think that github article is probably the place to go.   I'll do some digging. Thanks as always!

Dan Hoover

unread,
May 4, 2017, 9:57:57 AM5/4/17
to Node-RED
I'm still not seeing what's wrong with the reverse proxy... These are my nginx settings and I should be redirected to :1880 when I visit the fqdn, but I'm not. 

I wouldn't even care except I can't use https with the ip address.  Do you see anything wrong with this config?

server {
    listen 80;
    listen 443 ssl http2;
    server_name mydomain.com;
    ssl_certificate /etc/letsencrypt/live/mydomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/mydomain.com/privkey.pem;
    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
    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;

Julian Knight

unread,
May 5, 2017, 3:25:41 AM5/5/17
to Node-RED
OK, lets break things down a bit & make sure that NGINX is actually working as expected.

I'd start by taking out the proxy parts but leave everything else and put in a simple index.html at /var/www/html
On restart of NGINX, you should be able to access http://mydomain.com and be redirected to https://mydomain.com which should then show your static html file.

If that works, I would be tempted to create a really simple Node.JS server on an port, maybe 3000 which is common, there are lots of tutorials on how to do that. Then add your proxy settings back in with the 3000 port.

After that, we should have a better idea as to where the problem lies.

Dan Hoover

unread,
May 13, 2017, 3:16:39 PM5/13/17
to Node-RED
I totally missed this response. Sorry about that. I am going to give it a shot. This is a pretty important thing to have working. I appreciate your help!
Reply all
Reply to author
Forward
0 new messages