List Linux KVM VM IP Address ?

Gabriel9999

Member
Joined
Mar 12, 2019
Messages
38
Reaction score
4
Credits
130
How do I find out an IP address of Linux KVM guest from Linux host itself? I wanted to ssh into KVM guest VM. How can I find the IP address of a KVM Virtual Machine Guest on a CentOS Linux 7.x server?
 


If you have the ip command, this should work (executed from inside the guest machine):
Code:
/sbin/ip route show
or with ifconfig:
Code:
ifconfig | grep 'inet[^6]'
But this is a problem with different answers on different platforms. And the outputs of the various tools seems to change occasionally. I made a script named localip which I use that's not perfect, but is pretty good at ferreting out the answer on most platforms that I have access to. I'll post it here.

localip
Code:
#!/bin/sh
die() { echo "ERROR: $*" 1>&2; exit 1; }

if which ip >/dev/null 2>&1; then
    # Expect: "default via <ip_address> dev eth0"
    DEVICE="$(ip route show | awk '/default via/{print $5;exit}')"
    test -z "$DEVICE"  &&  die "There is no default route"
    # Expect: "inet <ip_address>/<bits> brd <mask> scope global <device>"
    IP="$(ip address show | awk '/inet [0-9.]+\/.* '$DEVICE'/{print $2;exit}')"
    test -z "$IP"  &&  die "There is no default route"
    echo "${IP%/*}"

elif which ipconfig >/dev/null 2>&1; then   # Cygwin, MSYS2, Windows, ReactOS
    # Expect: " IPv4 Address. . . . : <address>"
    ipconfig | awk '/IPv4 Addr.*: /{sub(/\r/,""); print $NF}'
   #ipconfig | sed -n 's/\r//; s/ *IPv4 Add.*: //p'
   #ipconfig | sed -n '/Local Area Co/,/Subnet/{s/\r//; s/ *IPv*4* Add.*: //p}'

elif ! which netstat >/dev/null 2>&1; then
    die "Can't find ip, netstat or ipconfig"

else
    # Expect: "0.0.0.0 <gateway> 0.0.0.0  <flags>  0 0  0 <device>"
    #EVICE="$(netstat -nr | sed -n '/^0.0/s/.* //p')"
    DEVICE="$(netstat -nr | awk '/^0\.0\.0\.0/{print $NF;exit}')"
    GATEWAY="$(netstat -nr | awk '/^0\.0\.0\.0/{print $2;exit}')"
    # Expect: "default  <gateway>  <flags>  <refs> <use> <mtu> <interface>"
    if [ -z "$DEVICE" ]; then
        DEVICE="$(netstat -nr | awk '/^default [^:]*$/{print $NF;exit}')"
        GATEWAY="$(netstat -nr | awk '/^default [^:]*$/{print $2;exit}')"
    fi
    test -z "$DEVICE"  &&  die "There is no default route"

    if test -x /sbin/ifconfig; then
        # Expect: "  inet <ip_address> netmask <mask> broadcast <addr>"
        #     or: "  inet addr:<ip_address> Bcast:<addr> Mask:<mask>"
        #     or: "  inet <ip_address>/<bits> broadcast <addr> flags 0x0"
        /sbin/ifconfig $DEVICE 2>/dev/null |\
                    awk '/inet /{sub(/addr:/,""); sub(/\/.*/,""); print $2}'

    else
        #echo "DEVICE=$DEVICE  GATEWAY=$GATEWAY"
        netstat -nr | awk "/$GATEWAY|\//{next}
                           /${DEVICE}\$/{print \$1 \"  (?)\";exit}"
    fi
fi
 
arp -e | grep $mac | grep -o -P "^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"

You used arp. Very good. I haven't used arp in so long that I forgot it existed.

Here's my version using GNU awk. On my system, arp -e doesn't print the IP addresses, so I use arp -a.

All my domains were created with qemu:///system, so I have to use the commented version of the C variable. You can just remove it if you don't need it.

Of course, this is run on the host, outside the virtual machine.

Code:
#!/bin/bash
VMNAME="$1"
C=''      # C='--connect qemu:///system'
for mac in $(sudo virsh $C domiflist "$VMNAME" | gawk 'NR>2{print $5}')
do
    /usr/sbin/arp -a | gawk /$mac/'{gsub(/\(|\)/,""); print $1 " " $2}'
done
 
  • Open the terminal app or login using ssh to host server.
  • Get the network list: virsh net-list.
  • Type the command: virsh net-dhcp-leases networkNameHere.
 

Members online


Top