Monday, December 31, 2018

Finding the IP address for a KVM guest (in bridge mode)

I have a Windows 10 vm guest, testdesktop, in my KVM vm host I want to remote in.

raub@vmhost:~$ virsh list
 Id    Name                           State
----------------------------------------------------
 1     desktop                        running
 16    testdesktop                    running

raub@vmhost:~$

Thing is I did not set it up to support VNC as console, so I cannot just do virsh vncdisplay testdesktop and go from there. Well, I really just want to connect to it using RDP because that is what I want to do. But to do that I need to know its hostname or IP. I thought it was testdesktop.in.example.com, but I am wrong. So, what can I do?

As far as I know (if I am wrong, do let me know!), I cannot get the IP of a guest directly using virsh unless KVM is acting as the DCHP server. In my case, that is not the case; I am using the domain's DHCP and DNS servers since this guest is in bridge mode:

virsh dumpxml testdesktop
[...[
    &linterface type='bridge'>
      &lmac address='c0:ff:ee:83:eb:ed'/>
      &lsource bridge='br0'/>
      <arget dev='vnet1'/>
      &lmodel type='rtl8139'/>
      <alias name='net0'/>

I found an interesting thread that does offer great suggestions for finding the IP address of a KVM Virtual Machine. Let's see if any of them will help me.

  1. Use my ARP table. The idea here is that since I am in the vm host, vmhost (yes, that is its name, really) testdesktop is a guest of, vmhost's ARP table should see it from time to time. All I need is the MAC address, which I have thanks to previously runnning virsh dumpxml testdesktop:

    raub@vmhost:~$ arp -n|grep c0:ff:ee:83:eb:ed
    raub@vmhost:~$

    Hmmm, don't know why but it ain't there. Next?

  2. Nmap. Yes, it's main use is network security scanner, but Nmap can be used as a glorified ping, where it returns amongst other things the MAC address. Let me show you what I mean by running it against the vmhost (I will be using desktop for that). First we cheat since we know the IP address:

    raub@desktop:/tmp$ sudo nmap -sn -n 192.168.10.19
    
    Starting Nmap 7.01 ( https://nmap.org ) at 2018-12-31 10:45 EST
    Nmap scan report for 192.168.10.19
    Host is up (0.000082s latency).
    MAC Address: BC:5F:F4:54:D7:8D (ASRock Incorporation)
    Nmap done: 1 IP address (1 host up) scanned in 0.22 seconds
    raub@desktop:/tmp$

    Then we use the MAC address to find the IP.

    raub@desktop:/tmp$ sudo nmap -sn 192.168.10.* | grep -B 3 BC:5F:F4:54:D7:8D
    Nmap scan report for vmhost.in.example.com (192.168.10.19)
    Host is up (-0.10s latency).
    MAC Address: BC:5F:F4:54:D7:8D (ASRock Incorporation)
    raub@desktop:/tmp$
    Note: If you want to look cooler, use 192.168.10.0/24 instead of 192.168.10.*. Also, grep -i helps to cover our asses.

    Looks like we have a plan here. So, let's look for testdesktop:

    raub@desktop:~$ nmap -sn 192.168.10.0/24 | grep -i c0:ff:ee:83:eb:ed -B 3
    raub@desktop:~$

    All I got back was was a nice cup of nothing. Next!

  3. What about virsh domifaddr?. Not holding my breath. Remember testdesktop is in bridge mode. But, just to be sure:

    raub@vmhost:~$ virsh domifaddr testdesktop
     Name       MAC address          Protocol     Address
    -------------------------------------------------------------------------------
    raub@vmhost:~$
  4. Well, the arp command should have been deprecated. What about ip neighbour? Er, nope.

    raub@vmhost:~$ ip neighbour | grep -i c0:ff:ee:83:eb:ed
    raub@vmhost:~$
  5. You are making this too complicated! Why not login to the console of this guest and then type ipconfig since it is a Windows box? What if vmhost is run headless? So, I would have to install a windows manager in vmhost, then VNC with all the extra cruft that GUIs require just so I can vnc into it and then use the gui console thingie to get into testdesktop to type one command? Can you say overkill and convoluted? I think we can do better thank you verymuch.

  6. OK, smartguy. Since you are making an article you have found a solution. What did you do?. Well, I like solutions that do not require me to keep installing extra programs; note I used nmap in desktop as it is where I run it. Here is my thought process: vmhost should have the network traffic for testdesktop since it is his guest. Why not then look for traffic matching its MAC address? We can do that using tcpdump which is there to begin with.

    Since I am lazy, I told it to probulate tcpdump the physical network interface, eno1 instead of the bridge I created for KVM. This way I cannot use the excuse that I missed something.

    raub@vmhost:~$ sudo tcpdump -i eno1 | grep c0:ff:ee:83:eb:ed
    [sudo] password for raub:
    tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
    listening on eno1, link-type EN10MB (Ethernet), capture size 262144 bytes
    23:19:09.835884 IP testdesktop.dhcp.example.com.68 > ns.in.example.com.67: BOOTP/DHCP, Request from c0:ff:ee:83:eb:ed (oui Unknown), length 327
    00:49:09.846907 IP testdesktop.dhcp.example.com.68 > ns.in.example.com.67: BOOTP/DHCP, Request from c0:ff:ee:83:eb:ed (oui Unknown), length 327
    02:19:09.857254 IP testdesktop.dhcp.example.com.68 > ns.in.example.com.67: BOOTP/DHCP, Request from c0:ff:ee:83:eb:ed (oui Unknown), length 327
    03:49:09.868670 IP testdesktop.dhcp.example.com.68 > ns.in.example.com.67: BOOTP/DHCP, Request from c0:ff:ee:83:eb:ed (oui Unknown), length 327
    05:19:09.882066 IP testdesktop.dhcp.example.com.68 > ns.in.example.com.67: BOOTP/DHCP, Request from c0:ff:ee:83:eb:ed (oui Unknown), length 327
    06:49:09.895852 IP testdesktop.dhcp.example.com.68 > ns.in.example.com.67: BOOTP/DHCP, Request from c0:ff:ee:83:eb:ed (oui Unknown), length 327
    ^C2384605 packets captured
    2385524 packets received by filter
    914 packets dropped by kernel
    186 packets dropped by interface
    
    raub@vmhost:~$

    So the guest is seen by DNS as testdesktop.dhcp.example.com (I don't want to know why), from which I can get the IP if I so want.

The beauty of the above solution is that it did not really require any special feature from KVM, meaning it should work with VirtualBox, ESXi, HyperV, or even Xen. I like generic solutions.