Showing posts with label virsh. Show all posts
Showing posts with label virsh. Show all posts

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.

Wednesday, October 03, 2018

Creating and mounting a fileshare as a file in a KVM Windows guest

Yeah, the title is a mouthfull.

So, let's get it done.

  1. Create the disk, which is henceforth called foretest.iso. I made it to be 1G because, as the name says, it is a test.
    raub@vmhost:~$ dd if=/dev/zero of=foretest.iso bs=1G count=1
    1+0 records in
    1+0 records out
    1073741824 bytes (1.1 GB, 1.0 GiB) copied, 2.29044 s, 469 MB/s
    raub@vmhost:~$
    NOTE: Some people would complain that I am using the .iso extension for my image file instead of, say, .img. Well, this is my article; deal with it.
  2. Now let's feed it to the vm.
    raub@vmhost:~$ virsh attach-disk desktop dev/foretest.iso hda --type raw --mode readwrite                 
    error: No support for readwrite in command 'attach-disk'
    
    raub@vmhost:~$

    Well, I did not know my KVM host does not have attach-disk. I guess I need to use attach-device instead. But, we will need to use a config file to describe how we want the storage to look like. If it looks familiar, we have used attach-disk to mount a USB device, namely an APC UPS.

    So, here is the .xml file:

    cat > dev/foretest.xml << 'EOF'
    <disk type='file' device='disk'>
       <driver name='qemu' type='raw' cache='none'/>
       <source file='/home/raub/dev/foretest.iso'/>
    <target dev='hdc'/>
    </disk >
    EOF

    And here we are feeding it into the guest:

    raub@vmhost:~$ sudo virsh attach-device --config testdesktop dev/foretest.xml
    Device attached successfully
    
    raub@vmhost:~$

    So we should be able to go to the guest and see the drive waving at us, right? Er, not quite. it is being listed here

    <disk type='file' device='disk'>
    
          <source file='/home/raub/dev/foretest.iso'/>
          <target dev='vdd' bus='virtio'/>
          <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/>
       </disk>

    But not in the GUI thingie nor inside the guest. And, yes, I have 2 virtual CD drives in this guest.


On a second thought, maybe I am doing this wrong. You see, the --config option tells it to add the drive to the config file. Only way to enable that is to completely shut down the vm guest (rebooting is not enough) and then restart it. What if I use --live instead, which does the deed in real time, as if I just pop the computer on and add the drive to an unused sata port?

raub@vmhost:~$ sudo virsh attach-device --live testdesktop dev/foretest.xml
error: Failed to attach device from dev/foretest.xml
error: internal error unable to execute QEMU command '__com.redhat_drive_add': Device 'drive-virtio-disk3' could not be initialized

raub@vmhost:~$

I guess it does not like me to add hard drives to a running guest. We need to try something else.

Attempt #2: USB

What if we pretend our disk is really a removable device like a USB drive? We begin by rewriting our .xml file:

cat > dev/foretest.xml << 'EOF'
<disk type='file' device='disk'>
  <driver name='qemu' type='raw'/>
  <source file='/home/raub/dev/foretest.iso'/>
  <target dev='sdd' bus='usb'/>
</disk>
EOF

Now let's mount it:

raub@desktop:~$ sudo virsh attach-device --live testdesktop dev/foretest.xml
Device attached successfully

raub@desktop:~$

So far so good. Can our guest see it this time? When I use Windows Explorer (do notice I disabled one of the CD drives as I was doing something else between the last screen capture and this one) I do not see the drive there; I kinda expected Windows to say something like "Hey! You just connected an unformatted drive! I need to format it!" Oh well; there are more than one way to get this done:

There it is! And we can format it!

And then, we can put things into it.

Now, let's unmount it

raub@desktop:~$ sudo virsh detach-device --live testdesktop dev/foretest.xml
Device detached successfully

raub@desktop:~$

Now let's make it a physical drive!

Stupid question: since we pretend our foretest.iso file is a USB drive, can we make it a real USB drive? We would test that question by first grabbing a USB drive which is at least 1GB in size (I had a 16GB one doing nothing), which was mounted into my KVM host as /dev/sdh.And now we need to copy the file to the drive.

raub@desktop:~$ sudo dd if=dev/foretest.iso of=/dev/sdh
raub@desktop:~$

Then grab USB drive and then mount it in a windows physical desktop. And it will look just like how it looks in the testdesktop guest down to be able to write to it.

The next step will be to see if we can make it a system disk, a disk we can boot a computer from. But, that will be for another article.