Wouter Verhelst <w(a)uter.be> writes:
On Mon, Oct 20, 2014 at 01:51:43PM +0200, Markus Armbruster wrote:
> Stefan Hajnoczi <stefanha(a)redhat.com> writes:
>
> > On Mon, Oct 20, 2014 at 08:58:14AM +0100, Daniel P. Berrange wrote:
> >> On Sat, Oct 18, 2014 at 07:33:22AM +0100, Richard W.M. Jones wrote:
> >> > On Sat, Oct 18, 2014 at 12:03:23AM +0200, Wouter Verhelst wrote:
> >> > > Hi all,
> >> > >
> >> > > (added rjones from nbdkit fame -- hi there)
> >> >
> >> > [I'm happy to implement whatever you come up with, but I've
added
> >> > Florian Weimer to CC who is part of Red Hat's product security
group]
> >> >
> >> > > So I think the following would make sense to allow TLS in NBD.
> >> > >
> >> > > This would extend the newstyle negotiation by adding two options
(i.e.,
> >> > > client requests), one server reply, and one server error as well
as
> >> > > extend one existing reply, in the following manner:
> >> > >
> >> > > - The two new commands are NBD_OPT_PEEK_EXPORT and
NBD_OPT_STARTTLS. The
> >> > > former would be used to verify if the server will do TLS for a
given
> >> > > export:
> >> > >
> >> > > C: NBD_OPT_PEEK_EXPORT
> >> > > S: NBD_REP_SERVER, with an extra field after the export name
> >> > > containing flags that describe the export (R/O vs R/W state,
> >> > > whether TLS is allowed and/or required).
> >>
> >> IMHO the server should never provide *any* information about the exported
> >> volume(s) until the TLS layer has been fully setup. ie we shouldn't
only
> >> think about the actual block data transfers, we should protect the entire
> >> NBD protocol even metadata related operations.
> >
> > This makes sense.
>
> Seconded.
Mmm. I suppose the NBD_OPT_PEEK_EXPORT message could be defined so that
it is fine for an export which has the "TLS required" bit set to provide
differing information after TLS has been negotiated.
Why is it useful to have a per-export "TLS required" bit?
Stefan's argument:
> > TLS is about the transport, not about a particular NBD
export. The only
> > thing that should be communicated is STARTTLS.
makes sense to me.
Wouldn't a per-export "TLS required" bit enlarge the attack surface? It
puts the "peek export" operation into the "without authentication"
bucket *and* makes it more complex.
The least complex STARTTLS solution seems to be "if server wants TLS,
absolutely nothing works but switching to TLS and any feature
negotiation necessary for the client to recognize the need to switch".
Hmm, further down you give a reason why you want to mix encrypted and
unencrypted exports.
> Furthermore, STARTTLS is vulnerable to active attacks: if you can
get
> between the peers, you can make them fall back to unencrypted silently.
> How do you plan to guard against that?
As I've said before in this discussion, encryption downgrade attacks are
not specific to STARTTLS; as soon as you have have an "encrypted" and an
"unencrypted" variant of a protocol, that becomes a problem. After all,
if an attacker can modify the communication so that STARTTLS is filtered
out of the communication, they can most likely also redirect all traffic
to a decrypting/encrypting proxy.
The only way to fix that is through userspace; make "opportunistic" TLS
(i.e., use it if available, but move on if not) difficult to achieve.
> See also
https://www.agwa.name/blog/post/starttls_considered_harmful
A random blog post by an author who is speaking about STARTTLS in
general terms is not a good technical argument for why STARTTLS is a bad
idea in *this* specific case.
Misunderstanding. I didn't mean to claim "STARTTLS is bad". If I
wanted to say that, I would've said it directly. I was merely asking
how you plan to guard against downgrade attacks. I gather your advice
is to make the client (QEMU) insist on TLS, and check the server's
certificate. Correct?
If I was defining a new protocol from scratch, I might dump the
whole
thing in TLS to begin with. But that's just not the case, so I have to
deal with what exists already.
Yes. You can still start over on a separate port. However:
In addition, with the current state of affairs, it is *not possible*
to
swap to an NBD device if you need to pipe its data through a separate
socket than the one you're handing to the kernel. The result of that is
that you can't do TLS on a device you want to swap to. This means we
need to continue to support a protocol that can do TLS for some exports,
and plain (unencrypted) traffic for other exports, *in the same running
nbd-server instance*.
I don't understand enough about NBD to challenge this argument. The sad
consequence is more complexity and a larger attack surface.
Out of curiosity: is this "merely" an implementation restriction, or is
it more fundamental?
I did add the NBD_REP_ERR_TLS_REQD message for a server which does
not
export anything unencrypted, so that it can (after the initial few
exchanges) reply to anything except for STARTTLS with "lalala, I'm not
listening until you encrypt things". However, unless it's fine to ditch
support for swapping to an NBD device (not an option from where I'm
standing), dropping support for unencrypted communication is not an
option.
That's a good idea. It doesn't make things less complex, though.