On Tue, Sep 18, 2007 at 03:50:18AM +0100, Daniel P. Berrange wrote:
> This is a serious patch at supporting Avahi advertisement of the libvirtd
> service.
> 
>  - configure by default will probe to see if avahi is available and if
>    found will enable appropriate code.
> 
>        --with-avahi    will force error if not found
>        --without-avahi   will disable it with no checking
> 
>  - HAVE_AVAHI is defined in config.h if avahi is found & used to conditionally
>    enable some code in qemud/qemud.c
> 
>  - HAVE_AVAHI is also a Makefile conditional to enable compilation of the
>    mdns.c and mdns.h files. A little makefile rearrangement was needed to
>    make sure variables like EXTRA_DIST were defined before we appended to
>    them with +=
> 
>  - The code in mdns.c contains all the support for dealing with the Avahi
>    APIs. 
> 
>  - The primary Avahi API is horribily complicated for day-to-day
>    use in application code, exposing far too much of the event loop and
>    state machine. So we expose a simplified API to libvirt in mdns.h

  Heh, did you tell the Avahi devels ?

>  - We fully support the Avahi state machine, so you can start libvirt even
>    if Avahi is not running on the machine. If you later start Avahi, then
>    libvirt will automatically detect & register with it. Likewise if you
>    stop Avahi we handle that gracefully by shutting down our internal mdns
>    support & waiting for avahi to restart. 
> 
>    NB this does require that the DBus system bus daemon is running. This
>    is a limitation of the current Avahi client library & not our use of it.
>    It is expected this will be fixed in future avahi releases.
> 
>  - The Avahi client library is basically a shim which talks to the Avahi
>    daemon using DBus system daemon. The DBus stuff doesn't leak out of 
>    the Avahi APIs - it is loosely couple - all we need do is provide Avahi
>    with an event loop implementation which was surprisingly easy. The
>    libvirtd daemon does now indirectly link with DBus, but I don't see any
>    problem with this. Don't want it - then use --without-avahi 

  That's fine, as long as the extensions don't decrease portability I
don't see this as a problem.

>  - We advertise a service name of _libvirt._tcp  The IETF draft recommends
>    use of the name from /etc/services associated with your app. There is a
>    way to register official Avahi services names. We don't have an 
> /etc/service
>    name registered either though.

  I rememember we looked at the IANA stuff for registering a port number
  http://www.redhat.com/archives/libvir-list/2007-June/msg00204.html
I suggested using 
  "10 " What SHORT name (14 CHARACTER MAXIMUM) do you want associated with this 
port number?"

  libvirt"

But we never did that registration step.

>  - If TLS is *not* enabled, we advertise _libvirt._tcp with a port number
>    of 0.  The use of a port number 0 is explicitly allowed by the IETF
>    draft docs - see [1] "8. Flagship Naming".  If seeing the _libvirt._tcp
>    service with a port of 0, then clients should figure out some way to
>    to tunnel to the UNXI domain socket on the advertised machine. The
>    tunnel mechanism is undefined, though SSH is the obvious choice.
> 
>    If TLS is enabled, then we use getsockname() to fetch the actual port 
>    number we're listening on for the TLS enabled socket. This plays nice 
>    with admins ability to override the port number. Clients  can still of
>    course choose to tunnel instead of use TLS.
> 
>    NB. we explicitly refuse to advertise the non-TLS port.
> 
>  - The default service name we advertise is 'Virtualization Host %h' where
>    '%h' is the short hostname (ie without domain name). This has to be less
>    than 63 characters & stripping domain name is usual practice, since this
>    is implicit from the mdns domain you are browsing.
> 
>    This can be overridden with mdns_name="Blah"  in the libvirtd.conf
>    configuration file. Service names *must* be unique in the LAN. If a name
>    clashes, then avahi appends junk like #1, #2, #3... until it is unique.
> 
>  - Even when compiled in, use of Avahi mdns can be disabled by setting the
>    mdns_adv=0 config file parameter in /etc/libvirt/libvirtd.conf
> 
>  - This patch does not advertise any per-VM  VNC server instances, but I have
>    prepared the APIs in mdns.h to be ready to support that with minimal 
> effort.
>    A pre-requisite for this is an extension to the driver API to get async
>    signals when VMs start & stop, since making the daemon poll hypervisors 
>    will suck big time.
> 
>    When implemented each VM will be its own mdns 'group' and the VNC server
>    associated with it will be the 'service' advertised in that group.
> 
> Having applied this patch & started the daemon, if /etc/init.d/avahi-daemon
> is running, you should see the service advertised on the LAN. As mentioned
> earlier if you start Avahi daemon after libvirt it should detect this too.

  Sounds excellent !

> You can verify by running the following on another box on the same local
> LAN segment.
> 
>   $ avahi-browse --resolve _libvirt._tcp 
> 
> 
> When you start libvirtd on the other box the avahi-browse should print out
> a record. It should look like this:
> 
> + eth0 IPv4 Virtualization Host avocado          _libvirt._tcp        local
> = eth0 IPv4 Virtualization Host avocado          _libvirt._tcp        local
>    hostname = [avocado.local]
>    address = [10.13.7.48]
>    port = [16514]
>    txt = ["org.freedesktop.Avahi.cookie=3025088350"]
> 
> 
> If you've not configured TLS, then port will be '0' instead of 16514.
> 
> 
> So that brings me nicely onto the main outstanding issue.
> 
> Notice the hostname is 'avocado.local' - this is the standard mdns practice
> for zero-conf DNS hostnames. If you're /etc/nsswitch.conf is setup correctly
> the name avocado.local will actually resolve to the IP address you see there
> of '10.13.7.48' (well s/avocado/your hostname/ of course).
> 
> Well, x509 certificates include a FQDN in them & the client is expected to
> validate the certificate hostname against the hostname it connected to. Now
> my FQDN is  avocado.virt.boston.redhat.com which is obviously going to not
> validate against avocado.local.
>
> There're a couple of ways around this issue I can come up with so far
> 
>   - Recommend that the client try to reverse-DNS the 'address' field from
>     the mdns advertisement. If reverse-DNS is working, 10.13.7.48 will be
>     transformed into 'avocado.virt.boston.redhat.com' which the client can
>     then connect to. 
> 
>   - Add TXT record containing the hostname associated with the certificate.
>     If the client were to use this record, then obviously any validation of
>     it against the resulting certificate is sort-of pointless, since both
>     came from the server. The first approach rather had this drawback too.
> 
>   - Advertise the records in the real domain 'virt.boston.redhat.com' instead
>     of '.local'. Not been able to make this work. 
> 
>   - Simply don't bother validating the remote hostname against the server
>     certificate cname. ie, take the position that if using zero-conf then
>     you already have some implicit level of trust in your LAN and validating
>     the cert against the CA cert is sufficient & hostname matching can be
>     ignored.
> 
> These are all mildy abusing mdns / zeroconf, but then x509 certificates don't
> really fit into the model of 'zero conf' in the first place. If people want 
> true zero-conf then the (SSH) tunnel is better (and always available), but 
> if they've setup certificates they should still be allowed to use zero-conf 
> to at least locate hosts. So mildly abusing the rules is reasonable IMHO.

  Maybe suggesting that application developpers default to SSH when using
a server autodetected with Avahi is the most practical ATM assuming we don't
find a way to advertise the FQDN. Unless we can find the domain from the
locally installed certificate, after all if people want to use the certificate
they should have some installed locally and then we can probably guess the
right domain name, no ?

> Personally I'm tending towards the latter approach.
> +dnl Avahi library
> +AC_ARG_WITH(avahi,
> +  [  --with-avahi         use avahi to advertise remote daemon],
> +  [],
> +  [with_avahi=check])
> +
> +if test "$with_avahi" = "check"; then
> +  PKG_CHECK_EXISTS(avahi-client >= $AVAHI_REQUIRED, [with_avahi=yes], 
> [with_avahi=no])
> +fi
> +
> +if test "$with_avahi" = "yes"; then
> +  PKG_CHECK_MODULES(AVAHI, avahi-client >= $AVAHI_REQUIRED)
> +  AC_DEFINE_UNQUOTED(HAVE_AVAHI, 1, [whether Avahi is used to broadcast 
> server presense])
> +else
> +  AVAHI_CFLAGS=
> +  AVAHI_LIBS=
> +fi
> +AM_CONDITIONAL(HAVE_AVAHI, [test "$with_avahi" = "yes"])
> +AC_SUBST(AVAHI_CFLAGS)
> +AC_SUBST(AVAHI_LIBS)

  I assume that if an OS has Avahi, then it has pkg-check, in that case it
really should not be a problem.

> +
> +if HAVE_AVAHI
> +libvirtd_SOURCES += mdns.c mdns.h
> +libvirtd_CFLAGS += $(AVAHI_CFLAGS)
> +libvirtd_LDADD += $(AVAHI_LIBS)
> +else
> +EXTRA_DIST += mdns.c mdns.h
> +endif

  Wouldn't adding them to EXTRA_DIST in any case be good enough ?
if SOURCES and EXTRA_DIST carry the same is that really a problem when
building the archive ?


   Patch is surprizingly small, looks good, I would commit to CVS, no pending
issue looks like a potential real problem for users, and more testing would
be good.

    +1

Daniel

-- 
Red Hat Virtualization group http://redhat.com/virtualization/
Daniel Veillard      | virtualization library  http://libvirt.org/
[EMAIL PROTECTED]  | libxml GNOME XML XSLT toolkit  http://xmlsoft.org/
http://veillard.com/ | Rpmfind RPM search engine  http://rpmfind.net/

--
Libvir-list mailing list
Libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Reply via email to