CESNET / netopeer2

NETCONF toolset
BSD 3-Clause "New" or "Revised" License
299 stars 188 forks source link

Encrypt startup data #1383

Closed lilililizheng closed 1 year ago

lilililizheng commented 1 year ago

Hi,I would like to know if there is any way to encrypt startup data。

michalvasko commented 1 year ago

No, this is generally not possible. However, the (startup) data are stored using a plugin so you are always free to write your own plugin that would encrypt the data.

lilililizheng commented 1 year ago

Do you mean to encrypt data before copying from the running database to the startup database in the plug-in? If this is the case, there will be a process to copy the startup library data to the running library when the device is started, which should also require decryption.

michalvasko commented 1 year ago

You mentioned only startup data and if you want to encrypt only those, you would not have to worry about running at all because you can configure a different plugin for each datastore. But I suppose it does not make much sense to encrypt only startup because those data always go into the running after a reboot so that would defeat the purpose.

Still, copying has a separate callback, which would not even require decryption (you simply make a copy of the file. Decryption would be required only for load and encryption for store.

Generally, the idea was to just use the file system rights to prevent any unauthorized access but adding encryption could actually not be that difficult. In other words, you would only have to implement the encryption itself thanks to the plugin mechanism and continue using sysrepo without any code changes.

lilililizheng commented 1 year ago

I now have a concern, "sysrepo/repository/data". Can the.start file in this directory be tampered with manually by the user? For example, you can use the vi to change the contents, so that incorrect data will be sent after the restart.

michalvasko commented 1 year ago

Yes, that is generally possible which is why, if it is a possibility, you should take care to set the access rights in a way that malicious users are not able to change the files. Use sysrepoctl for displaying and changing the permissions of each module.

lilililizheng commented 1 year ago

Ok, I feel that the permission setting method is better, and encrypting the data doesn't seem to prevent this problem

jktjkt commented 1 year ago

Keep in mind that sysrepo is all about managing collaborative access to a shared set of YANG datastores. If there's a malicious sysrepo application which wants to misbehave, it has all the possibilities of corrupting the shared in-memory state, and that's very likely to cause privilege escalation and/or denial of service via the SHM data which other sysrepo applications are processing concurrently.

I would suggest to identify your threat model as a first step, though. For example, if there's an on-disk file whose integrity you worry about, do you also worry about the integrity of, say, ld-linux-x86-64.so.2? If so, how do you detect its corruption? I'm not saying that dm-verity doesn't exist, but it's a rather hard problem to tackle.

A TL;DR version is that allowing your untrusted users to access sysrepo directly is probably not a great idea, and that only allowing access via the NETCONF protocol is the way to go. That way, Netopeer2 has a chance to validate all the RPCs, and there's no potential of causing memory corruption directly.

lilililizheng commented 1 year ago

Sorry, I don't understand how the plug-in encrypts data in the startup database. Leaving aside the issue of protecting against malicious users, encrypting permanently stored data is a routine operation. All I could think of was to modify the sysrepo copy code to encrypt the data whenever I copied it from the running library to the startup library, and then decrypt the startup library data first when the device was restarted. Also, does it matter if the startup library data is encrypted while the application is running? Or is it only useful at boot time.

michalvasko commented 1 year ago

Okay, so let me explain. I assume we are talking about encryption for the purpose of sensitive data not to be stored in a clear-text form in the filesystem. That means whenever data should be stored, the plugin would not just write the data into a standard JSON file (what the default plugin does) but rather create some encrypted data file. Then, load would first decrypt the file and then parse it providing sysrepo with the decrypted data. Not sure why you are so preoccupied with the copy operation, which is generally transparent for datastore plugins. There is a special copy callback that allows to perform more effective copy operation (which in this case could be performed without encryption/decryption by simply making a copy of the encrypted file) but you can always implement it by calling load and then store callback.

lilililizheng commented 1 year ago

Sorry, I still don't quite understand what you mean. Could you point out some API interfaces that I might use? This will help me understand better. I'm still learning about sysrepo

michalvasko commented 1 year ago

Introduction to the datastore plugins is in the docs. All the required callbacks are specified here and you can also look at how exactly these are implemented in the default JSON plugin, you should be able to reuse most (if not all) of the code and just add encryption/decryption.

jktjkt commented 1 year ago

encrypting permanently stored data is a routine operation

So is disk/filesystem encryption. Will that solve your needs? How do you plan to provide the decryption key(s)? Again, the most suitable solution depends on types of attacks/threats that you are aiming to solve.