[tahoe-dev] [tahoe-lafs] #466: extendable Introducer protocol: dictionary-based, signed announcements
tahoe-lafs
trac at tahoe-lafs.org
Fri Dec 24 23:13:48 UTC 2010
#466: extendable Introducer protocol: dictionary-based, signed announcements
------------------------------+---------------------------------------------
Reporter: warner | Owner:
Type: enhancement | Status: new
Priority: major | Milestone: undecided
Component: code-network | Version: 1.1.0
Resolution: | Keywords: introduction forward-compatibility performance accounting ecdsa pycryptopp review-needed
Launchpad Bug: |
------------------------------+---------------------------------------------
Comment (by warner):
I think I've got an idea to clean up the "what is your serverid anyway?"
issue. For reference, this is the problem:
* a server which is signing its Announcements holds two secrets:
* the Foolscap Tub private key, which is paired with the public
{{{TubID}}}
* the ECDSA signing key, which is paired with the public verifying-key /
keyid that shows up in the signed announcements
* For many aspects of Tahoe's share-placement behavior, we need a
reliable,
stable, and unspoofable "serverid":
* serverlist permutation
* write-enabler secrets
* consistent server reliability (if you think your share is safe because
it's on server A, but someone else was able to make you put the share
on
server B instead, then you aren't getting this. Note that server A is
allowed to unilaterally delegate its storage duties: the failure mode
is
if someone other than you and/or server A is able to make your share
go
elsewhere).
* and eventually accounting stuff
* To be unspoofable, the serverid needs to be the public half of some
cryptographic pair, so either the {{{TubID}}} or the ECDSA keyid would
do.
To be stable for all current servers, it needs to be the {{{TubID}}},
since
that's what we've been using since the beginning. But eventually we hope
to
get away from Foolscap and move to an easier-to-port-to-other-languages
protocol, so eventually we'd prefer to use the ECDSA keyid instead.
* To use the serverid safely, the client must validate it before allowing
any
of the storage-client code (!Uploader/Downloader) to rely upon it.
So today's thought is:
* the Introducer Announcement dictionary includes two new keys:
'{{{serverid}}}' and '{{{serverid-type}}}'
* the {{{StorageFarmBroker}}} (which subscribes to hear about storage
announcements and manages {{{RIStorageServer}}} connections) keeps two
lists: unvalidated announcements and validated connections. It only
tells
!Uploader/Downloader about the validated connections, in a table indexed
by
{{{serverid}}}.
* future world: new servers (who have never been known by their tubid)
will
set {{{serverid-type}}} to "pubkey_v1".
* The broker will validate the announcement by merely comparing
{{{serverid}}} against the keyid which was used to sign the
announcement.
({{{IntroducerClient}}} already checks signatures and discards invalid
ones, so the {{{subscribe}}} interface's callback is invoked with a
keyid
and an announcement dictionary).
* these new-world servers can still accept Foolscap connections, but
clients will connect to whatever FURL is in the announcement and won't
pay attention to that FURL's tubid: they will strictly use the pubkey
as
a serverid.
* current world: servers who *have* been known as a tubid will continue to
do
so: they will set {{{serverid-type}}} to "FURL_v1". When the broker sees
this, it will:
* compare the {{{TubID}}} of the claimed FURL against the announcement's
{{{serverid}}}, abort if they do not match
* connect to the FURL listed in the announcement
* invoke a new remote method, maybe named "{{{get_pubkey}}}"
* abort if the returned pubkey does not match the one used to sign the
announcement
* if they do match, validate the connection under the {{{serverid}}}
So when a {{{get_announcement}}} method returns a pubkey, that Tub is
delegating all its authority to the signing key. (this authority includes
the
right to know the write-enablers, and the right to decide where its shares
are placed).
The first check ({{{FURL.TubID}}} vs {{{serverid}}} is nominally redundant
(why not just extract the tubid and use it as the serverid), but I expect
it
will be convenient to keep a list of validated announcements around, and
we'd
like to be able to trust the {{{serverid}}} fields therein. It also
provides
useful non-validated data in some places (like the Introducer's web status
page).
The second check ({{{get_pubkey()==serverid}}}) blocks a bunch of noise:
bogus announcements made by someone other than the Tub operator, but
pointing
at that Tub. These announcements could contain false information about
server
capabilities, free space, versioning, etc (everything in the announcement
dictionary). By making sure that the Tub in question is actually willing
to
be represented (in announcements) by that pubkey, we prevent anyone else
from
making these false claims.
The legacy authority we're trying to protect here is the tubid-based
serverid. By restricting that authority to servers who can actually
provide
an object at that Tub, we prevent other parties from being able to claim
that
authority.
It's still an open question in my mind whether this transition is a good
idea
overall. I think it will help Tahoe if we can write clients in languages
other than Python, and relying upon Foolscap is a barrier to that (we
could
port Foolscap to other languages, but that feels like more work for less
gain
than changing Tahoe). If that's a good direction to go, then switching to
a
serverid based on some cryptographic quality *other* than a foolscap tubid
is
a necessary step.
I just worry about about the existing servers and the long-term baggage
that
they'll need to carry around (since all their mutable shares are tied to
the
serverid, they'll need to keep a Tub around forever, to prove knowledge of
the Tub private key, even if all the connections are using ECDSA-signed
HTTP
messages or whatnot). (incidentally, this might be relaxed somewhat if
[http://foolscap.lothar.com/trac/ticket/19 foolscap#19] were implemented,
allowing the SSL key to be used for signing arbitrary data, because then
we
could publish the public cert and its signature on the ECDSA pubkey in the
announcement. Both sides would still need to do some SSL work to verify
the
signature, but they wouldn't strictly need to use Foolscap to do it, nor
would they need to use foolscap connections to move shares around.
--
Ticket URL: <http://tahoe-lafs.org/trac/tahoe-lafs/ticket/466#comment:13>
tahoe-lafs <http://tahoe-lafs.org>
secure decentralized storage
More information about the tahoe-dev
mailing list