Coda File System

Re: Coda development (rpc2 handshake / instance authentication)

From: <u-myfx_at_aetey.se>
Date: Sat, 7 May 2016 17:36:22 +0200
On Fri, May 06, 2016 at 08:38:49PM -0400, Jan Harkes wrote:
> On Fri, May 06, 2016 at 08:59:15PM +0200, u-myfx_at_aetey.se wrote:
> > Nevertheless, one example to the contrary:
> > 
> > There is nothing preventing an update client to happily talk
> > to a wrong update server instance if the ip is spoofed and "scm"
> > data on some server hosts already are inconsistent
> > (iow there is a possibility of error escalation or recovery prevention).
> 
> In that case I can put your mind at easy very easily.
> 
> - There is only one update server in a realm, so a client cannot
>   accidentally talk to the wrong server within the same realm.
> - The update clients and update server use the 'update token' as a shared
>   secret to set up their connections.

> So any accidential or malicious other update server that happens to take
> over the same IP as the official update server will not possess the
> shared secret to succesfully fool the update client. And if it does have
> the right shared secret, a serverid isn't going to save anything here.

I am not worried about a man-in-the-middle who redirects traffic to a
server under his control, but about one who redirects traffic from one
service instance to another one.

In the example I am discussing a combination of several circumstances:
- corrupted consistency between different server instances so that
  they do not agree on who is scm
- a malicious party who can modify ip-numbers in packets in transit

Then an update client can be fooled to connect to a wrong/stale
update server which for any reason wrongly believes that it is scm.
As a result updates will be picked from a wrong source and they
can happen to be stale or corrupted, and the situation will be
undetectable for this update client.

A shared secret does not protect against this kind of influence.

The scenario above is artificially constructed but this does not
mean it is impossible.

> > From my perspective this is not any more of a layering violation than
> > CN checking in TLS.
> 
> TLS actually checks the common name in TLS, your server ids are some
> opaque blob passed up the application and are not checked by RPC2. So
> they can just as easily be implemented by adding a single RPC call right
> after connection setup doing something like a 'GetServerId', and then
> taking action in the client based on the result.

This looks like a clean and hardly disputable approach, applying the check
in the layer just above the rpc2 connection.

Indeed such a check is not automatically useful/necessary for every
protocol and thus rpc2 code might not be the most natural place for it.

(
 If there are multiple protocols making use of such a check, it probably
 should be "CheckServerId" (instead of Get...), to avoid to agree on a
 certain form and size of "serverid" and also to avoid the need to pass
 it over the wire - it can be long. A hash comparison with a generous
 hash size would do.

 The only downside I see is that this implies an additional rtt time
 at connection establishement, when the protocol applies the check.

 OTOH connection establishement is a heavy operation by itself and does
 not happen too often. If the check is done as an RPC, the extra rtt for
 the protocols which need this would be hardly noticeable.
)

Such an RPC would have a tiny impact on the code size, would not
postulate any modification of the existing code but allow for checking.
What can be better!

I agree otherwise that there is for the moment no practical impact
of _not_ doing such a check.

But when we make changes this can be useful for avoiding
the need of related exhaustive analysis of every case.

> This is actually quite close to what Coda clients do when they connect
> to Coda servers, they send an RPC request to 'bind' the connection to a
> specific volume, if the server claims it does not have the volume the
> connection is closed.

Given that this is a replica id (which of course can not be present on
another server), we are certainly in the clear.

> > > > Do you feel this would be expensive or risky? What would be the downsides,
> > > > besides the corresponding API extension (adding a "server instance id"

> Ok here is a simple answer. The server-id would probably end up as part
> of the INIT2 packet, which then turns any Coda server into a source for
> an amplification attack. Someone can send INIT1 packets from a fake
> origin, which then result in some very large INIT2 sent to the victim.

This would be bad indeed, but a change of the on-wire formats would be
probably not necessary.

> If you move it to the INIT4, by then the connection is already set up
> and it can just as well get sent as the first RPC on the new connection.

What I had in mind was mixing the data into the secret. This would
not change the size of any packet but ensure that the secret verification
fails as soon as there is a mismatch between what the client and the server
supply as the "id". Supplying an empty "id" would be even fully
compatible with peers running the current "instance-unaware" code.

The strengthening step would look to me like a suitable place for mixing
in the extra data.

This would generalize rpc2 to naturally support services
with multiple instances who share the authentication secret,
despite being distinct, from the upper layer protocol's viewpoint.

Coda servers are an example of such setup (they serve data which
differs between the servers, but share the authentication secret).
There are probably examples outside of Coda, too.

Given that Coda is the only known rpc2 user and that we do not see
apparent related vulnerabilities in its protocols, such a change is of
course less relevant.

Thanks Jan!

Rune
Received on 2016-05-07 11:36:54