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: