Bug 1910621

Summary: The hostname in one of the lease will disappear after libvirtd restart
Product: Red Hat Enterprise Linux 8 Reporter: yalzhang <yalzhang>
Component: dnsmasqAssignee: Petr Menšík <pemensik>
Status: CLOSED WONTFIX QA Contact: rhel-cs-infra-services-qe <rhel-cs-infra-services-qe>
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: 8.4Keywords: Triaged
Target Milestone: rc   
Target Release: 8.0   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of:
: 1978659 1978718 (view as bug list) Environment:
Last Closed: 2022-06-24 07:27:29 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On:    
Bug Blocks: 1978659, 1978718    
Attachments:
Description Flags
dnsmasq lease update on hostname reset none

Description yalzhang@redhat.com 2020-12-24 10:15:21 UTC
Description of problem:
The hostname in one of the lease will disappear after libvirtd restart

Version-Release number of selected component (if applicable):
dnsmasq-2.79-14.el8.x86_64

How reproducible:
100%

Steps to Reproduce:
1. prepare the default network as below:# virsh net-dumpxml default 
<network>
  <name>default</name>
  <uuid>0e9076a0-ea00-41f6-9c4f-12c38bdf008f</uuid>
  <forward mode='nat'>
    <nat>
      <port start='1024' end='65535'/>
    </nat>
  </forward>
  <bridge name='virbr0' stp='on' delay='0'/>
  <mac address='52:54:00:6e:27:85'/>
  <ip address='192.168.122.1' netmask='255.255.255.0'>
    <dhcp>
      <range start='192.168.122.2' end='192.168.122.254'/>
      <host mac='52:54:00:a4:6f:91' ip='192.168.122.3'/>
    </dhcp>
  </ip>
</network>

2. prepare a vm with 2 interfaces, both of them are connected to the default network, and one of the interface has mac address as  '52:54:00:a4:6f:91', and set the hostname of the vm as "test"
3.install the libvirt-nss package and edit the file "/etc/nsswitch.conf" to add "libvirt" in hosts entry:# cat /etc/nsswitch.conf | grep hosts
hosts:      files libvirt dns myhostname
4. start the vm, after the vm boot and interface initialized, check on host:# virsh net-dhcp-leases default 
 Expiry Time           MAC address         Protocol   IP address           Hostname   Client ID or DUID
------------------------------------------------------------------------------------------------------------
 2020-12-24 06:07:27   52:54:00:83:aa:39   ipv4       192.168.122.123/24   test       01:52:54:00:83:aa:39
 2020-12-24 06:07:27   52:54:00:a4:6f:91   ipv4       192.168.122.3/24     test       01:52:54:00:a4:6f:91

5. restart libvirtd and check again, the hostname will disappear in one of the lease record.# systemctl restart libvirtd 
# virsh net-dhcp-leases default 
 Expiry Time           MAC address         Protocol   IP address           Hostname   Client ID or DUID
------------------------------------------------------------------------------------------------------------
 2020-12-24 06:07:27   52:54:00:83:aa:39   ipv4       192.168.122.123/24   -          01:52:54:00:83:aa:39
 2020-12-24 06:07:27   52:54:00:a4:6f:91   ipv4       192.168.122.3/24     test       01:52:54:00:a4:6f:91

# cat /var/lib/libvirt/dnsmasq/virbr0.status 
[
  {
    "ip-address": "192.168.122.3",
    "mac-address": "52:54:00:a4:6f:91",
    "hostname": "test",
    "client-id": "01:52:54:00:a4:6f:91",
    "expiry-time": 1608808047
  },
  {
    "ip-address": "192.168.122.123",
    "mac-address": "52:54:00:83:aa:39",
    "client-id": "01:52:54:00:83:aa:39",
    "expiry-time": 1608808047
  }
]


Actual results:
The hostname in one of the lease will disappear after libvirtd restart

Expected results:
it should not disappear

Additional info:
libvirt developer has analysed the issue, the details can be found here: https://bugzilla.redhat.com/show_bug.cgi?id=1908053#c8 and #c9

the config file content:
# cat /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
pid-file=/run/libvirt/network/default.pid
except-interface=lo
bind-dynamic
interface=virbr0
dhcp-range=192.168.122.2,192.168.122.254,255.255.255.0
dhcp-no-override
dhcp-authoritative
dhcp-lease-max=253
dhcp-hostsfile=/var/lib/libvirt/dnsmasq/default.hostsfile
addn-hosts=/var/lib/libvirt/dnsmasq/default.addnhosts

# cat /var/lib/libvirt/dnsmasq/default.hostsfile
52:54:00:a4:6f:91,192.168.122.3

Comment 1 Petr Menšík 2021-07-01 13:23:34 UTC
It seems intended behaviour is not well specified anywhere in manual page. lease_set_hostname function in lease.c iterates over previous leases, calling kill_name(lease_tmp) on previous name instance with the same name. Excluding cases when hostname was set from configuration, which was unset according to example. One of hosts set address and IP pair, but hostname were dynamically set.

There seems to be mismatch of checking runtime, which allows both machines with the same name to exist. But when loaded, different checks are done on leases, last loaded one cancels previous name in case of conflict. No clear indication what exactly the behaviour should be. But clearly it should not make difference between runtime name management and startup loading management, results should be the same.

Note: libvirt gui manager does not allow two instances named the same name.

Comment 2 Petr Menšík 2021-07-01 13:54:04 UTC
This issue is still present even on the latest release 2.85 in Fedora. Tested it with Fedora 34 Live CD image, which sets hostname to "localhost-live". It allows both instances to have the same name when running. But after restart of libvirtd, only one record in virbr0.status file has "hostname": "localhost-live". After restart of those VMs, it will again have both hostnames set in status.


  {
    "ip-address": "192.168.122.102",
    "mac-address": "52:54:00:c4:a7:af",
    "hostname": "localhost-live",
    "client-id": "01:52:54:00:c4:a7:af",
    "expiry-time": 1625150434
  },
  {
    "ip-address": "192.168.122.151",
    "mac-address": "52:54:00:04:17:7d",
    "hostname": "localhost-live",
    "client-id": "01:52:54:00:04:17:7d",
    "expiry-time": 1625150441
  }

But at the same time, runtime status is different, it already replaced name with latest client.

$ dig @vhost.vm localhost-live.

; <<>> DiG 9.16.18-RH <<>> @vhost.vm localhost-live.
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 17470
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;localhost-live.			IN	A

;; ANSWER SECTION:
localhost-live.		0	IN	A	192.168.122.151

$ dig @vhost.vm -x 192.168.122.151

; <<>> DiG 9.16.18-RH <<>> @vhost.vm -x 192.168.122.151
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 24930
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;151.122.168.192.in-addr.arpa.	IN	PTR

;; ANSWER SECTION:
151.122.168.192.in-addr.arpa. 0	IN	PTR	localhost-live.vm.

$ dig @vhost.vm -x 192.168.122.102

; <<>> DiG 9.16.18-RH <<>> @vhost.vm -x 192.168.122.102
; (1 server found)
;; global options: +cmd
;; connection timed out; no servers could be reached

I consider it a proof two machines of the same name are not intentionally supported.

I consider it strange feature, because it allows stealing registered name of existing client, still connected and with active lease. Just by requesting the same hostname as them. If anyone is using that name to connect to correct host, it is quite easy to impersonate original host. The only thing to protect the name is to register also lease name in configuration.

Comment 3 Petr Menšík 2021-07-02 08:53:44 UTC
Created attachment 1797071 [details]
dnsmasq lease update on hostname reset

This patch does not allow two hostnames to have the same name in leases. Instead it fixes dnsmasq to run lease script also for lease with removed hostname from leases. If a new machine requests the same name, the last one gets the name and previous name is reset. I therefore matches state in DNS, which behaved this way even before.

It makes behaviour always the same, before or after libvirtd.service. As soon as new machine with the name starts, it moves hostname from previous to new record. /var/lib/libvirt/dnsamsq/virbrX.status is updated right away to reflect real state of leases.

Comment 4 Petr Menšík 2021-07-02 14:53:23 UTC
Posted on upstream mailing list:
https://lists.thekelleys.org.uk/pipermail/dnsmasq-discuss/2021q3/015237.html

Comment 8 RHEL Program Management 2022-06-24 07:27:29 UTC
After evaluating this issue, there are no plans to address it further or fix it in an upcoming release.  Therefore, it is being closed.  If plans change such that this issue will be fixed in an upcoming release, then the bug can be reopened.