mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-11-06 13:20:20 +00:00
22f7ceb695
So far the NSS module looks up only hostnames as provided by guests themselves. However, there are some cases where this is not enough: e.g. when there's a fresh new guest being installed (with some generic hostname) say from a live ISO image; or some (older) systems don't advertise their hostname in DHCP transactions at all. In cases like that it would be helpful if we translate domain name as seen by libvirt too so that users can: # virsh start $dom && ssh $dom In order to achieve that new libvirt-guest module is introduced, while older libvirt module maintains its current behaviour (that is translating guest provided names into IP addresses). Signed-off-by: Michal Privoznik <mprivozn@redhat.com>
190 lines
7.5 KiB
XML
190 lines
7.5 KiB
XML
<?xml version="1.0" encoding="UTF-8"?>
|
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
|
<body>
|
|
<h1>Libvirt NSS module</h1>
|
|
|
|
<ul id="toc"></ul>
|
|
|
|
<p>
|
|
When it comes to managing guests and executing commands inside them, logging
|
|
into guest operating system and doing the job is convenient. Users are used
|
|
to ssh in this case. Ideally:
|
|
</p>
|
|
|
|
<code>ssh user@virtualMachine</code>
|
|
|
|
<p>
|
|
would be nice. But depending on virtual network configuration it might not
|
|
be always possible. For instance, when using libvirt NATed network it's
|
|
dnsmasq (spawned by libvirt) who assigns IP addresses to domains. But by
|
|
default, the dnsmasq process is then not consulted when it comes to host
|
|
name translation. Users work around this problem by configuring their
|
|
libvirt network to assign static IP addresses and maintaining
|
|
<code>/etc/hosts</code> file in sync. But this puts needless burden onto
|
|
users. This is where NSS module comes handy.
|
|
</p>
|
|
|
|
<h2><a name="Installation">Installation</a></h2>
|
|
|
|
<p>
|
|
Installing the module is really easy:
|
|
</p>
|
|
|
|
<pre>
|
|
# yum install libvirt-nss
|
|
</pre>
|
|
|
|
<h2><a name="Configuration">Configuration</a></h2>
|
|
|
|
<p>
|
|
Enabling the module is really easy. Just add <b>libvirt</b> into
|
|
<code>/etc/nsswitch.conf</code> file. For instance:
|
|
</p>
|
|
|
|
<pre>
|
|
$ cat /etc/nsswitch.conf
|
|
# /etc/nsswitch.conf:
|
|
passwd: compat
|
|
shadow: compat
|
|
group: compat
|
|
hosts: files libvirt dns
|
|
# ...
|
|
</pre>
|
|
|
|
<p>
|
|
So, in this specific case, whenever ssh program is looking up the host user
|
|
is trying to connect to, <b>files</b> module is consulted first (which
|
|
boils down to looking up the host name in <code>/etc/hosts</code> file), if
|
|
not found <b>libvirt</b> module is consulted then. The DNS is the last
|
|
effort then, if none of the previous modules matched the host in question.
|
|
Therefore users should consider the order in which they want the modules to
|
|
lookup given host name.
|
|
</p>
|
|
|
|
<h2><a name="Sources">Sources of information</a></h2>
|
|
|
|
<p>
|
|
As of <code>v3.0.0</code> release, libvirt offers two NSS modules
|
|
implementing two different methods of hostname translation. The first and
|
|
older method is implemented by <code>libvirt</code> plugin and
|
|
basically looks up the hostname to IP address translation in DHCP server
|
|
records. Therefore this is dependent on hostname provided by guests. Thing
|
|
is, not all the guests out there provide one in DHCP transactions, or not
|
|
every sysadmin out there believes all the guests. Hence libvirt implements
|
|
second method in <code>libvirt-guest</code> module which does libvirt guest
|
|
name to IP address translation (regardless of hostname set in the guest).
|
|
</p>
|
|
|
|
<p>
|
|
To enable either of the modules put their name into the
|
|
<code>nsswitch.conf</code> file. For instance, to enable
|
|
<code>libvirt-guest</code> module:
|
|
</p>
|
|
|
|
<pre>
|
|
$ cat /etc/nsswitch.conf
|
|
# /etc/nsswitch.conf:
|
|
hosts: files libvirt-guest dns
|
|
# ...
|
|
</pre>
|
|
<p>Or users can enable both at the same time:</p>
|
|
<pre>
|
|
$ cat /etc/nsswitch.conf
|
|
# /etc/nsswitch.conf:
|
|
hosts: files libvirt libvirt-guest dns
|
|
# ...
|
|
</pre>
|
|
|
|
<p>
|
|
This configuration will mean that if hostname is not found by the
|
|
<code>libvirt</code> module (e.g. because a guest did not sent hostname
|
|
during DHCP transaction), the <code>libvirt-guest</code> module is
|
|
consulted (and if the hostname matches libvirt guest name it will be
|
|
resolved).
|
|
</p>
|
|
|
|
<h2><a name="Internals">How does it work?</a></h2>
|
|
|
|
<p>
|
|
Whenever an Unix process wants to do a host name translation
|
|
<a href="http://linux.die.net/man/3/gethostbyname"><code>gethostbyname()</code></a>
|
|
or some variant of it is called. This is a glibc function that takes a
|
|
string containing the host name, crunch it and produces a list of IP
|
|
addresses assigned to that host. Now, glibc developers made a really good
|
|
decision when implementing the internals of the function when they decided
|
|
to make the function pluggable. Since there can be several sources for the
|
|
records (e.g. <code>/etc/hosts</code> file, DNS, LDAP, etc.) it would not
|
|
make much sense to create one big implementation containing all possible
|
|
cases. What they have done instead is this pluggable mechanism. Small
|
|
plugins implementing nothing but specific technology for lookup process are
|
|
provided and the function then calls those plugins. There is just one
|
|
configuration file that instructs the lookup function in which order should
|
|
the plugins be called and which plugins should be loaded. For more info
|
|
reading <a href="https://en.wikipedia.org/wiki/Name_Service_Switch">wiki
|
|
page</a> is recommended.
|
|
</p>
|
|
|
|
<p>
|
|
And this is point where libvirt comes in. Libvirt provides plugin for the
|
|
NSS ecosystem. For some time now libvirt keeps a list of assigned IP
|
|
addresses for libvirt networks. The NSS plugin does no more than search the
|
|
list trying to find matching record for given host name. When found,
|
|
matching IP address is returned to the caller. If not found, translation
|
|
process continues with the next plugin configured. At this point it is
|
|
important to stress the order in which plugins are called. Users should be
|
|
aware that a hostname might match in multiple plugins and right after first
|
|
match, translation process is terminated and no other plugin is consulted.
|
|
Therefore, if there are two different records for the same host name users
|
|
should carefully chose the lookup order.
|
|
</p>
|
|
|
|
<h2><a name="Limitations">Limitations</a></h2>
|
|
|
|
<ol>
|
|
<li>The <code>libvirt</code> NSS module matches only hostnames provided by guest.
|
|
If the libvirt name and one advertised by guest differs, the latter is
|
|
matched. However, as of <code>v3.0.0</code> there are two libvirt NSS modules
|
|
translating both hostnames provided by guest and libvirt guest names.</li>
|
|
<li>The module works only in that cases where IP addresses are assigned by
|
|
dnsmasq spawned by libvirt. Libvirt NATed networks are typical
|
|
example.</li>
|
|
</ol>
|
|
|
|
<p>
|
|
<i>The following paragraph describes implementation limitation of the
|
|
<code>libvirt</code> NSS module.</i>
|
|
These limitation are result of libvirt's internal implementation. While
|
|
libvirt can report IP addresses regardless of their origin, a public API
|
|
must be used to obtain those. However, for the API a connection object is
|
|
required. Doing that for every name translation request would be too
|
|
costly. Fortunately, libvirt spawns dnsmasq for NATed networks. Not only
|
|
that, it provides small executable that on each IP address space change
|
|
updates an internal list of addresses thus keeping it in sync. The NSS
|
|
module then merely consults the list trying to find the match. Users can
|
|
view the list themselves:
|
|
</p>
|
|
|
|
<pre>
|
|
virsh net-dhcp-leases $network
|
|
</pre>
|
|
|
|
<p>
|
|
where <code>$network</code> iterates through all running networks. So the module
|
|
does merely the same as
|
|
</p>
|
|
|
|
<pre>
|
|
virsh domifaddr --source lease $domain
|
|
</pre>
|
|
|
|
<p>
|
|
If there's no record for either of the aforementioned commands, it's
|
|
very likely that NSS module won't find anything and vice versa.
|
|
As of <code>v3.0.0</code> libvirt provides <code>libvirt-guest</code> NSS
|
|
module that doesn't have this limitation. However, the statement is still
|
|
true for the <code>libvirt</code> NSS module.
|
|
</p>
|
|
</body>
|
|
</html>
|