Hi,
I'm looking for ideas for a lightweight (yet robust) autoupdate protocol for a family of network clients I'm designing.
Some criteria:
- Unattended, persistent operation. A device shouldn't require hand-holding from a user to get itself into a working configuration. It is acceptable (though not
*desireable*) to withold its normal functionality from the user while updating *or* recovering from a botched upgrade. But, it must be able to eventually "right itself".- I don't want to have to *tell* the devices that they need to be updated. The user shouldn't even be aware that this is happening. I.e., the devices should be able to examine/query the "current images" to see if they coincide with *their* images.
- I should be able to tailor an image to a *particular* device (i.e., an *instance* of a device; not just a "model number").
- Images need to be signed so they can't be forged.
- The protocol can't be spoofed by "unfriendlies".
- The protocol should be as light as possible -- but no lighter! ;-)
- Minimize unnecessary network traffic as well as load on the server (the goal is for the user *not* to notice this activity -- though I am not trying to "keep it secret")
(seems like I have forgotten something -- but I can't recall what! :< Too early in the day...)
So, all I should have to do is put "current images" on the user's server and wait for each device to discover the image and update itself accordingly.
For example, the devices could check the server at IPL (and periodically at run time -- though updates at run time can be more of a challenge as they will probably interfere with normal operation :< ) and "fingerprint" the current image located there to see if it looks like it differs from its own image.
One way of doing this is to store the image for each device instance in a R/O file bearing the MAC of the device in question. But, this would require the device to perform a "trial download" of the image for the sole purpose of computing the fingerprint (why not just do a bytewise compare if you are going to this extreme?!).
This will hammer the network pretty hard. Granted, the individual segments for each device will see modest traffic -- but the server's segment will quickly max out if multiple devices do this simultaneously (e.g., powering up together). This would necessitate a second layer of the protocol to randomize/defer such competition. :<
Another approach is to *store* the fingerprint on the server in a uniquely accessible manner (e.g., use a file name like MAC.fingerprint). But, that represents a duplication of data (pet peeve of mine) which makes it at risk for getting out of sync.
For example, updating the image and forgetting to update the fingerprint; or, a run-time race -- the device examines the fingerprint, sees that it differs, starts to download image but the image hasn't been updated yet. Or, the image is updated but the fingerprint is stale when the device examines it. As a result, the image is NOT seen as "new".
[you could get around this if you implemented network file locking -- but that is more complexity and leaves open the possibility of stale locks, etc.]This could be worked around by forcing the server to recompute the fingerprint each time an image is added. But, that still leaves a race window *and* requires the server to be aware of the introduction of the new image file(s).
The simplest compromise would seem to be having the device track the timestamp of the image file and check *that*. If changed, then *assume* the image actually has changed (of course, touch(1)-ing the image file would then force the device to consider the image file as changed -- this could be an advantage?). The device could then either fingerprint the image itself *or* naively assume it to be a new image and begin the (secure) update procedure.
Security then is another facet to be addressed. E.g., given that the devices *don't* have enough resources to store an entire image before flashing, the protocol would have to be interruptible. E.g., encrypted packets so they can't be spoofed. But, accepting the possibility that the entire image might not become available "when needed" for the reflash. I.e., fall back to a secure boot loader that can do the update without the rest of the application being available.
Note that this loader should *not* restart the upload but, instead, *continue* where it apparently left off, previously -- even in light of any intervening power cycles. This saves time, reduces flash wear and is just "smarter", in general. :>
But, it seems like this *still* requires server side locking so the file isn't changed *while* it is being doled out. E.g., something like TFTP would be inappropriate as it doesn't reliably lock the file from one packet to the next.
Shirley, this sort of thing has been done before (?). Pointers?
Thanks!
--don