[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: [PATCH v2] doc: Define a standard URI syntax for NBD URIs.



On Wed, Jun 05, 2019 at 01:27:48PM -0500, Eric Blake wrote:
> On 6/5/19 12:19 PM, Daniel P. Berrangé wrote:
> > On Tue, May 28, 2019 at 11:35:37AM +0100, Richard W.M. Jones wrote:
> >> For further information about discussion around this standard, see
> >> this thread on the mailing list:
> >> https://lists.debian.org/nbd/2019/05/msg00013.html
> >>
> 
> > 
> >> +## NBD URI scheme
> >> +
> >> +One of the following scheme names SHOULD be used to indicate an NBD URI:
> >> +
> >> +* `nbd`: NBD over an unencrypted or opportunistically TLS encrypted
> >> +  TCP/IP connection.
> >> +
> >> +* `nbds`: NBD over a TLS encrypted TCP/IP connection.  If encryption
> >> +  cannot be negotiated then the connection MUST fail.
> >> +
> >> +* `nbd+unix`: NBD over a Unix domain socket.  The query parameters
> >> +  MUST include a parameter called `socket` which refers to the name of
> >> +  the Unix domain socket.
> > 
> > This should mention "nbds+unix", since it is valid to run TLS over a
> > UNIX socket to. This does have complications for x509 though, because
> > you then need to explicitly pass the hostname to validate the cert
> > against. For PSK it is trivial though.
> > 
> > The rationale for TLS over UNIX sockets, is that the UNIX socket may
> > simply be a local tunnel to the real TCP connection.
> 
> qemu-nbd does not yet support TLS over Unix, but bringing it into line
> with what we document here should fill in that gap.
> 
> >> +## NBD URI authority
> >> +
> >> +The authority field SHOULD be used for TCP/IP connections and SHOULD
> >> +NOT be used for Unix domain socket connections.
> >> +
> >> +The authority field MAY contain the `userinfo`, `host` and/or `port`
> >> +fields as defined in [RFC 3986](https://www.ietf.org/rfc/rfc3986.txt)
> >> +section 3.2.
> >> +
> >> +The `host` field may be a host name or IP address.  Literal IPv6
> >> +addresses MUST be formatted in the way specified by
> >> +[RFC 2732](https://www.ietf.org/rfc/rfc2732.txt).
> >> +
> >> +If the `port` field is not present then it MUST default to the NBD
> >> +port number assigned by IANA (10809).
> >> +
> >> +The `userinfo` field is used to supply a username for TLS
> >> +authentication.  If the `userinfo` field is not present but is needed
> >> +by the client for TLS authentication then it SHOULD default to a local
> >> +operating system credential if one is available.
> > 
> > What do you mean by "TLS authentication" here ? This is the name used
> > to lookup the PSK credentials when the PSK file contains many creds ?
> > 
> > If so this probably needs explaining, since IIUC this use of many
> > PSK creds in one file is not really a TLS thing, it is an impl
> > choice of QEMU's PSK support.
> > 
> > Using the URI authority section for passing "userinfo" feels like a
> > bad idea though. Shouldn't we pass that as a parameter and keep the
> > authority as the normal "hostname" semantics, or unused if no hostname
> > is applicable.
> 
> If I'm understanding the intent, this is a difference between:
> 
> nbds://user@host/exportname
> nbd+unix://user@/exportname?socket=path
> 
> vs.
> 
> nbds://host/exportname?tls_username=user
> nbd+unix:///exportname?socket=path&tls_username=user
> 
> I don't have a strong preference at the moment.

Actually ignore my comment here. I was misreading the text above
as saying that the hostname part should be interpreted as a username,
which is obviously wrong.

> >> +It is up to the NBD client what should happen if the authority field
> >> +is not present for TCP/IP connections, or present for Unix domain
> >> +socket connections.  Options might include failing with an error,
> >> +ignoring it, or using defaults.
> 
> The userinfo field is part of the authority; so this is
> self-contradictory if we want nbds+unix://username@/ for specifying the
> tls username.

Yeah, ignore my comment.

> 
> 
> >> +
> >> +On platforms which support Unix domain sockets in the abstract
> >> +namespace, and if the client supports this, the `socket` parameter MAY
> >> +begin with an ASCII NUL character.  When the URI is properly encoded
> >> +it will look like this:
> >> +
> >> +    nbd+unix:///?socket=%00/abstract
> > 
> > In the abstract namespace, the entire 108 characters are significant.
> > IOW, if you pass a 10 character abstract path you've got 98 NULs
> > implicitly following that. We should document this, as it is a
> > frequent interoperability screw up in apps to not take this into
> > account.
> 
> Does the Linux kernel treat:
> 
> "\0a" length 2
> "\0a\0...\0" length 108
> 
> as the same socket? If specifying an explicit shorter length has the
> same effect as providing explicit NUL bytes in the padding of a longer
> length, that's a little easier, but yes, documenting that any trailing
> bytes must be initialized to 0 is worthwhile.

I thought it did, but after testing, I can confirm they are different.

$ netstat -a -n -x -p | grep './unix-demo'
unix  2      [ ]         STREAM                   638293   15094/./unix-demo           @a
unix  2      [ ]         STREAM                   638292   15094/./unix-demo           @a@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

IOW, if users want padding, they must specify the URI encoded
trailing NULs.

I would note that QEMU is not able to support abstract sockets
right now & it isn't easy to add this if the path contains
real NULs. In QAPI it uses 'str' which assumes NUL-terminated
string with no embedded NULs. The sockets code liberally
uses strlen() too.  A common "hack" is to use "@" in place of
a real NUL, though that makes life confusing if you want a
real "@".

> 
> >> +If TLS encryption is to be negotiated then the following query
> >> +parameters MAY be present:
> >> +
> >> +* `tls-type`: Possible values include `anon`, `x509` or `psk`.  This
> >> +  specifies the desired TLS authentication method.  The client MAY
> >> +  default to an authentication method based on which other `tls-*`
> >> +  parameters are present.
> >> +
> >> +* `tls-certificates`: The path to the TLS certificates directory.
> >> +
> >> +* `tls-psk-file`: The path to the TLS-PSK key file.
> > 
> > In QEMU, we don't accept a path to the PSK file, we take a path to
> > a directory which contains "tls-creds-psk" and optionally also
> > a "dh-params.pem" file.
> > 
> > IOW, we just have a single "tls-creds-dir" parameter working the
> > same way for PSK and x509. All that differs is what files are
> > expected to be present.
> > 
> > So this spec conflicts with QEMU's view of managing TLS creds
> > files.
> 
> We could, of course, teach qemu to support whatever this spec ends up
> with in addition to everything else; but there's also the point that the
> qemu code uses a consistent model for TLS across multiple entities (not
> just NBD, but also Spice, chardevs, ...), and then there's the question
> of whether a compatibility hack should be global to all of them or just
> to the NBD code.
> 
> > 
> >> +* `tls-hostname`: The TLS client hostname.
> > 
> > We should document how this relates to the hostname in the URI
> > authority. ie, if omitted the URI authority will be used instead.
> 
> If a Unix socket is using TLS, would we allow URI authority there?

We could allow either.

Regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|


Reply to: