Node-red SSL over Cloudflare

1,120 views
Skip to first unread message

Paul Reed

unread,
Jul 16, 2016, 4:25:14 PM7/16/16
to Node-RED
Has anyone managed to configure node-red correctly to work with Cloudflare?

Cloudflare is currently configured as Flexible SSL, meaning that there is an encrypted connection between my site visitors and CloudFlare, but not from CloudFlare to my server. So I don't have any SSL certificates.
A Cloudflare page rule forces all visitors to use https, but if I disable the page rule, I can access node-red via http://mysite.com:2052 OK. 
However if I re-enable the page rule to force SSL, and try to access via https://mysite.com:2052 the request is rejected.

In anticipation of using node-red-dashboard, it would be good to finally get this working, now that Cloudflare have now enabled websockets for all users.

Paul

Paul Reed

unread,
Jul 16, 2016, 4:38:43 PM7/16/16
to Node-RED
I should add that Cloudflare recognise port 2052 for http traffic, but if I try port 2053 which is a Cloudflare https port, I get SSL handshake failed;


Julian Knight

unread,
Jul 17, 2016, 1:41:24 PM7/17/16
to Node-RED
I use Cloudflare SSL with some other sites but not with NR. You of course need to ensure that NR cannot accept any connections other than from Cloudflare itself otherwise there isn't much point.

It looks at first site from your image that cloudflare is expecting the connection from itself to your server to be SSL protected.

You might want to run up a simple node.js/ExpressJS server listening on port 80 and see if you can get that working. I can't see why it wouldn't.

Otherwise, you could always create a self-signed local certificate for NR and use that to provide an encrypted link between Cloudflare and yourself. This is a better configuration anyway really though I'd still make sure that you use a firewalled local connection that only allows connections from Cloudflare servers and nowhere else.

Paul Reed

unread,
Jul 19, 2016, 5:15:07 AM7/19/16
to Node-RED
Thanks Julian
I went for your second option and changed from 'Flexible SSL' system to a 'Full Strict SSL' instead, which works fine now with node-red, and which grants me https access to my node-red dashboard ui.
I didn't however use a self-signed certificate, instead I used a Cloudflare Origin Certificate, which is reputedly more secure than self-signed, free & easier to obtain and manage, and has a 15 year life, so can forget about renewals.
I just need to read some more on the best way to ensure a "firewalled local connection that only allows connections from Cloudflare servers and nowhere else".

Paul

Julian Knight

unread,
Jul 20, 2016, 8:27:24 AM7/20/16
to Node-RED
Ah, glad I could give some pointers and a good call on the cert, I must check that out, always looking for good cert options.

The firewall thing is going to depend on how you are configured locally and what options you have. You could configure in your router/firewall for example or you could create a configuration in IPTABLES on a Pi or other Linux server.

In the former case, it may or may not be possible depending on how configurable your router is. 

It is usually easiest to do this kind of thing with IPTABLES and Cloudflare helpfully publish some useful information:

Basically, you block all incoming traffic and whitelist your local network and the Cloudflare IP address ranges.

Julian Knight

unread,
Jul 20, 2016, 8:28:44 AM7/20/16
to Node-RED
Incidentally, I use a Uquiqity Networks EdgeRouter Lite at home that has very comprehensive firewall capabilities so I could do the same in the firewall on the router if I wanted to.

Paul Reed

unread,
Jul 21, 2016, 6:41:12 AM7/21/16
to Node-RED
I've tried using the Cloudflare's 'Authenticated Origin Pulls' - where CloudFlare origin-pull servers present a TLS client certificate as part of connections to the origin. Web servers and other infrastructure are configured to require client certificate authentication for connections.
Very easy and quick to install, and works really well, stopping unauthenticated traffic to origin, but haven't quite worked out how complete the handshake via node-red.

It is achieved for normal traffic by adding a third pem certificate and the following to the https apache config;

SSLVerifyClient require
SSLVerifyDepth 10
SSLCACertificateFile /var/www/cloudflare-origin-pull-ca.pem

I can however get node-red running by creating a site profile for port 2053, adding the code above, and enabling it with a2ensite, which although works, is a hack, and the code (I think) needs to be called from node-red's settings.js in a similar way to how node-red authenticates https.

Is this a possibility?

Paul

Julian Knight

unread,
Jul 21, 2016, 12:02:42 PM7/21/16
to Node-RED
Not tried this as yet but it is an interesting idea though possibly rather overkill if you are limiting input to the cloudflare IP's.

In fact, Node-Red creates an ExpressJS server to run behind so if you can work out the settings for that, you may be able to work out the required NR settings. If not, you can always run NR in "embedded" mode, check out my GitHub repo (user TotallyInformation) where you will find an example setup. That way, you control the Express server rather than letting NR do it for you.

The alternative of course, is to run NR behind a reverse proxy using Apache or better still, NGINX and using the proxies security features instead. This puts less load on NR itself and is less likely to result in incorrect configurations.

I really need to do some experimenting on those modes of operation including running from a simple Azure Web App (which uses IISnode to link from the IIS server). But there always seems as though there are too many other interesting things to do higher up in the queue!

Paul Reed

unread,
Jul 23, 2016, 6:47:18 PM7/23/16
to Node-RED
It wasn't in addition to limiting access to CF's IP's, I was hoping that it was instead, as the IP's may change, and iptables are not the easiest to set up.
However.... after looking at a number of alternatives, including proxy-pass, I'm conceding to using iptables...

I've added CF's IP's as ACCEPT, together with SSH & Loopback, with a base INPUT policy of deny, which works OK for https & SSH but not node-red.
Is it necessary to include the node-red port (1880 or whatever) as an accept statement?

-A INPUT -p tcp --dport 1880 -j ACCEPT

Paul

Julian Knight

unread,
Aug 8, 2016, 5:25:14 PM8/8/16
to Node-RED
Hi, sorry, I've been on holiday.

Yes, if cloudflare is handling NR requests on the standard port, you would need to open that port also to the CF servers. You can, of course use any port for NR so if your local server isn't doing anything else, you could move NR onto 80 or 443 if you really wanted to but then you would need to make sure that the user running the NR process (normally Pi on a Pi) has rights to open ports below 1024. There are many options but keeping it simple is probably best. 

Paul Reed

unread,
Aug 10, 2016, 6:05:41 PM8/10/16
to Node-RED
Thanks Julian, all sorted now by using ufw to setup the iptables, I've written it up in my blog if it helps anyone else.

Paul

Julian Knight

unread,
Aug 11, 2016, 3:24:23 AM8/11/16
to Node-RED
And duly tweeted because more people need to do that.
Reply all
Reply to author
Forward
0 new messages