Need a means to protect my source code

Any solution will have ways around it. It all depends on how sophisticated you want to make it.

A node-red flow that auto-deletes itself would help in the case the SD card is plugged into another Pi and booted by a casual user. Just deleting the file would probably leave the data on the SD card and still recoverable - you'd need to securely erase the contents by ensuring the blocks on the file system are wiped.

For anyone actually intent on access the flow file, they will easily get around that - they can just mount the SD card and get the flow file off it without Node-RED ever running.

As has been said in this thread before, this is a hard problem.

1 Like

if you just plug it into a different Pi - it would most likely have a different hostname so it would expect to load flows_{hostname}.json file... so would appear blank by default...
Of course it isn't really - and just copying the file off without using Node-RED would be easy.

Yes if its a DHCP assigned hostname. If its a fixed hostname then that will be on the SD card they have just booted from... but I think we're straying from the point :slight_smile:

I think that part of the point is that Getting Node-RED to delete its own flows is not a terribly secure solution. Certainly it can be done for specific cases and that may be enough.

But after some quick thought, I would create a boot script that checked the IP address and if it was not in the right range, prevented Node-RED from starting and securely deleted the whole userDir folder. This could be done with a reasonably simple amendment to the systemd service file that starts Node-RED.

Anybody actually steeling a Pi with intent to access data on it is likely knowledgable enough to make the SD-Card read-only before putting it into a different device to read. The above process might slip through a casual examination.

There are lots of other things that you could attempt to do to make things difficult for attackers like use the boot process to create an env variable containing critical information such that your flows are useless without it. Add an encrypted filing system that unlocks on boot only if a memory stick is present on a USB stick - or indeed if a specific network share is available.

But as hazymat says, if you really need things secure, you need a professional. You will also need to pay for testing. At the end of the day, a JavaScript based application is never going to be completely secure if someone has access to the device, especially when that device makes it easy to remove the data card - maybe consider gluing the card in place and using a USB stick to do updates.

This solution is not feasible if the unauthorised user just copy/import the flows.json on another machine running Node-Red because in this case the script will remainn in the orignal MicroSD. The boot script so will only secure the case the user uses the stolen MicroSD and boot the Rasp from this.

I think the safer way to protect the code is glue the MicroSD on the Raspberry in a way that it will be damaged when someone try to extract it.

The node-red flows update can then be made also via SSH Keys authentication anc connecting remotely to the Rasp.

At best you'll make it slightly inconvenient to access all of the data on the Pi. If that is good enough for you, then go for it.

1 Like

It wasn't a stand-alone suggestion. Rather an extension to further enhance the security.

I already suggested gluing in the card but I think that the OP has suggested that external network access may be limited so that may also not be possible.

Though doing that - and then updating via a separate USB that isn't left installed is actually one of the first deployments I did (updated the flows and extracted the logs at the same time... - good old udev script and rsync both ways. :slight_smile:

2 Likes

What is "niche" about wanting to encrypt flows on IoT devices that are out in the wild? Seems like a pretty general requirement to me. Feel free to reply if you have solutions to offer.

Hi @dennishvo

if this is a commercial product with internet access, then Nebula by yellaUmbrella (or Nebula via Iotobox ) does precisely that, with other advantages too.

Nebula enables the download of a single exe (a 'Device'), which in itself contains node-red (no dependencies, windows/mac/linux/rpi, no 'installation'). Every Device is unique, all the source is encrypted, and your actual flows never exist on disk.
When the Nebula Device is run, it gets it's flows (and their configuration) from the Nebula web server.
All communication is HTTPS/WSS, and everything served is encrypted as well.
Via the Nebula server, you can add, configure and control the flows present on the Device - making it easy to change what a process (flow) does in seconds, and the majority of the operational code is downloaded as required.
It also supports (most) native node modules and secondary executables as dependencies - which are also delivered encrypted, but then unwrapped to disk for use :).

The current version (used in production the last 18 months) is based on node 6.9.11, NR 0.17; but I'm in the process of qualifying node 12.10.0, NR 1.0.1, and it's looking good so far (thankyou Nick & Dave et al for a brilliant project!).
I have built the 6.9.11 version for RPi in the past - you need at least 1Gbyte of ram - and the requirement for RPi is current with the involvement of Iotobox.

Note that this IS a commercial product. We (yellaUmbrella) use it in support of our Broadcast Media based activity - I developed it to address our need for pay-per-use delivery of processes to the user's machine, wherever that may be.
So with that, we have a highly competent mechanism of charging the end users, but also a developed concept of revenue share, so you can charge for the use of the processes based on a range of parameters.
Each process (flow) may have up to 10 counters, and each counter can have an associated price.
A 'Price' can be per count (or a calculation based off a count, e.g. ā‚¬0.01 per 30kb or part of, where the counter is in bytes), or can be interval based (e.g. '0.10ā‚¬ for the first use in an hour/day/week/month/quarter').
And every price has an up to three way split of revenue - e.g. if you created a process, the mechanisms are in place for us to take 10%, you 70% and Amazon 20%, for example.
A 'price' can also be dependent on a 'paygo'/'monthly' switch on the webserver (per project - collection of flows on a device) - we far prefer the good honest pay-as-you-use, don't-pay-if-you-don't model.

We (yellaUmbrella) do not have the bandwidth to take Nebula into other business areas, so we keep an eye out for partners in other business areas who could use the underlying technology and framework to their benefit, hence the involvement of Iotobox. Joe 'noticed' Nebula some time back, and it was a very good fit for a (Rpi based) product he had which was based on Node-Red flows, and has now taken on the mantle of application of Nebula to IOT.

So, if it sounds interesting, you can contact us through the contact page on yellaumbrella.tv, or contact Joe (US based) through iotobox.com, or PM me directly to talk further?

Personally, I fell in love with NR when I first used it ~2 1/2 years ago. Now I use (abuse) it almost exclusively for everything we do, have basically built a business on it, and contribute where I can... My background was c/c++, but now I can literally do everything I need to in Node-Red.

sorry if this is overly commercial :wink:

best regards,

Simon

3 Likes

We do believe that we have a complete solution for the issues raised here. Without any hardware modifications or worrying about deleting the flows. Also, with our implementation because there is no writing of the code to the SD card we also minimize the potential of the SD card going bad because of too much activity. Additionally, the code remains encrypted in memory so even if someone got root access to the device they would see minimal source code.

I spoke (texted) @knolleary a while back asking permission to post our request for beta testers. With his "ok" I have attached a document that describes Nebula and talks about its advantages. As Nebula is new to IOT we are looking for people to test it for us. As @btsimonh mentions, we have used it in a vertical market for quite some time. So its not like it is brand new code.

Please see the attached beta request and feel free to contact me.

Joe

Beta Testers Posting -MD 2.txt (4.9 KB)

1 Like

I just want to comment on one item:

Network loading would be the best option for my use case, I think. Sounds like a non-trivial effort.

Creating a network loading storage plugin (for the flow files) is actually pretty easy.

The issue is securing the service that provides the flow files when you can't rely on the local machine. If you could rely on the serial number (or serial number and IP) to authenticate the device it would be relatively easy. I did some PoC's with a custom network service and it was easy but I was able to trust the device and store keys on it locally.

If someone can access the SD card any sort of trust goes out the window. It would be possible to take the card edit your config and install all kinds of back doors then slot the SD card back in place. At a minimum you would need to pass the network flow service the device serial number (or whatever you use to authenticate the device) and a hash of the install directories to ensure against tampering.

1 Like

I've cobbled together a solution that uses a secure web service to deliver a flow file. And you're right, it wasn't that difficult to build. My devices are now able to update themselves, and that is a huge step forward.

Thanks, all, for your input.

3 Likes

Have you thought about changing the hardware to something else that doesn't require an SD card? An Orange Pi PC Plus for example has 8 GB of EMMC that can't be removed.

The Orange Pi line is now fully supported by Armbian. Even the GPIO are accessible.

2 Likes

I got hit by the same topic... I have to build few prototypes for a bigger project.
I've worked several days on it and I would clearly want that the code is "secure" and it cannot be cloned to another card and than use it for the next n systems.
What I will do - get the MAC address of the wlan0 or eth0 - that is unique.
If it will not match to a variable from the code, it will start the script to delete the flow files.
Again we arrive to the point that is not the most secure but it will discourage people that want to just copy the system.

Ummm unless they start Node-RED from the CLI using the ā€”safe option which starts NR with out running it......

1 Like

I don't recommend anyone try that :wink:

2 Likes

blast auto correct! Fixed it.

1 Like

@dennishvo
Would you not be kind and share your solution you "cobbled together"? I think it sounds interesting for many users, I would like to try something like that myself

@krambriw Unfortunately, I can't share the code itself, but I can describe the solution, which is straightforward to implement. This is all somewhat off-topic because it's about installing updated flows, rather than protecting source code. Nevertheless, you may find it useful.

In the cloud, implement two web services: "query for update" and "deliver update". Periodically, the client sends "query for update" (using GET) with a set of parameters that you, the designer, must choose. You may want to verify that the client is known, what version of software they are currently running, what application, what platform, etc.

If no update is available, the server returns HTTP response code 204 (No content). Otherwise, HTTP 200 is returned with a payload consisting of a "ticket", which is an encrypted string that contains data that describes the update. The client doesn't need to understand the ticket.

With ticket in hand, the client calls "deliver update" (using POST). In the cloud, the ticket is decrypted and the fields become a pointer to the version of code to be returned. I keep my flows in a database but you could keep them as files on disk. The content returned is the json for the set of flows that correspond to the ticket. I also include a checksum that I compute against the code.

Back on the client, the code's checksum is computed and compared with the sent checksum. Then the code is stored on disk. The client flow invokes a script to install the file (I use python). It's easier to use a script to archive the current flow file and move the new file into place than to do this all in the flow, in my opinion. Lastly, you either immediately reboot or communicate a message for the user to reboot at the next opportunity.

Of course, you should use SSL/TLS for these services.