51工具盒子

依楼听风雨
笑看云卷云舒,淡观潮起潮落

如何检测Linux Guest VM使用的哪种虚拟化技术

如何检测Linux Guest VM使用的哪种虚拟化技术_https://www.tiejiang.org_Linux安全运维_第1张

写在前面的话 {#i}

如果我有一台基于云的虚拟机,并且运行了Ubuntu或CentOS的Linux服务器系统,而这些设备可能是虚拟化的,也可能不是虚拟化的,那我们应该如何去判断这台Linux Guest系统设备使用的是哪种虚拟化技术(VMWARE/ KVM/ XEN/ VirtualBox/ Container/lxc/Hyper-V等等)呢?那我们如何才能识别一台CentOS 7 Linux VPS所使用的虚拟化技术类型呢?

技术分析 {#i-2}

我们需要使用virt-what程序(一个Shell脚本)来检测目标设备系统所使用的虚拟化技术类型,它可以打印出每一条关于目标设备虚拟化技术的相关信息。在这篇文章中,我们将介绍如何去判断Linux Guest VM虚拟化技术类型。

判断Linux Guest VM虚拟化技术类型 {#linux-guest-vm}

正如我们刚才说的,我们需要使用virt-what Linux命令来判断一个程序当前是否在一台虚拟机设备上运行。该脚本支持各种虚拟机管理程序,接下来,我们看看如何在不同的Linux发行版系统中安装virt-what。

Debian或Ubuntu Linux安装

首先,运行下列apt命令/apt-get命令:

[sourcecode language="plain"]
$ sudo apt-get install virt-what
[/sourcecode]

或者

[sourcecode language="plain"]
$ sudo apt install virt-what
[/sourcecode]

如何检测Linux Guest VM使用的哪种虚拟化技术_https://www.tiejiang.org_Linux安全运维_第2张

在RHEL/CentOS/Scientific Linux VM中安装virt-what

我们可以使用yum命令完成安装:

[sourcecode language="plain"]
$ sudo yum install virt-what
[/sourcecode]

如何检测Linux Guest VM使用的哪种虚拟化技术_https://www.tiejiang.org_Linux安全运维_第3张

Fedora Linux VM安装virt-what来检测当前环境是否为虚拟机环境

执行dnf命令:

[sourcecode language="plain"]
$ sudo dnf install virt-what
[/sourcecode]

Suse/OpenSUSE安装

运行zypper命令:

[sourcecode language="plain"]
sudo zypper in virt-what
[/sourcecode]

如何检测Linux Guest VM使用的哪种虚拟化技术_https://www.tiejiang.org_Linux安全运维_第4张

判断远程服务器是否为虚拟机环境 {#i-3}

我们可以直接输入并运行下列命令:

[sourcecode language="plain"]
$ $ sudo virt-what
xen
xen-domU
[/sourcecode]

输出结果

[sourcecode language="plain"]
$ $ sudo virt-what
kvm
[/sourcecode]

其他输出结果

[sourcecode language="plain"]
$ $ sudo virt-what
lxc
[/sourcecode]

下面给出aws反回结果

[sourcecode language="plain"]
$ sudo virt-what
xen
xen-hvm
aws
[/sourcecode]

如何检测Linux Guest VM使用的哪种虚拟化技术_https://www.tiejiang.org_Linux安全运维_第5张

其他可能的值 {#i-4}

[sourcecode language="plain"]
1、hyperv : 这是微软的Hyper-V管理程序;

2、parallels : 访客用户正在Parallels虚拟平台(Parallels Desktop、Parallels Server)中运行;

3、powervm_lx86 : 访客用户正在IBM powervm lx86 Linux/x86模拟器中运行;

4、qemu : 这是使用软件模拟技术的QEMU管理程序;

5、virtualpc : 访客用户正在微软VirualPC上运行;

6、xen-hvm : 这是一个Xen Guest完全虚拟化平台(HVM);

7、uml : 这是一个用户模式Linux(UML)客户机;

8、openvz : 访客用户正在OpenVZ或Virtuozzo容器中运行;

9、linux_vserver : 此进程正在Linux VServer容器中运行;

10、ibm_systemz : 这是一个IBM SystemZ硬件分区系统;
[/sourcecode]

如果没有任何输出结果,那意味着我们的程序可能是在裸机上运行的,或者程序是在一种我们无法检测到的虚拟机系统中运行的。

检测脚本源代码 {#i-5}

下面给出的是脚本的源代码:

[sourcecode language="plain"]
#!/bin/sh -

virt-what. Generated from virt-what.in by configure.

Copyright (C) 2008-2017 Red Hat Inc.

This program is free software; you can redistribute it and/or modify

it under the terms of the GNU General Public License as published by

the Free Software Foundation; either version 2 of the License, or

(at your option) any later version.

This program is distributed in the hope that it will be useful,

but WITHOUT ANY WARRANTY; without even the implied warranty of

MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the

GNU General Public License for more details.

You should have received a copy of the GNU General Public License

along with this program; if not, write to the Free Software

Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

'virt-what' tries to detect the type of virtualization being

used (or none at all if we're running on bare-metal). It prints

out one or more lines each being a 'fact' about the virtualization.

Please see also the manual page virt-what(1).

This script should be run as root.

The following resources were useful in writing this script:

. http://dmo.ca/blog/detecting-virtualization-on-linux/

Do not allow unset variables, and set defaults.

set -u

root=''

skip_qemu_kvm=false

skip_lkvm=false

VERSION="1.20"

have_cpuinfo () {

test -e "${root}/proc/cpuinfo"

}

use_sysctl() {

Lacking /proc, on some systems sysctl can be used instead.

OS=$(uname) || fail "failed to get operating system name"

[ "$OS" = "OpenBSD" ]

}

fail () {

echo "virt-what: $1" >&2

exit 1

}

usage () {

echo "virt-what [options]"

echo "Options:"

echo " --help Display this help"

echo " --version Display version and exit"

exit 0

}

Handle the command line arguments, if any.

while test $# -gt 0; do

case "$1" in

--help) usage ;;

--test-root=*)

Deliberately undocumented: used for 'make check'.

root=$(echo "$1" | sed 's/.*=//')

shift 1

test -z "$root" && fail "--test-root option requires a value"

;;

-v|--version) echo "$VERSION"; exit 0 ;;

--) shift; break ;;

*) fail "unrecognized option '$1'";;

esac

done

test $# -gt 0 && fail "extra operand '$1'"

Add /sbin and /usr/sbin to the path so we can find system

binaries like dmidecode.

Add /usr/libexec to the path so we can find the helper binary.

prefix=/usr/local

exec_prefix=${prefix}

PATH="${root}${exec_prefix}/libexec:${root}/sbin:${root}/usr/sbin:${PATH}"

export PATH

Check we're running as root.

EFFUID=$(id -u) || fail "failed to get current user id"

if [ "x$root" = "x" ] && [ "$EFFUID" -ne 0 ]; then

fail "this script must be run as root"

fi

Try to locate the CPU-ID helper program

CPUID_HELPER=$(which virt-what-cpuid-helper 2>/dev/null)

if [ -z "$CPUID_HELPER" ] ; then

fail "virt-what-cpuid-helper program not found in \$PATH"

fi

Many fullvirt hypervisors give an indication through CPUID. Use the

helper program to get this information.

cpuid=$(virt-what-cpuid-helper)

Check for various products in the BIOS information.

Note that dmidecode doesn't exist on all architectures. On the ones

it does not, then this will return an error, which is ignored (error

message redirected into the $dmi variable).

dmi=$(LANG=C dmidecode 2>&1)

Architecture.

Note for the purpose of testing, we only call uname with -m option.

arch=$(uname -m | sed -e 's/i.86/i386/' | sed -e 's/arm.*/arm/')

Check for VMware.

cpuid check added by Chetan Loke.

if [ "$cpuid" = "VMwareVMware" ]; then

echo vmware

elif echo "$dmi" | grep -q 'Manufacturer: VMware'; then

echo vmware

fi

Check for Hyper-V.

http://blogs.msdn.com/b/sqlosteam/archive/2010/10/30/is-this-real-the-metaphysics-of-hardware-virtualization.aspx

if [ "$cpuid" = "Microsoft Hv" ]; then

echo hyperv

fi

Check for VirtualPC.

The negative check for cpuid is to distinguish this from Hyper-V

which also has the same manufacturer string in the SM-BIOS data.

if [ "$cpuid" != "Microsoft Hv" ] &&

echo "$dmi" | grep -q 'Manufacturer: Microsoft Corporation'; then

echo virtualpc

fi

Check for VirtualBox.

Added by Laurent Léonard.

if echo "$dmi" | grep -q 'Manufacturer: innotek GmbH'; then

echo virtualbox

fi

Check for bhyve.

if [ "$cpuid" = "bhyve bhyve " ]; then

echo bhyve

elif echo "$dmi" | grep -q "Vendor: BHYVE"; then

echo bhyve

fi

Check for OpenVZ / Virtuozzo.

Added by Evgeniy Sokolov.

/proc/vz - always exists if OpenVZ kernel is running (inside and outside

container)

/proc/bc - exists on node, but not inside container.

if [ -d "${root}/proc/vz" -a ! -d "${root}/proc/bc" ]; then

echo openvz

fi

Check for LXC containers

http://www.freedesktop.org/wiki/Software/systemd/ContainerInterface

Added by Marc Fournier

if [ -e "${root}/proc/1/environ" ] &&

cat "${root}/proc/1/environ" | tr '\000' '\n' | grep -Eiq '^container='; then

echo lxc

fi

Check for Linux-VServer

if test -e "${root}/proc/self/status" \

&& cat "${root}/proc/self/status" | grep -q "VxID: [0-9]*"; then

echo linux_vserver

if grep -q "VxID: 0$" "${root}/proc/self/status"; then

echo linux_vserver-host

else

echo linux_vserver-guest

fi

fi

Check for UML.

Added by Laurent Léonard.

if have_cpuinfo && grep -q 'UML' "${root}/proc/cpuinfo"; then

echo uml

fi

Check for IBM PowerVM Lx86 Linux/x86 emulator.

if have_cpuinfo && grep -q '^vendor_id.*PowerVM Lx86' "${root}/proc/cpuinfo"

then

echo powervm_lx86

fi

Check for Hitachi Virtualization Manager (HVM) Virtage logical partitioning.

if echo "$dmi" | grep -q 'Manufacturer.*HITACHI' &&

echo "$dmi" | grep -q 'Product.* LPAR'; then

echo virtage

fi

Check for IBM SystemZ.

if have_cpuinfo && grep -q '^vendor_id.*IBM/S390' "${root}/proc/cpuinfo"; then

echo ibm_systemz

if [ -f "${root}/proc/sysinfo" ]; then

if grep -q 'VM.*Control Program.*KVM/Linux' "${root}/proc/sysinfo"; then

echo ibm_systemz-kvm

elif grep -q 'VM.*Control Program.*z/VM' "${root}/proc/sysinfo"; then

echo ibm_systemz-zvm

elif grep -q '^LPAR' "${root}/proc/sysinfo"; then

echo ibm_systemz-lpar

else

This is unlikely to be correct.

echo ibm_systemz-direct

fi

fi

fi

Check for Parallels.

if echo "$dmi" | grep -q 'Vendor: Parallels'; then

echo parallels

skip_qemu_kvm=true

fi

Check for oVirt/RHEV.

if echo "$dmi" | grep -q 'Manufacturer: oVirt'; then

echo ovirt

fi

if echo "$dmi" | grep -q 'Product Name: RHEV Hypervisor'; then

echo rhev

fi

Check for Xen.

if [ "$cpuid" = "XenVMMXenVMM" ] &&

! echo "$dmi" | grep -q 'No SMBIOS nor DMI entry point found, sorry'; then

echo xen; echo xen-hvm

skip_qemu_kvm=true

elif [ -d "${root}/proc/xen" ]; then

echo xen

if grep -q "control_d" "${root}/proc/xen/capabilities" 2>/dev/null; then

echo xen-dom0

else

echo xen-domU

fi

skip_qemu_kvm=true

skip_lkvm=true

elif [ -f "${root}/sys/hypervisor/type" ] &&

grep -q "xen" "${root}/sys/hypervisor/type"; then

Ordinary kernel with pv_ops. There does not seem to be

enough information at present to tell whether this is dom0

or domU. XXX

echo xen

elif [ "$arch" = "arm" ] || [ "$arch" = "aarch64" ]; then

if [ -d "${root}/proc/device-tree/hypervisor" ] &&

grep -q "xen" "${root}/proc/device-tree/hypervisor/compatible"; then

echo xen

skip_qemu_kvm=true

skip_lkvm=true

fi

elif [ "$arch" = "ia64" ]; then

if [ -d "${root}/sys/bus/xen" -a ! -d "${root}/sys/bus/xen-backend" ]; then

PV-on-HVM drivers installed in a Xen guest.

echo xen

echo xen-hvm

else

There is no virt leaf on IA64 HVM. This is a last-ditch

attempt to detect something is virtualized by using a

timing attack.

virt-what-ia64-xen-rdtsc-test > /dev/null 2>&1

case "$?" in

  1. ;; # not virtual

  2. Could be some sort of virt, or could just be a bit slow.

echo virt

esac

fi

fi

Check for QEMU/KVM.

Parallels exports KVMKVMKVM leaf, so skip this test if we've already

seen that it's Parallels. Xen uses QEMU as the device model, so

skip this test if we know it is Xen.

if ! "$skip_qemu_kvm"; then

if [ "$cpuid" = "KVMKVMKVM" ]; then

echo kvm

elif [ "$cpuid" = "TCGTCGTCGTCG" ]; then

echo qemu

skip_lkvm=true

elif echo "$dmi" | grep -q 'Product Name: KVM'; then

echo kvm

skip_lkvm=true

elif echo "$dmi" | grep -q 'Manufacturer: QEMU'; then

The test for KVM above failed, so now we know we're

not using KVM acceleration.

echo qemu

skip_lkvm=true

elif [ "$arch" = "arm" ] || [ "$arch" = "aarch64" ]; then

if [ -d "${root}/proc/device-tree" ] &&

ls "${root}/proc/device-tree" | grep -q "fw-cfg"; then

We don't have enough information to determine if we're

using KVM acceleration or not.

echo qemu

skip_lkvm=true

fi

elif [ -d ${root}/proc/device-tree/hypervisor ] &&

grep -q "linux,kvm" /proc/device-tree/hypervisor/compatible; then

We are running as a spapr KVM guest on ppc64

echo kvm

skip_lkvm=true

elif use_sysctl; then

SmartOS KVM

product=$(sysctl -n hw.product)

if echo "$product" | grep -q 'SmartDC HVM'; then

echo kvm

fi

else

This is known to fail for qemu with the explicit -cpu

option, since /proc/cpuinfo will not contain the QEMU

string. QEMU 2.10 added a new CPUID leaf, so this

problem only triggered for older QEMU

if have_cpuinfo && grep -q 'QEMU' "${root}/proc/cpuinfo"; then

echo qemu

fi

fi

fi

if ! "$skip_lkvm"; then

if [ "$cpuid" = "LKVMLKVMLKVM" ]; then

echo lkvm

elif [ "$arch" = "arm" ] || [ "$arch" = "aarch64" ]; then

if [ -d "${root}/proc/device-tree" ] &&

grep -q "dummy-virt" "${root}/proc/device-tree/compatible"; then

echo lkvm

fi

fi

fi

Check for Docker.

if [ -f "${root}/.dockerinit" ]; then

echo docker

fi

Check ppc64 lpar, kvm or powerkvm

example /proc/cpuinfo line indicating 'not baremetal'

platform : pSeries

example /proc/ppc64/lparcfg systemtype line

system_type=IBM pSeries (emulated by qemu)

if [ "$arch" = "ppc64" ] || [ "$arch" = "ppc64le" ] ; then

if have_cpuinfo && grep -q 'platform.**pSeries' "${root}/proc/cpuinfo"; then

if grep -q 'model.*emulated by qemu' "${root}/proc/cpuinfo"; then

echo ibm_power-kvm

else

Assume LPAR, now detect shared or dedicated

if grep -q 'shared_processor_mode=1' "${root}/proc/ppc64/lparcfg"; then

echo ibm_power-lpar_shared

else

echo ibm_power-lpar_dedicated

fi

detect powerkvm?

fi

fi

fi

Check for OpenBSD/VMM

if [ "$cpuid" = "OpenBSDVMM58" ]; then

echo vmm

fi

Check for LDoms

if [ "${arch#sparc}" != "$arch" ] && [ -e "${root}/dev/mdesc" ]; then

echo ldoms

if [ -d "${root}/sys/class/vlds/ctrl" ] && \

[ -d "${root}/sys/class/vlds/sp" ]; then

echo ldoms-control

else

echo ldoms-guest

fi

MDPROP="${root}/usr/lib/ldoms/mdprop.py"

if [ -x "${MDPROP}" ]; then

if [ -n "$($MDPROP -v iodevice device-type=pciex)" ]; then

echo ldoms-root

echo ldoms-io

elif [ -n "$($MDPROP -v iov-device vf-id=0)" ]; then

echo ldoms-io

fi

fi

fi

Check for AWS.

AWS on Xen.

if echo "$dmi" | grep -q 'Version: [0-9]\.[0-9]\.amazon'; then

echo aws

AWS on baremetal or KVM.

elif echo "$dmi" | grep -q 'Vendor: Amazon EC2'; then

echo aws

fi
[/sourcecode]

如何使用dmidecode命令来寻找相同的信息 {#dmidecode}

配合Bash for循环并使用dmidecode命令判断目标虚拟化技术:

[sourcecode language="plain"]
for i in system-manufacturer system-product-name
do
sudo dmidecode -s $i
done
[/sourcecode]

样本输出

[sourcecode language="plain"]
Red Hat

KVM
[/sourcecode]

其他用来判断虚拟化技术的命令 {#i-6}

我们还可以使用systemd-detect-virt命令来检测虚拟化环境:

[sourcecode language="plain"]
systemd-detect-virt
[/sourcecode]

如何检测Linux Guest VM使用的哪种虚拟化技术_https://www.tiejiang.org_Linux安全运维_第6张

资源获取 {#i-7}

1、virt-what:【点我获取

2、Bash for循环:【参考文档

3、yum命令:【参考文档

4、apt命令:【参考文档

5、apt-get命令:【参考文档

赞(1)
未经允许不得转载:工具盒子 » 如何检测Linux Guest VM使用的哪种虚拟化技术