Re: Auto-update protocol



D Yuniskis <not.going.to.be@xxxxxxxx>
wibbled on Monday 08 March 2010 19:34

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! ;-)


I would use TFTP for the actual image transfer - simple, standard and the
client initiates the connection so as long as it is happy it is talking to
the right IP it doesn't have to worry too much about connection based
attacks - code signing should sort the rest of the security out.



- 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")

Unless you go multicast/broadcast (with the extra complexity that will force
onto the clients) I don't think you could do much better. Would you really
need to reduce net traffic below one image transmission per device?

(seems like I have forgotten something -- but I
can't recall what! :< Too early in the day...)

Now the interesting bit is advertising the availability of images to the
clients. TFTP of course cannot do directory listings, though the client
could periodically retrieve a manifest file.

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?!).

Do the devices have a notion of "type ID" anywhere in their firmware? In
which case, you could serve the files up thusly named:

TypeID-Version
or
MacAddress

eg

23FE-010A
23FE-010B
FFEECCBB1177
2401-0200

etc

Any device of type 23FE will sort the list and discover that version 010B is
the highest version and will update to that.

Device with MAC address FFEECCBB1177 will find a specific image and will see
if it i the one it is currently running and if necessary will update to
that.

Images should contain a header also containing TypeID and Version so the
device can make sanity checks that it has runnable code.

Simple, controllable.

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. :<

Random hold off for server polling. Or don't poll, but send a magic packet
(contents unimportant) to a specific device to start the poll operation,
then the server can manage timings.

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.

I'd just go for Type and Version numbers, it's all you need if I understand
your problem correctly. Timestamps are not really necessary.

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.

Put a management system in place that people do not manage the TFTP
directory directly, but give new firmware to a script that gracefully puts
it in place, atomically updating the manifest file (hint rename() under
linux is atomic)

I think the hardest part is managing encryption and/or code signing in a way
that doesn't overload the client if they are lightweight. The basic approach
however of offering a manifest of files and allowing the client to make a
simple informed choice is the easy bit IMO.

--
Tim Watts

Managers, politicians and environmentalists: Nature's carbon buffer.

.



Relevant Pages

  • Re: Auto-update protocol
    ... The protocol can't be spoofed by "unfriendlies". ... Minimize unnecessary network traffic as well as ... load on the server (the goal is for the user *not* ... the fingerprint (why not just do a bytewise compare ...
    (comp.arch.embedded)
  • Re: network booting
    ... So the client would need to tell on which offset into on of the ... The client asks the server to open a specific file (by ... component of DOS 3.3, as well as RWTS. ... code on the C64 can send commands (using a serial protocol called IEC) ...
    (comp.sys.apple2)
  • Re: client -server interaction over XML supporting multiple protocols
    ... > NETBEUI to access the server to access the functionalities exposed. ... > server doesnot know in advance which client is using what protocol. ... size of the XML and Xfunctionality will determine the demands ...
    (comp.lang.cpp)
  • Re: Auto-update protocol
    ... I'm not worried about the client side as I can control that. ... I just don't want to have to dick with anything server side if ... Whether you write a server from scratch or wrap the protocol in HTTP and bundle an Apache blob, at least you give the user something to install which you do control. ... network and the server-- is next most important. ...
    (comp.arch.embedded)
  • Auto-update protocol
    ... The protocol can't be spoofed by "unfriendlies". ... Minimize unnecessary network traffic as well as ... load on the server (the goal is for the user *not* ... the fingerprint (why not just do a bytewise compare ...
    (comp.arch.embedded)