Вопрос: Доступ к виртуальным машинам libvirt + KVM с DNS


У меня есть машина Ubuntu Trusty с KVM + Libvirt для управления небольшими виртуальными машинами и использование стандартного NetworkManager для подключения к обычным сетям.

Я хочу иметь доступ к виртуальным машинам через DNS с хоста.

Libvirt использует виртуальную приватную подсеть (192.168.122.0/24), NAT для доступа к остальному миру через мост (virbr0) на моем eth0. Dnamasq приносит DHCP + DNS этой виртуальной сети.

Это версия libvirt для виртуальной сети:

<network>
  <name>default</name>
  <uuid>400c59ff-c276-4154-ab73-9a8a8d1c6be3</uuid>
  <forward mode='nat'>
    <nat>
      <port start='1024' end='65535'/>
    </nat>
  </forward>
  <bridge name='virbr0' stp='on' delay='0'/>
  <mac address='52:54:00:f4:bd:37'/>
  <domain name='kvm'/>
  <dns forwardPlainNames='no'>
    <forwarder addr='127.0.1.1'/>
    <host ip='192.168.122.1'>
      <hostname>host</hostname>
      <hostname>host.kvm</hostname>
    </host>
  </dns>
  <ip address='192.168.122.1' netmask='255.255.255.0'>
    <dhcp>
      <range start='192.168.122.2' end='192.168.122.254'/>
    </dhcp>
  </ip>
</network>

Libvirt запускает экземпляр dnsmasq, прослушивающий 192.168.122.1:53, который отвечает на все запросы для .knv и пересылает любые другие запросы моему хосту. Эта конфигурация dnsmasq автоматически создается libvirt:

/var/lib/libvirt/dnsmasq/default.conf

##WARNING:  THIS IS AN AUTO-GENERATED FILE. CHANGES TO IT ARE LIKELY TO BE
##OVERWRITTEN AND LOST.  Changes to this configuration should be made using:
##    virsh net-edit default
## or other application using the libvirt API.
##
## dnsmasq conf file created by libvirt
strict-order
user=libvirt-dnsmasq
no-resolv
server=127.0.1.1
domain=kvm
expand-hosts
domain-needed
local=//
pid-file=/var/run/libvirt/network/default.pid
except-interface=lo
bind-dynamic
interface=virbr0
dhcp-range=192.168.122.2,192.168.122.254
dhcp-no-override
dhcp-leasefile=/var/lib/libvirt/dnsmasq/default.leases
dhcp-lease-max=253
dhcp-hostsfile=/var/lib/libvirt/dnsmasq/default.hostsfile
addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts

NetworkManager имеет экземпляр dnsmasq, прослушивающий 127.0.1.1:53, который он использует для всех запросов DNS, прежде чем переходить на какие-либо DNS-серверы, которые мой хост получает от внешней DHCP-системы.

Чтобы моя система Ubuntu моего хоста использовала dnsmasq libvirt, я указываю dnsmasq NetworkManager использовать 192.168.122.1 для домена kvm:

/etc/NetworkManager/dnsmasq.d/libvirt.conf

server=/kvm/192.168.122.1

И это работает, по большей части ...

me@host ~ $ ps aufx
...cut...
root     11010  0.2  0.0 342084  6348 ?        Ssl  10:59   0:00 NetworkManager
root     11018  0.0  0.0  10232  3732 ?        S    10:59   0:00  \_ /sbin/dhclient -d -sf /usr/lib/NetworkManager/nm-dhcp-client.action -pf /run/sendsigs.omit.d/network-manager.dhclient-eth0.pid -lf /var/lib/NetworkManager/dhclient-b8043 
nobody   11228  0.0  0.0  32252  1564 ?        S    10:59   0:00  \_ /usr/sbin/dnsmasq --no-resolv --keep-in-foreground --no-hosts --bind-interfaces --pid-file=/run/sendsigs.omit.d/network-manager.dnsmasq.pid --listen-address=127.0.1.1 --
root     11033  1.0  0.1 513356 15160 ?        Sl   10:59   0:01 /usr/sbin/libvirtd -d
libvirt+ 11085  0.0  0.0  28208   948 ?        S    10:59   0:00 /usr/sbin/dnsmasq --conf-file=/var/lib/libvirt/dnsmasq/default.conf

me@host ~ $ sudo netstat -nulpd | grep dnsmasq
udp  0  0  127.0.1.1:53      0.0.0.0:*  11228/dnsmasq   
udp  0  0  192.168.122.1:53  0.0.0.0:*  11085/dnsmasq   
udp  0  0  0.0.0.0:67        0.0.0.0:*  11085/dnsmasq  

me@host ~ $ host test.kvm
test.kvm has address 192.168.122.193
;; connection timed out; no servers could be reached
;; connection timed out; no servers could be reached

Но создает огромное количество запросов dnsmasq AAAA, ожидающих ответа.

me@host ~ $ sudo netstat -nulpd | grep dnsmasq
udp  0  0  0.0.0.0:39329  0.0.0.0:*  11228/dnsmasq   
udp  0  0  0.0.0.0:2469   0.0.0.0:*  11085/dnsmasq   
udp  0  0  0.0.0.0:14805  0.0.0.0:*  11228/dnsmasq
...cut...
udp  0  0  0.0.0.0:51569  0.0.0.0:*  11228/dnsmasq   
udp  0  0  0.0.0.0:31091  0.0.0.0:*  11085/dnsmasq   
udp  0  0  0.0.0.0:39305  0.0.0.0:*  11085/dnsmasq

me@host ~ $ sudo netstat -nulpd | grep dnsmasq | wc -l
131

И tcpdump показывает, что это в основном запросы AAAA:

me@host ~ $ sudo tcpdump -vni any udp port 53
tcpdump: listening on any, link-type LINUX_SLL (Linux cooked), capture size 65535 bytes
11:04:49.453864 IP (tos 0x0, ttl 64, id 56217, offset 0, flags [none], proto UDP (17), length 55)
    127.0.0.1.58535 > 127.0.1.1.53: 31275+ A? mysql.kvm. (27)
11:04:49.453948 IP (tos 0x0, ttl 64, id 20062, offset 0, flags [DF], proto UDP (17), length 55)
    192.168.122.1.7098 > 192.168.122.1.53: 41491+ A? mysql.kvm. (27)
11:04:49.454013 IP (tos 0x0, ttl 64, id 20063, offset 0, flags [DF], proto UDP (17), length 71)
    192.168.122.1.53 > 192.168.122.1.7098: 41491* 1/0/0 mysql.kvm. A 192.168.122.193 (43)
11:04:49.454068 IP (tos 0x0, ttl 64, id 37088, offset 0, flags [DF], proto UDP (17), length 71)
    127.0.1.1.53 > 127.0.0.1.58535: 31275* 1/0/0 mysql.kvm. A 192.168.122.193 (43)
11:04:49.454321 IP (tos 0x0, ttl 64, id 56218, offset 0, flags [none], proto UDP (17), length 55)
    127.0.0.1.56040 > 127.0.1.1.53: 47999+ AAAA? mysql.kvm. (27)
11:04:49.454381 IP (tos 0x0, ttl 64, id 20064, offset 0, flags [DF], proto UDP (17), length 55)
    192.168.122.1.19631 > 192.168.122.1.53: 20542+ AAAA? mysql.kvm. (27)
...cut...
11:05:09.510237 IP (tos 0x0, ttl 64, id 20515, offset 0, flags [DF], proto UDP (17), length 55)
    192.168.122.1.19631 > 192.168.122.1.53: 35761+ MX? mysql.kvm. (27)
11:05:09.510237 IP (tos 0x0, ttl 64, id 56674, offset 0, flags [DF], proto UDP (17), length 55)
    127.0.0.1.46085 > 127.0.1.1.53: 53641+ AAAA? mysql.kvm. (27)
11:05:09.510315 IP (tos 0x0, ttl 64, id 56675, offset 0, flags [DF], proto UDP (17), length 55)
    127.0.0.1.46085 > 127.0.1.1.53: 26166+ MX? mysql.kvm. (27)
11:05:09.510334 IP (tos 0x0, ttl 64, id 20516, offset 0, flags [DF], proto UDP (17), length 55)
    192.168.122.1.19631 > 192.168.122.1.53: 4247+ AAAA? mysql.kvm. (27)
11:05:09.510407 IP (tos 0x0, ttl 64, id 56676, offset 0, flags [DF], proto UDP (17), length 55)
    127.0.0.1.46085 > 127.0.1.1.53: 49331+ AAAA? mysql.kvm. (27)
11:05:09.510433 IP (tos 0x0, ttl 64, id 20517, offset 0, flags [DF], proto UDP (17), length 55)
    192.168.122.1.19631 > 192.168.122.1.53: 63294+ MX? mysql.kvm. (27)
^C
934 packets captured
1857 packets received by filter
0 packets dropped by kernel

Я попытался снизить приоритет записей AAAA в /etc/gai.conf

precedence ::ffff:0:0/96  100

Даже попытался отключить IPv6 полностью /etc/sysctl.conf:

# Disable IPv6
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1

Но запросы AAAA все еще отправляются, а разрешение имен становится невыносимо медленным.

Есть ли способ, чтобы libvirt или NetworkManager игнорировали или отвечали отрицательно на эти запросы, поэтому мне не нужно ждать, пока все запросы будут отключены, прежде чем использовать уже записанную запись A?


5
2017-11-06 10:28


Источник




Ответы:


Если форвардер настроен, dnsmasq пересылает все DNS-запросы, для которых нет явных данных. Это включает записи для настроенных статических DHCP-клиентов, у которых нет активной аренды, записи AAAA, если адреса IPv6 не определены явно и так далее.

Существует несколько способов избежать этого:

Не настраивать форвардер

Просто оставьте записи форадера в определении сети. Вероятно, нежелательно, если только виртуальная сеть не является действительно изолированы. Это единственная возможность, которую поддерживает libvirt (12/2014), AFAIK.

локальный домен в dnsmasq.conf

Настройте домен как «local» в dnsmasq:

 domain=local.net,192.168.10.0/24
 local=/local.net/
 local=/10.168.192.in-addr.arpa/

Теоретически это можно было бы сократить domain=local.net,192.168.10.0/24,local, но ошибка dnsmasq исправлена ​​только недавно приводит к сбою.

libvirt не поддерживает это. Чтобы использовать эту конфигурацию, вам необходимо настроить мост вручную в своей ОС и настроить сеть libvirt следующим образом:

   <network>
     <name>local</name>
     <forward mode='bridge'/>
     <bridge name='br0'/>
   </network>

Вам не нужно создавать виртуальную сеть libvirt вообще в этой конфигурации, просто используйте <interface 'type=bridge'> в файлах определения виртуальной машины.

auth zone в dnsmasq.conf

auth-zone параметр имеет аналогичный эффект local, Однако у меня есть другие последствия, которые я не утверждаю, чтобы полностью понять. Я полагаю, что эта конфигурация была бы желательной, если имена в виртуальной сети должны были быть разрешены извне.

domain=local.net
auth-zone=local.net

Эта настройка также не поддерживается libvirt, поэтому аналогичную процедуру настройки моста необходимо применять, как указано выше.


3
2017-12-17 16:52