Windows XP Windows 7 Windows 2003 Windows Vista Windows 綜合教學 Linux 系統教學
Windows 10 Windows 8 Windows 2008 Windows NT Windows Server 電腦軟體教學
您现在的位置: Windows教程網 >> Windows教程 >  >> Linux 系統教學 >> Linux 教學

Linux 判斷是否運行於虛擬機的完整偵測技術大全

編輯:Linux 教學

在雲端、容器、嵌入式開發等場景,程式常需感知自身是否運行於虛擬化環境,並識別具體 Hypervisor 類型(KVM、Xen、VMware、VirtualBox 等)。本文系統整理 /proc、/sys、CPUID、DMI/SMBIOS、ACPI 等多層面偵測手法,並提供可直接部署的 Python、C、Shell 檢測腳本。

一、容器/半虛擬化:直接讀取 /proc 特徵檔

虛擬化類型特徵路徑判斷邏輯
OpenVZ / Virtuozzo 容器/proc/vz 存在、/proc/bc 不存在容器內無 /proc/bc;Host 節點兩者皆有
Xen PV (Paravirtualized)/proc/xen/capabilities檔案大小 > 0 為 Dom0,= 0 為 DomU
User-Mode Linux (UML)/proc/cpuinfo包含 UML 關鍵字
LXC/Docker 容器/proc/1/environ、/.dockerenvPID 1 環境變數含 container= 或根目錄有 .dockerenv

Python 一鍵偵測腳本(支援 OpenVZ/Xen PV/UML)

#!/usr/bin/env python3
import os, sys

def main():
    if os.geteuid() != 0:
        print("WARN: 建議 root 執行以獲得完整資訊", file=sys.stderr)

    # OpenVZ
    if os.path.exists("/proc/vz"):
        print("openvz container" if not os.path.exists("/proc/bc") else "openvz host(node)")

    # Xen PV
    xen_cap = "/proc/xen/capabilities"
    if os.path.exists(xen_cap):
        print("xen dom0" if os.path.getsize(xen_cap) > 0 else "xen domU")

    # UML
    try:
        with open("/proc/cpuinfo") as f:
            if "UML" in f.read():
                print("uml")
    except OSError:
        pass

if __name__ == "__main__":
    main()

二、全虛擬化:CPUID 葉子 0x40000000 識別 Hypervisor 簽名

Intel/AMD 定義 CPUID leaf 0x40000000 回傳 Hypervisor 簽名(EBX/ECX/EDX 拼成 12 字元字串)。常見簽名對照:

Hypervisor簽名字串備註
Xen HVMXenVMMXenVMM
VMwareVMwareVMware
KVMKVMKVMKVMQEMU/KVM 預設
Microsoft Hyper-VMicrosoft Hv
Parallelslrpepyh vr實為 prl hyperv 反序
VirtualBoxVBoxVBoxVBox較新版本支援

C 語言偵測程式(GCC/Clang 通用)

/* detect_hv.c */
#include 
#include 
#include 

#define CPUID(in, a, b, c, d) \
    __asm__ volatile ( \
        "cpuid" \
        : "=a" (a), "=b" (b), "=c" (c), "=d" (d) \
        : "0" (in) \
    )

int main(void) {
    uint32_t eax, ebx, ecx, edx;
    char sig[13] = {0};

    CPUID(0x40000000, eax, ebx, ecx, edx);
    *(uint32_t*)(sig + 0) = ebx;
    *(uint32_t*)(sig + 4) = ecx;
    *(uint32_t*)(sig + 8) = edx;

    if (strncmp(sig, "XenVMMXenVMM", 12) == 0)       puts("xen hvm");
    else if (strncmp(sig, "VMwareVMware", 12) == 0)   puts("vmware");
    else if (strncmp(sig, "KVMKVMKVM", 12) == 0)      puts("kvm");
    else if (strncmp(sig, "Microsoft Hv", 12) == 0)   puts("hyper-v");
    else if (strncmp(sig, "VBoxVBoxVBox", 12) == 0)   puts("virtualbox");
    else                                               puts("bare metal / unknown");

    return 0;
}

編譯執行:gcc -o detect_hv detect_hv.c && ./detect_hv

三、桌面級虛擬機:DMI/SMBIOS 系統製造商欄位

# VirtualBox
dmidecode -s system-manufacturer   # → innotek GmbH
dmidecode -s system-product-name   # → VirtualBox

# VMware
dmidecode -s system-manufacturer   # → VMware, Inc.
dmidecode -s system-product-name   # → VMware Virtual Platform

# Hyper-V
dmidecode -s system-manufacturer   # → Microsoft Corporation
dmidecode -s system-product-name   # → Virtual Machine

# QEMU/KVM (預設)
dmidecode -s system-manufacturer   # → QEMU
dmidecode -s system-product-name   # → Standard PC (i440FX + PIIX, 1996)

腳本化判斷:

#!/bin/bash
vendor=$(dmidecode -s system-manufacturer 2>/dev/null | tr '[:upper:]' '[:lower:]')
case "$vendor" in
    *innotek*) echo "virtualbox";;
    *vmware*)  echo "vmware";;
    *microsoft*) echo "hyper-v";;
    *qemu*)    echo "kvm/qemu";;
    *)         echo "physical or unknown";;
esac

四、systemd 統一介面:systemd-detect-virt

systemd-detect-virt
# 輸出範例:kvm, vmware, xen, oracle, virtualbox, wsl, docker, lxc, openvz, qemu, uml, none

內部綜合上述所有機制,為現代 Linux 發布版首選標準工具。

五、容器內偵測宿主機虛擬化(嵌套虛擬化)

容器共享宿主機核心,/proc/cpuinfo、CPUID 反映宿主機狀態。結合 systemd-detect-virt --container 可區分「容器內」與「宿主機層」虛擬化類型。

六、常見誤區與最佳實踐

  1. 僅檢查 /proc/cpuinfo flags(如 hypervisor bit)不足以區分具體 Hypervisor。
  2. 嵌套虛擬化(KVM on KVM、VMware on Hyper-V)會導致 CPUID 簽名呈現最外層 Hypervisor,需結合 DMI 判斷內層。
  3. 權限不足:dmidecode、cpuid 指令需 root;容器需 --privileged 或 CAP_SYS_RAWIO。
  4. 建議策略:優先 systemd-detect-virt → 失敗則 CPUID → 再失敗則 DMI → 最後回退 /proc 特徵檔。

掌握多層次偵測技術,即可在自動化部署、授權驗證、效能調優、安全審計等場景精準識別執行環境,編寫更健壯的基礎設施代碼。

Copyright © Windows教程網 All Rights Reserved