Remote Access to NR Dashboard

I'm looking to access my NR Dashboard on a R-Pi from anywhere, when I'm away form home. I'm considering using either Ngrok or Serveo. Any advice from users as to which might be best.
I also note that whenever I want to access Serveo website that I get a warning that the site "is not private and may be impersonating
Comments appreciated.

Well I certainly wouldn't use Serveo uses an invalid security certificate. The certificate is only valid for the following names: *, The certificate expired on 13 April 2017, 00:59. The current time is 8 November 2019, 18:15. Error code: SSL_ERROR_BAD_CERT_DOMAIN

1 Like

Hi Colin, thanks. I was a bit weary and tat's why I asked. I thought that I'd try Localtunnel; it's open source and seems to be well regarded. Any comments?

You might be interested in my recent experiments with ngrok.

The default configuration of ngrok isn't that secure so I did some playing and came up with a flow that turns the ngrok link on/off via a secure Telegram bot.

You need to use a slightly more complex command to get ngrok reasonably secure:

http https://localhost:1880 -bind-tls=true -auth='jk:jk' -inspect=false -region=eu

Obviously you should change the id/password pair and change the region if you don't want to use the EU. Also, if you don't have local Node-RED set up with https then you need to change the URL. This sets up an HTTPS only connection regardless of whether you are using TLS locally. It also protects access to the link with an id/password.

Here is a pic of the flow

And the flow itself:

[{"id":"3407a95c.e462c6","type":"inject","z":"396e6d9.614e192","name":"start","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":190,"y":2140,"wires":[["c24eb059.ab369"]]},{"id":"c24eb059.ab369","type":"exec","z":"396e6d9.614e192","command":"ngrok","addpay":false,"append":"http https://localhost:1880 -bind-tls=true -auth='jk:jk' -inspect=false -region=eu","useSpawn":"false","timer":"","oldrc":false,"name":"","x":410,"y":2140,"wires":[[],[],["364295d4.c3b10a"]]},{"id":"364295d4.c3b10a","type":"debug","z":"396e6d9.614e192","name":"NGROK Error Output","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":620,"y":2140,"wires":[]},{"id":"c14ae7ba.7900a8","type":"status","z":"396e6d9.614e192","name":"","scope":["c24eb059.ab369"],"x":200,"y":2180,"wires":[["2bba47c7.fe0628"]]},{"id":"fe34ab54.9dce58","type":"debug","z":"396e6d9.614e192","name":"NGROK Status Output","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":620,"y":2180,"wires":[]},{"id":"e8eea2dc.6ac12","type":"exec","z":"396e6d9.614e192","command":"kill","addpay":true,"append":"","useSpawn":"false","timer":"","oldrc":false,"name":"","x":410,"y":2220,"wires":[["459d2525.b9a25c"],["459d2525.b9a25c"],["459d2525.b9a25c"]]},{"id":"48a318df.9d6098","type":"inject","z":"396e6d9.614e192","name":"","topic":"","payload":"","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":155,"y":2220,"wires":[["d4aebdad.d16aa"]],"l":false},{"id":"2bba47c7.fe0628","type":"change","z":"396e6d9.614e192","name":"","rules":[{"t":"set","p":"ngrokPid","pt":"flow","to":"$contains(status.text,\"pid:\") ? $number($replace(status.text,\"pid:\",\"\"))+1 : $null","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":390,"y":2180,"wires":[["fe34ab54.9dce58"]]},{"id":"459d2525.b9a25c","type":"debug","z":"396e6d9.614e192","name":"NGROK Kill Output","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":610,"y":2220,"wires":[]},{"id":"4b24c6b2.807768","type":"comment","z":"396e6d9.614e192","name":"Start/Kill NGROK","info":"## How this works\n\nYou can start NGROK manually or send anything you like to the `Start-NGROK` link. Similarly, you can end it with the end inject node or sending anything to the `End-NGROK` link.\n\nFor example, I have a Telegram bot set up to start/stop NGROK remotely so that I don't have to try and keep it running all the time.\n\nThe flow saves the PID of the running instance of NGROK. This pid is +1 above the pid that the exec node creates (which is the parent shell). The flow saves the correct pid in a flow variable & uses that to facilitate a kill command.\n\n## Why not the node-red-contrib-ngrok node?\n\nI don't think that creates a secure connection.\n\nThe default ngrok command starts *both* secure and insecure URL's to your system. \n\nIn addition, the node does not let you input a login as this method does. \n\nWithout a login, anyone who finds your URL will have full access to Node-RED.\n\n## Notes\n\n* Starting NGROK from the exec node creates **2** tasks.\n* To Kill NGROK this way, you have to kill the **second** task not the one that the exec node reports back.\n* You cannot use `spawn` mode with NGROK, it doesn't work correctly. While it starts a session, it doesn't let you interact with it correctly (e.g. you cannot successfully log in).\n* The default NGROK command **IS NOT SECURE** - use the format given here.\n* If you allow the NGROK client to start its inspect web interface, you can only interact with it locally on the device - http(s)://localhost:4040\n* Don't forget that the free version of NGROK will terminate the link after 6 hours. Using this flow, you will have to end and then start again. You could easily automate this with a node like cron-plus or bigtimer.\n\nCommand used:\n\n```bash\nngrok http https://localhost:1880 -bind-tls=true -auth=someid:somepassword -inspect=false -region=eu\n```\n\n* *`-bind-tls=true`* - turns OFF the http link and only serves the https one.\n* *`https://localhost:1880`* - change to http if you haven't configured Node-RED for TLS. That would still be reasonably secure as long as you always use the NGROK URL since you are forcing https externally.\n* *`region=eu`* - you can an appropriate NGROK region with this, EU in this case.\n* *`-inspect=false`* - turns off the inspector web interface. You don't need this anyway if accessing remotely as you can only reach it locally.","x":400,"y":2100,"wires":[]},{"id":"d4aebdad.d16aa","type":"change","z":"396e6d9.614e192","name":"flow.ngrokPid","rules":[{"t":"set","p":"payload","pt":"msg","to":"ngrokPid","tot":"flow"}],"action":"","property":"","from":"","to":"","reg":false,"x":270,"y":2220,"wires":[["e8eea2dc.6ac12"]]},{"id":"d347b34c.b62f8","type":"link in","z":"396e6d9.614e192","name":"Start-NGROK","links":["39de9645.73912a"],"x":215,"y":2100,"wires":[["c24eb059.ab369"]]},{"id":"15e9ee7c.9a6722","type":"link in","z":"396e6d9.614e192","name":"End-NGROK","links":["1d19c614.25eb6a"],"x":155,"y":2260,"wires":[["d4aebdad.d16aa"]]}]

I can't really share the Telegram part so easily since it uses my own bot ids:

The function node contains:

const command = msg.payload.content

msg.payload.content = `NGROK is*${command}ing*`
msg.payload.options = { "parse_mode": "Markdown" }
msg.topic = 'TELEGRAM/<botname>/NGROK'

let msg2 = null
if ( command === " start" ) {
    msg2 = {
        topic: msg.topic,
        payload: 'start'

let msg3 = null
if ( command === " end" ) {
    msg3 = {
        topic: msg.topic,
        payload: 'end'

return [msg, msg2, msg3];

// EOF

Output 1 is just feedback, 2 and 3 are the important parts.

By the way, I got round to creating a flow from this now: