Adding SSH key after flashing

Hi all,

When flashing balenaOS to a device, it’s possible to add an SSH key to be able to SSH or tunnel into production devices, which is awesome. But I have some doubts about the security of this and maybe you guys can help me out.

We’re looking at the ability to add an SSH key after flashing the device. When a device is provisioned with cloudBalena/openBalena and the software is downloaded, the first thing it does is register itself with our server. So the device gets registered to our server, gets a serialnumber and sets the name of that device to that serialnumber on cloudBalena/openBalena. It also recieves a public and private key for communicating to our server. So far so good.

Now we want to generate an SSH key for that device and add that to the OS. Using 1 SSH key for all of our devices isn’t something that I see as very secure. Once that SSH key is compromised, someone can get into all of our devices using SSH. That’s the reason we want to generate an unique SSH key per device. For us, it’s more work to SSH into a device, because we have to locate the SSH key and use that for communication, but I think that’s better than just using 1 SSH key. But I’m here to learn, so if anyone can convince me that it’s not more secure, I’m all ears!

And the reason why we’re not generating the SSH key beforehand and also provisioning our device beforehand (like changing the config.json for the flash file)? That’s because we want to flash our devices with just 1 image. Creating an image per device is time consuming and not very efficient for our production process. And because we’d like to use the EtcherPro when it’s released!

Thanks in advance!

Sure a key per device does make sense, but it is much more important how these keys are stored and used.
For example if you use one key for your whole fleet and this key is stored in a HSM, it would be much more secure then when you store unencrypted per device keys in a database.
It should be ensured that nobody has access to the plain keys itself, but systems can only use the keys.
Just using multiple keys does not mean that this is more secure than using single key for the whole fleet. It adds a nice property that if one key is leaked only this device is compromised, but more important is how the keys are stored, used and how the keys can be rotated.

Hi @afitzek,

Thanks for your response!
The way the keys are stored is very important, I agree. The way we’d like to store them is on a (local) server that can’t be accessed easily by others. On the device itself, only the public key is stored like in every SSH transaction of course. But if we can add an extra layer of security, by using a SSH key per device, it’s an added bonus. If you have any tips regarding storing all SSH keys, it’s certainly worth knowing about!

But before we get our hopes up and investigate further in storing SSH keys, is it even possible in Balena to add an SSH keys after flashing the device?

It is indeed! You can put the public keys in an array in your config.json: {"os": {"sshKeys": ["key1", "key2"]}}.

Hi @wrboyce,

So even after flashing the device, this is the way to go?
So I have to add the public key to the config.json in /mnt/boot/config.json, correct?

Yep, thats right, I suspect you will need to reboot after modifying the config.json too.

Thanks! Rebooting is no problem after modifying the config.json file.
I’m going to try that asap!