服务器身份之谜:一键脚本,看清物理机与虚拟机的真面目

缘起:一个让运维人员夜不能寐的问题
"这到底是不是虚拟机?"
这个问题看似简单,却困扰着无数运维工程师、系统管理员和开发人员。记得那是一个周五的深夜,我们正在为某个关键业务系统进行性能调优。监控显示某台数据库服务器响应异常,我本能地开始检查硬件状态——内存频率、磁盘队列、CPU缓存……
直到三个小时后,一位同事偶然发现:这特么根本就是一台虚拟机!我们一直在用排查物理机的方法去诊断虚拟机的问题,就像用修汽车的工具去修飞机一样荒谬。
那一刻我意识到,必须有一个可靠的方法来快速、准确地识别服务器环境。这就是我开发这个检测脚本的初衷。
现实困境:为什么环境识别如此重要却如此困难?
性能调优的迷思
物理机和虚拟机的性能特征天差地别。物理机的瓶颈可能在硬件本身,而虚拟机的性能问题往往源于资源分配或虚拟化层。用错了调优方法,就像给鱼开车——再努力也是白费劲。
成本核算的困惑
企业IT成本核算时,物理机的折旧与虚拟机的资源计费完全不同的。错误的环境识别可能导致成本分配不公,甚至引发部门间的矛盾。
安全合规的隐患
某些安全策略对物理机和虚拟机有不同的要求。错误的环境判断可能导致安全配置不当,给系统留下致命漏洞。
故障排查的误区
我曾亲眼见过团队花了两天时间排查"物理网卡故障",最后发现是虚拟机的网络驱动问题。这种时间浪费在紧急故障处理时是致命的。
破局之道:从人工猜测到自动化检测
传统方法的局限性
过去,我们依赖零散的命令来猜测服务器身份:
dmidecode -s system-manufacturer
lscpu | grep Hypervisor
dmesg | grep -i virtual
这种方法就像盲人摸象,每个命令只能看到真相的一个侧面,而且容易漏掉关键证据。
我们的解决方案:多维度证据链分析
受税务检查中"证据链"概念的启发,我在AI的协助下,开发了基于多维度交叉验证的检测方法。核心思想是:单一证据可能误导,但多个独立证据形成的证据链很难伪造。
硬件证据层
系统固件信息:如同服务器的"身份证"
CPU特征指纹:物理CPU与虚拟CPU的微妙差异
内存分布模式:物理内存条与虚拟内存的分配特征
软件证据层
设备驱动特征:virtio、vmxnet等虚拟化驱动的存在
系统服务痕迹:VMware Tools、Cloud-Init等服务进程
内核模块指纹:特定的虚拟化内核模块
网络证据层
MAC地址归属:各虚拟化平台的专属地址段
网络接口特征:驱动类型和命名规则
云元数据服务:访问云厂商的内部元数据端点
性能证据层
磁盘I/O模式:物理磁盘与虚拟存储的性能特征
CPU调度特征:物理核心与虚拟CPU的调度差异
时钟源行为:不同时钟源在虚拟化环境下的表现
实战检验:脚本的精彩破案时刻
案例1:神秘的"物理服务器"
某服务公司一直将一台数据库服务器当作物理机管理,直到性能监控显示异常。我们的脚本在30秒内给出结论:这是一台VMware虚拟机!原来当初的运维文档记录有误,导致后续的性能调优全部走错了方向。
案例2:云中的"伪装者"
一家电商企业的日志服务器表现异常,团队以为是硬件故障。脚本检测发现这是阿里云ECS实例,结合云监控发现是磁盘IOPS配额用尽。问题在5分钟内定位,避免了不必要的工单和等待。
案例3:容器里的"套娃"
开发团队报告测试环境性能问题,脚本立即警告:"当前运行在Docker容器中"。这才发现容器嵌套导致资源竞争,根本不是硬件问题。
如何使用这个侦探工具如何使用这个侦探工具
1、创建脚本文件
# 使用你喜欢的编辑器创建文件
cd /usr/local/bin/
vi server_detective.sh
# 或者
nano server_detective.sh
2、将完整的检测脚本代码粘贴到文件中。
#!/bin/bash
# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
PURPLE='\033[0;35m'
CYAN='\033[0;36m'
NC='\033[0m' # No Color
# 检测结果存储
VIRTUAL_INDICATORS=()
PHYSICAL_INDICATORS=()
INCONCLUSIVE_INDICATORS=()
# 日志函数
log_info() {
echo -e "${BLUE}[INFO]${NC} $1"
}
log_warning() {
echo -e "${YELLOW}[WARNING]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
log_success() {
echo -e "${GREEN}[SUCCESS]${NC} $1"
}
log_debug() {
echo -e "${PURPLE}[DEBUG]${NC} $1"
}
# 检查命令是否存在
check_command() {
if command -v "$1" &> /dev/null; then
return 0
else
return 1
fi
}
# 检查 root 权限
check_root() {
if [[ $EUID -eq 0 ]]; then
return 0
else
return 1
fi
}
# 显示权限警告
show_permission_warning() {
if ! check_root; then
log_warning "当前未使用root权限运行,部分检测可能无法执行"
log_warning "建议使用: sudo $0"
echo
fi
}
# 1. 检查系统制造商和产品名称
check_system_manufacturer() {
if check_command dmidecode; then
log_info "检查系统制造商信息..."
if check_root; then
local sys_man=$(dmidecode -s system-manufacturer 2>/dev/null | head -1)
local sys_prod=$(dmidecode -s system-product-name 2>/dev/null | head -1)
else
local sys_man=$(sudo dmidecode -s system-manufacturer 2>/dev/null | head -1)
local sys_prod=$(sudo dmidecode -s system-product-name 2>/dev/null | head -1)
fi
if [[ -n "$sys_man" ]]; then
echo " 制造商: $sys_man"
echo " 产品: $sys_prod"
# 虚拟化厂商检测
if echo "$sys_man" | grep -qiE "vmware|microsoft|innotek|red hat|qemu|parallels|xen|kvm|amazon|google|alibaba|tencent|huawei|jd"; then
VIRTUAL_INDICATORS+=("系统制造商: $sys_man")
elif echo "$sys_man" | grep -qiE "dell|hp|ibm|supermicro|lenovo|cisco|fujitsu"; then
PHYSICAL_INDICATORS+=("系统制造商: $sys_man")
else
INCONCLUSIVE_INDICATORS+=("系统制造商: $sys_man")
fi
else
log_warning "无法获取系统制造商信息"
fi
else
log_warning "dmidecode 命令不可用,跳过系统制造商检查"
log_warning "可以安装: sudo apt-get install dmidecode"
fi
}
# 2. 检查 BIOS 信息
check_bios_info() {
if check_command dmidecode; then
log_info "检查 BIOS 信息..."
if check_root; then
local bios_vendor=$(dmidecode -s bios-vendor 2>/dev/null | head -1)
local bios_version=$(dmidecode -s bios-version 2>/dev/null | head -1)
else
local bios_vendor=$(sudo dmidecode -s bios-vendor 2>/dev/null | head -1)
local bios_version=$(sudo dmidecode -s bios-version 2>/dev/null | head -1)
fi
if [[ -n "$bios_vendor" ]]; then
echo " BIOS厂商: $bios_vendor"
echo " BIOS版本: $bios_version"
if echo "$bios_vendor" | grep -qiE "vmware|innotek|virtualbox|qemu|bochs|sea bios|american megatrends"; then
VIRTUAL_INDICATORS+=("BIOS厂商: $bios_vendor")
elif echo "$bios_vendor" | grep -qiE "dell|hp|ibm|insyde|phoenix"; then
PHYSICAL_INDICATORS+=("BIOS厂商: $bios_vendor")
fi
fi
fi
}
# 3. 检查 CPU 信息
check_cpu_info() {
log_info "检查 CPU 信息..."
# 检查 /proc/cpuinfo
if [[ -f "/proc/cpuinfo" ]]; then
local cpu_hypervisor=$(grep -i "hypervisor" /proc/cpuinfo | head -1)
local cpu_vendor=$(grep -i "vendor" /proc/cpuinfo | head -1 | cut -d: -f2 | xargs)
echo " CPU厂商: $cpu_vendor"
if [[ -n "$cpu_hypervisor" ]]; then
VIRTUAL_INDICATORS+=("CPU包含hypervisor标志")
echo " ⚠️ 检测到hypervisor标志"
fi
# 检查CPU型号特征
if echo "$cpu_vendor" | grep -qi "GenuineIntel\|AuthenticAMD"; then
if [[ ${#VIRTUAL_INDICATORS[@]} -eq 0 ]]; then
PHYSICAL_INDICATORS+=("CPU厂商为物理硬件厂商")
fi
fi
fi
# 使用 lscpu 如果可用
if check_command lscpu; then
echo " CPU架构信息:"
lscpu | grep -E "(Architecture|CPU\(s\)|Thread|Core|Socket)" | sed 's/^/ /'
else
log_warning "lscpu 命令不可用"
fi
}
# 4. 检查磁盘信息
check_disk_info() {
log_info "检查磁盘信息..."
# 使用 lsblk 检查磁盘模型
if check_command lsblk; then
local disk_info=$(lsblk -d -o NAME,MODEL,SIZE,TYPE 2>/dev/null | grep -v "NAME" | head -5)
if [[ -n "$disk_info" ]]; then
echo " 磁盘信息:"
echo "$disk_info" | sed 's/^/ /'
if echo "$disk_info" | grep -qiE "virtual|vhd|vdi|vmware|qemu|amazon|google|alibaba|tencent"; then
VIRTUAL_INDICATORS+=("虚拟磁盘类型")
elif echo "$disk_info" | grep -qiE "samsung|western digital|seagate|toshiba|hitachi"; then
PHYSICAL_INDICATORS+=("物理磁盘型号")
fi
fi
else
log_warning "lsblk 命令不可用"
fi
# 检查 /sys/block 中的设备
if [[ -d "/sys/block" ]]; then
for device in /sys/block/sd* /sys/block/vd* /sys/block/xvd* /sys/block/nvme*; do
if [[ -e "$device" ]]; then
local device_name=$(basename "$device")
if [[ "$device_name" == vd* ]] || [[ "$device_name" == xvd* ]]; then
VIRTUAL_INDICATORS+=("虚拟块设备: $device_name")
elif [[ "$device_name" == sd* ]] || [[ "$device_name" == nvme* ]]; then
PHYSICAL_INDICATORS+=("物理块设备: $device_name")
fi
fi
done
fi
# 使用 fdisk 作为备选
if check_command fdisk; then
echo " 磁盘列表:"
fdisk -l 2>/dev/null | grep -E "^Disk /dev/" | head -3 | sed 's/^/ /'
fi
}
# 5. 检查设备驱动
check_device_drivers() {
log_info "检查设备驱动..."
# 使用 lspci 检查设备
if check_command lspci; then
local virt_devices
if check_root; then
virt_devices=$(lspci 2>/dev/null | grep -iE "virtio|vmware|virtualbox|qemu|xen|red hat|amazon|alibaba")
else
virt_devices=$(sudo lspci 2>/dev/null | grep -iE "virtio|vmware|virtualbox|qemu|xen|red hat|amazon|alibaba")
fi
if [[ -n "$virt_devices" ]]; then
echo " 虚拟化设备:"
echo "$virt_devices" | sed 's/^/ /'
VIRTUAL_INDICATORS+=("发现虚拟化PCI设备")
fi
# 检查物理设备
local phys_devices
if check_root; then
phys_devices=$(lspci 2>/dev/null | grep -iE "broadcom|intel|realtek|marvell|qlogic" | head -5)
else
phys_devices=$(sudo lspci 2>/dev/null | grep -iE "broadcom|intel|realtek|marvell|qlogic" | head -5)
fi
if [[ -n "$phys_devices" ]]; then
echo " 物理设备:"
echo "$phys_devices" | sed 's/^/ /'
PHYSICAL_INDICATORS+=("发现物理PCI设备")
fi
else
log_warning "lspci 命令不可用,跳过PCI设备检查"
log_warning "可以安装: sudo apt-get install pciutils"
fi
# 检查内核模块
if check_command lsmod; then
local virt_modules
if check_root; then
virt_modules=$(lsmod | grep -iE "virtio|vmw|vbox|qemu|xen|hv_")
else
virt_modules=$(sudo lsmod 2>/dev/null | grep -iE "virtio|vmw|vbox|qemu|xen|hv_")
fi
if [[ -n "$virt_modules" ]]; then
echo " 虚拟化内核模块:"
echo "$virt_modules" | sed 's/^/ /'
VIRTUAL_INDICATORS+=("加载虚拟化内核模块")
fi
fi
}
# 6. 检查系统进程和服务
check_system_services() {
log_info "检查系统进程和服务..."
# 检查虚拟化相关进程
local virt_processes=$(ps aux 2>/dev/null | grep -E "(vmtoolsd|qemu-ga|virtio|vboxadd|hyperv|aws|aliyun|tencent|jdcloud)" | grep -v grep)
if [[ -n "$virt_processes" ]]; then
echo " 虚拟化相关进程:"
echo "$virt_processes" | sed 's/^/ /'
VIRTUAL_INDICATORS+=("运行虚拟化相关进程")
fi
# 检查系统服务
if check_command systemctl; then
local virt_services=$(systemctl list-units 2>/dev/null | grep -iE "virtual|vmware|vbox|qemu|hyperv|aws|google|aliyun|tencent|jdcloud|huawei" | head -10)
if [[ -n "$virt_services" ]]; then
echo " 虚拟化相关服务:"
echo "$virt_services" | sed 's/^/ /'
VIRTUAL_INDICATORS+=("运行虚拟化相关服务")
fi
else
# 对于使用 SysV init 的系统
if [[ -d "/etc/init.d" ]]; then
local init_services=$(ls /etc/init.d/ | grep -iE "vmware|vbox|aliyun|tencent" | head -5)
if [[ -n "$init_services" ]]; then
echo " 虚拟化相关服务 (init.d):"
echo "$init_services" | sed 's/^/ /'
VIRTUAL_INDICATORS+=("运行虚拟化相关服务")
fi
fi
fi
}
# 7. 检查网络接口
check_network_interfaces() {
log_info "检查网络接口..."
if check_command ip; then
local mac_addresses=$(ip addr show 2>/dev/null | grep -oE "([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}" | tr '[:lower:]' '[:upper:]' | sort -u)
if [[ -n "$mac_addresses" ]]; then
echo " MAC地址:"
for mac in $mac_addresses; do
echo " $mac"
# 检查MAC地址前三位
local prefix=$(echo "$mac" | cut -d: -f1-3)
case $prefix in
"00:0C:29"|"00:50:56")
VIRTUAL_INDICATORS+=("VMware MAC地址: $mac")
;;
"08:00:27")
VIRTUAL_INDICATORS+=("VirtualBox MAC地址: $mac")
;;
"00:15:5D")
VIRTUAL_INDICATORS+=("Hyper-V MAC地址: $mac")
;;
"00:16:3E")
VIRTUAL_INDICATORS+=("Xen MAC地址: $mac")
;;
"00:1C:42"|"00:03:FF")
VIRTUAL_INDICATORS+=("Parallels MAC地址: $mac")
;;
"52:54:00")
VIRTUAL_INDICATORS+=("QEMU/KVM MAC地址: $mac")
;;
"0A:00:27")
VIRTUAL_INDICATORS+=("VirtualBox NAT MAC地址: $mac")
;;
"02:42:AC"|"02:42:AD")
VIRTUAL_INDICATORS+=("Docker容器MAC地址: $mac")
;;
"06:00:*"|"06:05:*"|"06:0A:*")
INCONCLUSIVE_INDICATORS+=("可能的云环境MAC地址: $mac")
;;
"00:16:3E")
VIRTUAL_INDICATORS+=("阿里云MAC地址: $mac")
;;
esac
done
fi
# 检查网络接口名称
local interfaces=$(ip addr show 2>/dev/null | grep -E "^[0-9]+:" | awk '{print $2}' | tr -d ':')
if [[ -n "$interfaces" ]]; then
echo " 网络接口: $interfaces"
# 检查虚拟网络接口
if echo "$interfaces" | grep -qE "veth|docker|br-"; then
VIRTUAL_INDICATORS+=("虚拟网络接口")
fi
fi
else
log_warning "ip 命令不可用"
# 尝试使用 ifconfig
if check_command ifconfig; then
local mac_addresses=$(ifconfig 2>/dev/null | grep -oE "([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}" | tr '[:lower:]' '[:upper:]' | sort -u)
if [[ -n "$mac_addresses" ]]; then
echo " MAC地址:"
for mac in $mac_addresses; do
echo " $mac"
done
fi
fi
fi
}
# 8. 检查 dmesg 输出
check_dmesg() {
log_info "检查内核消息..."
if check_command dmesg; then
local dmesg_virt
if check_root; then
dmesg_virt=$(dmesg 2>/dev/null | grep -iE "virtual|hypervisor|vmware|vbox|qemu|xen|hyper-v|cloud" | head -5)
else
dmesg_virt=$(sudo dmesg 2>/dev/null | grep -iE "virtual|hypervisor|vmware|vbox|qemu|xen|hyper-v|cloud" | head -5)
fi
if [[ -n "$dmesg_virt" ]]; then
echo " 虚拟化相关内核消息:"
echo "$dmesg_virt" | sed 's/^/ /'
VIRTUAL_INDICATORS+=("内核消息包含虚拟化痕迹")
fi
# 检查物理硬件相关消息
local dmesg_phys
if check_root; then
dmesg_phys=$(dmesg 2>/dev/null | grep -iE "memory:|cpu:|acpi:" | head -3)
else
dmesg_phys=$(sudo dmesg 2>/dev/null | grep -iE "memory:|cpu:|acpi:" | head -3)
fi
if [[ -n "$dmesg_phys" ]]; then
echo " 硬件相关内核消息:"
echo "$dmesg_phys" | sed 's/^/ /'
fi
fi
}
# 9. 检查容器环境(排除容器干扰)
check_container() {
log_info "检查容器环境..."
local container_detected=false
# 检查常见的容器标识
if [[ -f "/.dockerenv" ]]; then
log_warning "当前运行在Docker容器中,检测结果可能不准确"
container_detected=true
fi
if [[ -f "/run/.containerenv" ]]; then
log_warning "当前运行在容器环境中,检测结果可能不准确"
container_detected=true
fi
if grep -q "docker" /proc/1/cgroup 2>/dev/null; then
log_warning "当前运行在Docker容器中,检测结果可能不准确"
container_detected=true
fi
if grep -q "kubepods" /proc/1/cgroup 2>/dev/null; then
log_warning "当前运行在Kubernetes Pod中,检测结果可能不准确"
container_detected=true
fi
# 检查 PID 1 的进程名
local pid1_process=$(ps -p 1 -o comm= 2>/dev/null)
if [[ "$pid1_process" != "systemd" && "$pid1_process" != "init" && "$pid1_process" != "bash" && "$pid1_process" != "sh" ]]; then
log_warning "PID 1 进程为 $pid1_process,可能运行在容器中"
container_detected=true
fi
# 检查根文件系统类型
local root_fs=$(stat -f -c %T / 2>/dev/null)
if [[ "$root_fs" == "overlayfs" || "$root_fs" == "aufs" ]]; then
log_warning "根文件系统为 $root_fs,可能运行在容器中"
container_detected=true
fi
if [[ "$container_detected" == true ]]; then
INCONCLUSIVE_INDICATORS+=("运行在容器环境中")
return 1
fi
echo " 未检测到容器环境"
return 0
}
# 10. 性能简单测试(可选)
check_performance() {
log_info "执行简单性能测试..."
# 检查是否有写入权限
if [[ -w "/tmp" ]]; then
# 磁盘写入测试
local test_file="/tmp/vm_test_$$"
local start_time=$(date +%s%N)
# 使用 dd 进行测试,但处理可能的错误
if dd if=/dev/zero of="$test_file" bs=1M count=16 oflag=dsync status=none 2>/dev/null; then
local end_time=$(date +%s%N)
local duration=$(( (end_time - start_time) / 1000000 ))
echo " 16MB磁盘写入测试: ${duration}ms"
# 简单性能判断
if [[ $duration -gt 2000 ]]; then
INCONCLUSIVE_INDICATORS+=("磁盘写入性能较慢: ${duration}ms")
elif [[ $duration -lt 200 ]]; then
PHYSICAL_INDICATORS+=("磁盘写入性能优秀: ${duration}ms")
else
INCONCLUSIVE_INDICATORS+=("磁盘写入性能一般: ${duration}ms")
fi
# 清理测试文件
rm -f "$test_file"
else
log_warning "磁盘写入测试失败"
fi
# CPU性能简单测试
start_time=$(date +%s%N)
local count=0
for i in {1..1000}; do
count=$((count + i))
done
end_time=$(date +%s%N)
local cpu_duration=$(( (end_time - start_time) / 1000000 ))
echo " CPU简单计算测试: ${cpu_duration}ms"
else
log_warning "没有/tmp目录写入权限,跳过性能测试"
fi
}
# 11. 检查系统特定文件
check_system_files() {
log_info "检查系统特定文件..."
# 检查 /proc/scsi 目录
if [[ -d "/proc/scsi" ]]; then
local scsi_drivers=$(ls /proc/scsi/ 2>/dev/null)
if echo "$scsi_drivers" | grep -qi "vmware"; then
VIRTUAL_INDICATORS+=("VMware SCSI驱动")
fi
fi
# 检查 /sys/class/dmi/id 目录
if [[ -d "/sys/class/dmi/id" ]]; then
if [[ -f "/sys/class/dmi/id/product_name" ]]; then
local product_name=$(cat /sys/class/dmi/id/product_name 2>/dev/null)
if [[ -n "$product_name" ]]; then
echo " 产品名称: $product_name"
if echo "$product_name" | grep -qiE "vmware|virtual|qemu|amazon|google|alibaba|tencent|jdcloud|huawei"; then
VIRTUAL_INDICATORS+=("DMI产品名称: $product_name")
elif echo "$product_name" | grep -qiE "poweredge|proliant|system x|ucs"; then
PHYSICAL_INDICATORS+=("DMI产品名称: $product_name")
fi
fi
fi
if [[ -f "/sys/class/dmi/id/sys_vendor" ]]; then
local sys_vendor=$(cat /sys/class/dmi/id/sys_vendor 2>/dev/null)
if [[ -n "$sys_vendor" ]]; then
echo " 系统供应商: $sys_vendor"
if echo "$sys_vendor" | grep -qiE "vmware|innotek|microsoft|amazon|google|alibaba|tencent|jdcloud|huawei"; then
VIRTUAL_INDICATORS+=("DMI系统供应商: $sys_vendor")
elif echo "$sys_vendor" | grep -qiE "dell|hp|ibm|lenovo|cisco"; then
PHYSICAL_INDICATORS+=("DMI系统供应商: $sys_vendor")
fi
fi
fi
if [[ -f "/sys/class/dmi/id/board_vendor" ]]; then
local board_vendor=$(cat /sys/class/dmi/id/board_vendor 2>/dev/null)
if [[ -n "$board_vendor" ]]; then
echo " 主板供应商: $board_vendor"
fi
fi
fi
# 检查 /proc/device-tree (ARM架构)
if [[ -d "/proc/device-tree" ]]; then
echo " 检测到设备树(可能是ARM架构)"
PHYSICAL_INDICATORS+=("使用设备树(通常为物理ARM设备)")
fi
}
# 12. 检查特定的虚拟化技术特征
check_virt_specific() {
log_info "检查虚拟化技术特定特征..."
local virt_detected=false
# 检查 VMware 特定特征
if [[ -f /usr/bin/vmware-toolbox-cmd ]]; then
VIRTUAL_INDICATORS+=("检测到VMware Tools")
echo " ✅ 发现VMware Tools"
virt_detected=true
fi
if [[ -d /proc/vmware ]]; then
VIRTUAL_INDICATORS+=("VMware专用proc目录")
echo " ✅ 发现/proc/vmware目录"
virt_detected=true
fi
# 检查 VirtualBox 特定特征
if [[ -f /usr/bin/VBoxService ]]; then
VIRTUAL_INDICATORS+=("检测到VirtualBox Guest Additions")
echo " ✅ 发现VirtualBox Guest Additions"
virt_detected=true
fi
# 检查 Hyper-V 特定特征
if [[ -d /sys/bus/vmbus ]]; then
VIRTUAL_INDICATORS+=("Hyper-V VMBus设备")
echo " ✅ 发现Hyper-V VMBus"
virt_detected=true
fi
if lsmod | grep -q hv_; then
VIRTUAL_INDICATORS+=("Hyper-V内核模块")
echo " ✅ 发现Hyper-V内核模块"
virt_detected=true
fi
# 检查 KVM 特定特征
if [[ -r /dev/kvm ]]; then
echo " ✅ 发现KVM设备 (/dev/kvm)"
if check_command dmesg; then
local kvm_dmesg
if check_root; then
kvm_dmesg=$(dmesg | grep -i "kvm" | head -3)
else
kvm_dmesg=$(sudo dmesg 2>/dev/null | grep -i "kvm" | head -3)
fi
if [[ -n "$kvm_dmesg" ]]; then
VIRTUAL_INDICATORS+=("KVM虚拟化支持")
echo " ✅ 发现KVM相关日志"
virt_detected=true
fi
fi
fi
# 检查 Xen 特定特征
if [[ -d /proc/xen ]]; then
VIRTUAL_INDICATORS+=("Xen虚拟化环境")
echo " ✅ 发现/proc/xen目录"
virt_detected=true
fi
if lsmod | grep -q xen; then
VIRTUAL_INDICATORS+=("Xen内核模块")
echo " ✅ 发现Xen内核模块"
virt_detected=true
fi
# 检查云厂商特定文件
if [[ -f /etc/aliyun-release ]]; then
VIRTUAL_INDICATORS+=("阿里云环境")
echo " ✅ 发现阿里云标识文件"
virt_detected=true
fi
if [[ -f /etc/tlinux-release ]]; then
VIRTUAL_INDICATORS+=("腾讯云环境")
echo " ✅ 发现腾讯云标识文件"
virt_detected=true
fi
if [[ "$virt_detected" == false ]]; then
echo " 未发现特定虚拟化技术特征"
fi
}
# 13. 检查时钟源,虚拟机和物理机通常使用不同的时钟源
check_clocksource() {
log_info "检查系统时钟源..."
if [[ -f /sys/devices/system/clocksource/clocksource0/current_clocksource ]]; then
local clocksource=$(cat /sys/devices/system/clocksource/clocksource0/current_clocksource 2>/dev/null)
if [[ -n "$clocksource" ]]; then
echo " 当前时钟源: $clocksource"
# 虚拟化环境常见的时钟源
if echo "$clocksource" | grep -qiE "kvm-clock|hyperv|acpi_pm"; then
VIRTUAL_INDICATORS+=("虚拟化时钟源: $clocksource")
elif echo "$clocksource" | grep -qiE "tsc|hpet"; then
PHYSICAL_INDICATORS+=("物理机时钟源: $clocksource")
else
INCONCLUSIVE_INDICATORS+=("未知时钟源: $clocksource")
fi
else
log_warning "无法获取当前时钟源信息"
fi
else
log_warning "无法访问时钟源信息文件"
fi
# 检查可用时钟源
if [[ -f /sys/devices/system/clocksource/clocksource0/available_clocksource ]]; then
local available_clocksources=$(cat /sys/devices/system/clocksource/clocksource0/available_clocksource 2>/dev/null)
if [[ -n "$available_clocksources" ]]; then
echo " 可用时钟源: $available_clocksources"
fi
fi
}
# 14. 检查内存信息,虚拟机和物理机在内存分配上有差异
check_memory_info() {
log_info "检查内存信息..."
# 检查内存总量和分布
if [[ -f /proc/meminfo ]]; then
local mem_total=$(grep -i "memtotal" /proc/meminfo | awk '{print $2}')
local mem_available=$(grep -i "memavailable" /proc/meminfo | awk '{print $2}')
if [[ -n "$mem_total" ]]; then
local mem_total_mb=$((mem_total / 1024))
local mem_total_gb=$((mem_total_mb / 1024))
echo " 内存总量: ${mem_total_mb} MB (${mem_total_gb} GB)"
# 检查内存是否为2的幂次方(物理机常见)
if (( (mem_total & (mem_total - 1)) == 0 )); then
PHYSICAL_INDICATORS+=("内存总量为2的幂次方(物理机特征)")
else
INCONCLUSIVE_INDICATORS+=("内存总量非2的幂次方")
fi
# 检查内存总量是否常见(如 1024, 2048, 4096, 8192 MB)
if [[ $mem_total_mb -eq 1024 ]] || [[ $mem_total_mb -eq 2048 ]] || [[ $mem_total_mb -eq 4096 ]] || [[ $mem_total_mb -eq 8192 ]] || [[ $mem_total_mb -eq 16384 ]]; then
echo " 内存配置为常见虚拟化规格"
fi
fi
if [[ -n "$mem_available" ]]; then
local mem_available_mb=$((mem_available / 1024))
echo " 可用内存: ${mem_available_mb} MB"
fi
fi
# 检查内存插槽信息(需要dmidecode)
if check_command dmidecode; then
log_info "检查内存插槽信息..."
local memory_slots
if check_root; then
memory_slots=$(dmidecode -t memory 2>/dev/null | grep -c "Size:" | grep -v "No Module")
else
memory_slots=$(sudo dmidecode -t memory 2>/dev/null | grep -c "Size:" | grep -v "No Module")
fi
if [[ "$memory_slots" -gt 0 ]]; then
echo " 检测到 $memory_slots 个内存插槽有模块"
if [[ "$memory_slots" -ge 2 ]]; then
PHYSICAL_INDICATORS+=("多内存插槽(物理机特征)")
fi
else
echo " 无法获取内存插槽信息或没有检测到内存模块"
fi
fi
}
# 15. 检查CPU高级特征
check_advanced_cpu() {
log_info "检查CPU高级特征..."
if [[ -f /proc/cpuinfo ]]; then
# 检查CPU核心数
local core_count=$(grep -c "^processor" /proc/cpuinfo)
echo " CPU逻辑核心数: $core_count"
# 检查物理核心数
local physical_cores=$(grep "core id" /proc/cpuinfo | sort -u | wc -l)
if [[ "$physical_cores" -gt 0 ]]; then
echo " CPU物理核心数: $physical_cores"
# 如果逻辑核心数远大于物理核心数,可能是虚拟机
if [[ $core_count -gt $((physical_cores * 2)) ]]; then
INCONCLUSIVE_INDICATORS+=("逻辑核心数远超物理核心数(超线程或虚拟CPU)")
elif [[ $core_count -eq $physical_cores ]]; then
PHYSICAL_INDICATORS+=("逻辑与物理核心数一致")
fi
fi
# 检查CPU频率缩放驱动(虚拟机和物理机不同)
if [[ -d /sys/devices/system/cpu/cpu0/cpufreq ]]; then
local scaling_driver=$(cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_driver 2>/dev/null)
if [[ -n "$scaling_driver" ]]; then
echo " CPU频率缩放驱动: $scaling_driver"
if [[ "$scaling_driver" == "acpi-cpufreq" ]]; then
PHYSICAL_INDICATORS+=("使用ACPI CPU频率调节")
elif [[ "$scaling_driver" == "intel_pstate" ]]; then
PHYSICAL_INDICATORS+=("使用Intel P-State驱动")
fi
fi
fi
# 检查CPU漏洞缓解状态
local cpu_bugs=$(grep "bugs" /proc/cpuinfo | head -1 | cut -d: -f2 | xargs)
if [[ -n "$cpu_bugs" ]]; then
echo " CPU漏洞信息: $cpu_bugs"
fi
fi
}
# 16. 检查文件系统特征
check_filesystem_features() {
log_info "检查文件系统特征..."
# 检查根文件系统类型
local root_fs=$(df -T / 2>/dev/null | awk 'NR==2 {print $2}')
if [[ -n "$root_fs" ]]; then
echo " 根文件系统类型: $root_fs"
# 某些文件系统在虚拟化环境中更常见
if [[ "$root_fs" == "overlay" ]] || [[ "$root_fs" == "aufs" ]]; then
INCONCLUSIVE_INDICATORS+=("使用容器常用文件系统: $root_fs")
fi
fi
# 检查是否有虚拟化特定的文件系统
if mount | grep -q "fuse.vmware"; then
VIRTUAL_INDICATORS+=("VMware FUSE文件系统")
echo " ✅ 发现VMware共享文件夹文件系统"
fi
if mount | grep -q "vboxsf"; then
VIRTUAL_INDICATORS+=("VirtualBox共享文件夹文件系统")
echo " ✅ 发现VirtualBox共享文件夹文件系统"
fi
# 检查设备映射器(常用于虚拟化存储)
if check_command dmsetup; then
local dm_devices=$(dmsetup ls --target linear 2>/dev/null | wc -l)
if [[ "$dm_devices" -gt 0 ]]; then
echo " 设备映射器设备数: $dm_devices"
if [[ "$dm_devices" -gt 2 ]]; then
INCONCLUSIVE_INDICATORS+=("多个设备映射器设备(可能是LVM或虚拟化存储)")
fi
fi
fi
# 检查 /proc/mounts 中的特殊文件系统
local special_mounts=$(grep -E "fuse|vbox|vmware" /proc/mounts 2>/dev/null | head -3)
if [[ -n "$special_mounts" ]]; then
echo " 特殊文件系统挂载:"
echo "$special_mounts" | sed 's/^/ /'
fi
}
# 17. 检查网络高级特征
check_advanced_network() {
log_info "检查网络高级特征..."
# 检查网络设备驱动
if [[ -d /sys/class/net ]]; then
local virt_net_detected=false
local phys_net_detected=false
for iface in /sys/class/net/*; do
local iface_name=$(basename "$iface")
# 跳过lo回环接口
if [[ "$iface_name" != "lo" ]]; then
if [[ -f "$iface/device/driver" ]]; then
local driver=$(basename $(readlink "$iface/device/driver") 2>/dev/null)
if [[ -n "$driver" ]]; then
echo " 接口 $iface_name 驱动: $driver"
if echo "$driver" | grep -qiE "virtio|veth|vif|vmxnet"; then
VIRTUAL_INDICATORS+=("虚拟网络驱动: $driver")
virt_net_detected=true
elif echo "$driver" | grep -qiE "e1000|igb|ixgbe|bnx2x|tg3"; then
PHYSICAL_INDICATORS+=("物理网络驱动: $driver")
phys_net_detected=true
fi
fi
fi
fi
done
if [[ "$virt_net_detected" == false ]] && [[ "$phys_net_detected" == false ]]; then
echo " 无法确定网络驱动类型"
fi
fi
# 检查网络时间协议(NTP)配置
if check_command timedatectl; then
local ntp_service=$(timedatectl show --property=NTPSynchronized --value 2>/dev/null)
if [[ "$ntp_service" == "yes" ]]; then
echo " NTP同步: 已启用"
else
echo " NTP同步: 未启用或无法确定"
fi
elif check_command ntpq; then
local ntp_peers=$(ntpq -p 2>/dev/null | wc -l)
if [[ $ntp_peers -gt 0 ]]; then
echo " NTP对等点: $((ntp_peers - 2)) 个"
fi
fi
# 检查网络桥接信息
if check_command brctl; then
local bridges=$(brctl show 2>/dev/null | sed '1d' | wc -l)
if [[ $bridges -gt 0 ]]; then
echo " 网络桥接数量: $bridges"
INCONCLUSIVE_INDICATORS+=("存在网络桥接(可能是虚拟化网络)")
fi
fi
}
# 18. 检查系统调用和性能计数器检测
check_syscall_features() {
log_info "检查系统调用特征..."
# 检查 /proc/cpuinfo 中的bugs字段
local cpu_bugs=$(grep "bugs" /proc/cpuinfo | head -1 | cut -d: -f2 | xargs)
if [[ -n "$cpu_bugs" ]]; then
echo " CPU漏洞信息: $cpu_bugs"
# 某些CPU漏洞在虚拟化环境中表现不同
if echo "$cpu_bugs" | grep -qi "spectre"; then
INCONCLUSIVE_INDICATORS+=("存在Spectre漏洞缓解")
fi
if echo "$cpu_bugs" | grep -qi "meltdown"; then
INCONCLUSIVE_INDICATORS+=("存在Meltdown漏洞缓解")
fi
fi
# 检查系统页大小
if check_command getconf; then
local page_size=$(getconf PAGE_SIZE)
echo " 系统页大小: $page_size 字节"
# 检查大页支持
if [[ -d /sys/kernel/mm/hugepages ]]; then
local hugepages=$(ls /sys/kernel/mm/hugepages/ 2>/dev/null | wc -l)
if [[ $hugepages -gt 0 ]]; then
echo " 大页支持: 已启用"
PHYSICAL_INDICATORS+=("启用大页支持(物理机常见)")
fi
fi
fi
# 检查内核版本和构建选项
local kernel_version=$(uname -r)
echo " 内核版本: $kernel_version"
# 检查内核是否包含虚拟化相关模块
if [[ -d /lib/modules/$kernel_version ]]; then
local kvm_modules=$(find /lib/modules/$kernel_version -name "*kvm*" -o -name "*virtio*" 2>/dev/null | wc -l)
if [[ $kvm_modules -gt 0 ]]; then
echo " 内核虚拟化模块: $kvm_modules 个"
fi
fi
}
# 19. 检查云环境特定检测
check_cloud_environment() {
log_info "检查云环境特征..."
local cloud_detected=false
# AWS 检测
if curl -s --connect-timeout 2 http://169.254.169.254/latest/meta-data/ > /dev/null; then
VIRTUAL_INDICATORS+=("AWS EC2实例")
echo " ☁️ 检测到AWS环境"
cloud_detected=true
# 尝试获取AWS实例类型
local aws_instance_type=$(curl -s --connect-timeout 2 http://169.254.169.254/latest/meta-data/instance-type 2>/dev/null)
if [[ -n "$aws_instance_type" ]]; then
echo " AWS实例类型: $aws_instance_type"
fi
fi
# 京东云检测
if curl -s --connect-timeout 2 -H "Metadata-Flavor: JDCloud" http://169.254.169.254/latest/meta-data/ > /dev/null; then
VIRTUAL_INDICATORS+=("京东云实例")
echo " ☁️ 检测到京东云环境"
cloud_detected=true
# 尝试获取京东云实例信息
local jd_metadata=$(curl -s --connect-timeout 2 -H "Metadata-Flavor: JDCloud" http://169.254.169.254/latest/meta-data/ 2>/dev/null | head -5)
if [[ -n "$jd_metadata" ]]; then
echo " 京东云元数据可用"
fi
fi
# 华为云检测
if curl -s --connect-timeout 2 -H "Metadata-Flavor: Huawei" http://169.254.169.254/latest/meta-data/ > /dev/null ||
curl -s --connect-timeout 2 http://169.254.169.254/latest/meta-data/ > /dev/null; then
# 验证是否为华为云
local huawei_meta=$(curl -s --connect-timeout 2 http://169.254.169.254/latest/meta-data/ 2>/dev/null | head -10)
if echo "$huawei_meta" | grep -qi "huawei\|ecs" || [[ -n "$huawei_meta" ]]; then
VIRTUAL_INDICATORS+=("华为云实例")
echo " ☁️ 检测到华为云环境"
cloud_detected=true
# 尝试获取华为云实例信息
local huawei_instance_id=$(curl -s --connect-timeout 2 http://169.254.169.254/latest/meta-data/instance-id 2>/dev/null)
if [[ -n "$huawei_instance_id" ]]; then
echo " 华为云实例ID: $huawei_instance_id"
fi
fi
fi
# 腾讯云检测
if curl -s --connect-timeout 2 http://169.254.169.254/latest/meta-data/ > /dev/null; then
local tx_metadata=$(curl -s --connect-timeout 2 http://169.254.169.254/latest/meta-data/ 2>/dev/null)
if echo "$tx_metadata" | grep -q "qcloud" || echo "$tx_metadata" | grep -q "tencent" ||
[[ -f /etc/tlinux-release ]] || systemctl list-unit-files | grep -q "qcloud"; then
VIRTUAL_INDICATORS+=("腾讯云实例")
echo " ☁️ 检测到腾讯云环境"
cloud_detected=true
# 检查腾讯云特定服务
if systemctl list-unit-files | grep -q "qcloud"; then
echo " 发现腾讯云相关服务"
fi
# 尝试获取腾讯云实例信息
local tx_instance_id=$(curl -s --connect-timeout 2 http://169.254.169.254/latest/meta-data/instance-id 2>/dev/null)
if [[ -n "$tx_instance_id" ]]; then
echo " 腾讯云实例ID: $tx_instance_id"
fi
fi
fi
# 阿里云检测
if curl -s --connect-timeout 2 http://169.254.169.254/latest/meta-data/ > /dev/null; then
local aliyun_metadata=$(curl -s --connect-timeout 2 http://169.254.169.254/latest/meta-data/ 2>/dev/null)
if echo "$aliyun_metadata" | grep -q "aliyun" || echo "$aliyun_metadata" | grep -q "ecs" ||
[[ -f /etc/aliyun-release ]] || systemctl list-unit-files | grep -q "aliyun"; then
VIRTUAL_INDICATORS+=("阿里云实例")
echo " ☁️ 检测到阿里云环境"
cloud_detected=true
# 尝试获取阿里云实例信息
local aliyun_instance_id=$(curl -s --connect-timeout 2 http://169.254.169.254/latest/meta-data/instance-id 2>/dev/null)
if [[ -n "$aliyun_instance_id" ]]; then
echo " 阿里云实例ID: $aliyun_instance_id"
fi
local aliyun_region=$(curl -s --connect-timeout 2 http://169.254.169.254/latest/meta-data/region-id 2>/dev/null)
if [[ -n "$aliyun_region" ]]; then
echo " 阿里云区域: $aliyun_region"
fi
fi
fi
# Google Cloud 检测
if curl -s --connect-timeout 2 -H "Metadata-Flavor: Google" http://169.254.169.254/computeMetadata/v1/ > /dev/null; then
VIRTUAL_INDICATORS+=("Google Cloud实例")
echo " ☁️ 检测到Google Cloud环境"
cloud_detected=true
fi
# Azure 检测
if curl -s --connect-timeout 2 -H "Metadata: true" http://169.254.169.254/metadata/instance > /dev/null; then
VIRTUAL_INDICATORS+=("Azure虚拟机")
echo " ☁️ 检测到Azure环境"
cloud_detected=true
fi
# DigitalOcean 检测
if curl -s --connect-timeout 2 http://169.254.169.254/metadata/v1.json > /dev/null; then
VIRTUAL_INDICATORS+=("DigitalOcean Droplet")
echo " ☁️ 检测到DigitalOcean环境"
cloud_detected=true
fi
# Oracle Cloud 检测
if curl -s --connect-timeout 2 http://169.254.169.254/opc/v1/instance/ > /dev/null; then
VIRTUAL_INDICATORS+=("Oracle Cloud实例")
echo " ☁️ 检测到Oracle Cloud环境"
cloud_detected=true
fi
# 检查云初始化标志
if [[ -f /etc/cloud/cloud.cfg ]] || [[ -d /var/lib/cloud ]]; then
echo " ☁️ 发现云初始化配置"
cloud_detected=true
# 检查云初始化供应商
if [[ -f /etc/cloud/cloud.cfg ]]; then
local cloud_vendor=$(grep -i "cloud" /etc/cloud/cloud.cfg | head -1)
if [[ -n "$cloud_vendor" ]]; then
echo " 云初始化配置: $cloud_vendor"
fi
fi
fi
# 检查 cloud-init 服务
if systemctl is-active cloud-init >/dev/null 2>&1 || systemctl is-enabled cloud-init >/dev/null 2>&1; then
echo " ☁️ cloud-init服务已启用"
cloud_detected=true
fi
# 检查云厂商特定的驱动和服务
check_cloud_specific_services
if [[ "$cloud_detected" == false ]]; then
echo " 未检测到主流云环境特征"
else
INCONCLUSIVE_INDICATORS+=("运行在云环境中")
fi
}
# 辅助函数:检查云厂商特定的驱动和服务
check_cloud_specific_services() {
log_info "检查云厂商特定服务..."
# 检查阿里云特定服务
if systemctl list-unit-files | grep -q "aliyun"; then
VIRTUAL_INDICATORS+=("阿里云服务")
echo " ✅ 发现阿里云相关服务"
fi
# 检查腾讯云特定服务
if systemctl list-unit-files | grep -q "qcloud\|tencent"; then
VIRTUAL_INDICATORS+=("腾讯云服务")
echo " ✅ 发现腾讯云相关服务"
fi
# 检查华为云特定服务
if systemctl list-unit-files | grep -q "huawei"; then
VIRTUAL_INDICATORS+=("华为云服务")
echo " ✅ 发现华为云相关服务"
fi
# 检查京东云特定服务
if systemctl list-unit-files | grep -q "jdcloud"; then
VIRTUAL_INDICATORS+=("京东云服务")
echo " ✅ 发现京东云相关服务"
fi
# 检查云厂商特定的驱动模块
local cloud_drivers=$(lsmod | grep -iE "virtio|vmw|vbox|qemu|xen|hv_" | head -5)
if [[ -n "$cloud_drivers" ]]; then
echo " 虚拟化驱动:"
echo "$cloud_drivers" | sed 's/^/ /'
fi
# 检查云厂商特定的进程
local cloud_processes=$(ps aux | grep -E "(aliyun|qcloud|jdcloud|huawei|aws|azure|gcp)" | grep -v grep | head -5)
if [[ -n "$cloud_processes" ]]; then
echo " 云厂商相关进程:"
echo "$cloud_processes" | sed 's/^/ /'
fi
# 检查云厂商特定的配置文件
local cloud_configs=$(find /etc -name "*cloud*" -type f 2>/dev/null | head -5)
if [[ -n "$cloud_configs" ]]; then
echo " 云相关配置文件:"
echo "$cloud_configs" | sed 's/^/ /'
fi
# 检查云厂商特定的日志文件
local cloud_logs=$(find /var/log -name "*cloud*" -type f 2>/dev/null | head -3)
if [[ -n "$cloud_logs" ]]; then
echo " 云相关日志文件:"
echo "$cloud_logs" | sed 's/^/ /'
fi
}
# 20. 检查系统架构和平台特定特征
check_system_architecture() {
log_info "检查系统架构..."
local architecture=$(uname -m)
echo " 系统架构: $architecture"
case $architecture in
"x86_64")
PHYSICAL_INDICATORS+=("x86_64架构")
;;
"aarch64"|"arm64")
echo " ARM64架构"
# ARM架构在虚拟化和物理机都有广泛应用
;;
"ppc64"|"ppc64le")
echo " PowerPC架构"
PHYSICAL_INDICATORS+=("PowerPC架构(通常为物理机)")
;;
"s390x")
echo " IBM Z架构"
PHYSICAL_INDICATORS+=("IBM Z架构(通常为物理机或大型机)")
;;
*)
echo " 其他架构: $architecture"
;;
esac
# 检查UEFI/BIOS引导
if [[ -d /sys/firmware/efi ]]; then
echo " 引导方式: UEFI"
PHYSICAL_INDICATORS+=("UEFI引导")
else
echo " 引导方式: BIOS"
fi
}
# 汇总结果显示
show_results() {
echo
echo "================================================"
echo " 环境检测结果(增强版)"
echo "================================================"
local virtual_score=${#VIRTUAL_INDICATORS[@]}
local physical_score=${#PHYSICAL_INDICATORS[@]}
local inconclusive_score=${#INCONCLUSIVE_INDICATORS[@]}
# 显示详细证据
if [[ $virtual_score -gt 0 ]]; then
echo -e "\n${RED}🚨 检测到虚拟机特征 ($virtual_score 个证据):${NC}"
for indicator in "${VIRTUAL_INDICATORS[@]}"; do
echo -e " ❌ $indicator"
done
fi
if [[ $physical_score -gt 0 ]]; then
echo -e "\n${GREEN}✅ 检测到物理服务器特征 ($physical_score 个证据):${NC}"
for indicator in "${PHYSICAL_INDICATORS[@]}"; do
echo -e " ✅ $indicator"
done
fi
if [[ $inconclusive_score -gt 0 ]]; then
echo -e "\n${YELLOW}⚠️ 不确定的特征 ($inconclusive_score 个):${NC}"
for indicator in "${INCONCLUSIVE_INDICATORS[@]}"; do
echo -e " ⚠️ $indicator"
done
fi
echo
echo "================================================"
# 增强的判断逻辑
local confidence_level=""
local conclusion=""
if [[ $virtual_score -ge 5 ]] && [[ $physical_score -le 1 ]]; then
conclusion="${RED}🎯 结论: 这是一个虚拟机环境(高置信度)${NC}"
confidence_level="高"
elif [[ $physical_score -ge 5 ]] && [[ $virtual_score -le 1 ]]; then
conclusion="${GREEN}🎯 结论: 这是一个物理服务器环境(高置信度)${NC}"
confidence_level="高"
elif [[ $virtual_score -ge 3 ]] && [[ $virtual_score -gt $physical_score ]]; then
conclusion="${RED}🎯 结论: 这很可能是一个虚拟机环境(中等置信度)${NC}"
confidence_level="中"
elif [[ $physical_score -ge 3 ]] && [[ $physical_score -gt $virtual_score ]]; then
conclusion="${GREEN}🎯 结论: 这很可能是一个物理服务器环境(中等置信度)${NC}"
confidence_level="中"
elif [[ $virtual_score -eq 0 ]] && [[ $physical_score -eq 0 ]]; then
conclusion="${YELLOW}🎯 结论: 证据不足,无法明确判断环境类型${NC}"
confidence_level="低"
elif [[ $virtual_score -eq $physical_score ]] && [[ $virtual_score -gt 0 ]]; then
conclusion="${YELLOW}🎯 结论: 环境类型存在矛盾特征,需要进一步分析${NC}"
confidence_level="低"
else
conclusion="${YELLOW}🎯 结论: 环境类型不确定,证据相互矛盾${NC}"
confidence_level="低"
fi
echo -e "$conclusion"
echo -e "${BLUE}📊 检测置信度: $confidence_level${NC}"
echo -e "${CYAN}🔍 检测维度: 20个${NC}"
echo -e "${CYAN}📈 证据统计: 虚拟[$virtual_score] | 物理[$physical_score] | 不确定[$inconclusive_score]${NC}"
# 显示建议
echo "================================================"
if ! check_root; then
echo -e "${YELLOW}💡 建议: 使用root权限重新运行以获得更准确的结果${NC}"
echo -e "${YELLOW} sudo $0${NC}"
fi
local missing_tools=""
if ! check_command dmidecode; then
missing_tools="$missing_tools dmidecode"
fi
if ! check_command lspci; then
missing_tools="$missing_tools pciutils"
fi
if ! check_command lsblk; then
missing_tools="$missing_tools util-linux"
fi
if [[ -n "$missing_tools" ]]; then
echo -e "${YELLOW}💡 建议: 安装缺失的工具以获得完整检测${NC}"
echo -e "${YELLOW} sudo apt-get install$missing_tools${NC}"
fi
# 新增:根据检测结果给出具体建议
if [[ $confidence_level == "低" ]]; then
echo -e "${YELLOW}💡 建议: 考虑使用多种工具交叉验证${NC}"
echo -e "${YELLOW} 可尝试: virt-what, systemd-detect-virt, dmidecode -t system${NC}"
fi
if [[ $virtual_score -gt 0 ]]; then
echo -e "${BLUE}💡 提示: 检测到虚拟化特征,可能是云服务器、VPS或企业虚拟化平台${NC}"
fi
if [[ $physical_score -gt 0 ]]; then
echo -e "${BLUE}💡 提示: 检测到物理服务器特征,可能是裸金属服务器或专用硬件${NC}"
fi
echo "================================================"
}
# 显示脚本头信息
show_header() {
echo -e "${CYAN}"
echo "╔══════════════════════════════════════════════════════════════╗"
echo "║ 服务器环境检测脚本 v2.0 ║"
echo "║ Enhanced Server Environment Detector ║"
echo "║ ║"
echo "║ 功能: 物理机/虚拟机检测 • 云环境识别 • 容器环境排除 ║"
echo "║ 检测: 20个维度全方位分析 • 多证据链交叉验证 • 置信度评估 ║"
echo "╚══════════════════════════════════════════════════════════════╝"
echo -e "${NC}"
}
# 主函数
main() {
show_header
echo -e "${BLUE}开始检测系统环境类型...${NC}"
echo "================================================"
# 记录开始时间
local start_time=$(date +%s)
# 显示权限警告
show_permission_warning
# 检查容器环境
check_container
# 执行各项检测
check_system_architecture
check_system_manufacturer
check_bios_info
check_cpu_info
check_advanced_cpu
check_memory_info
check_disk_info
check_device_drivers
check_system_services
check_network_interfaces
check_advanced_network
check_dmesg
check_system_files
check_virt_specific
check_clocksource
check_filesystem_features
check_syscall_features
check_cloud_environment
check_performance
# 记录结束时间并计算耗时
local end_time=$(date +%s)
local duration=$((end_time - start_time))
echo
echo "================================================"
echo -e "${GREEN}所有检测完成,总耗时: ${duration}秒${NC}"
echo "================================================"
# 显示结果
show_results
}
# 脚本入口
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
main
fi
3、赋予执行权限
chmod +x /usr/local/bin/server_detective.sh
4、运行检测
# 完整检测(使用root权限)
sudo /usr/local/bin/server_detective.sh
5、解读检测报告
脚本会提供清晰的证据清单和置信度评估:
🚨 红色:虚拟机证据
✅ 绿色:物理机证据
⚠️ 黄色:不确定特征
高置信度结论会明确告诉你服务器类型,低置信度结论会给出进一步排查建议。
这个脚本不仅仅是一堆命令的集合,它体现了系统检测的深层智慧:
智能证据权重
不同证据的可靠性不同。比如,云元数据服务是强证据,而性能测试结果是弱证据。脚本会智能权衡各种证据的可信度。
渐进式检测策略
从低成本检测开始,逐步深入到需要特权的操作。即使没有root权限,也能提供有价值的参考结果。
交叉验证机制
多个独立证据相互印证,避免单一特征的误判。就像多个目击证人的证词比单人证词更可靠。
容器环境识别
特别加入容器检测,避免在容器环境中得出误导性结论。
全面的云环境支持
不仅支持AWS、Azure等国际云厂商,还特别优化了对阿里云、腾讯云、华为云、京东云等国内主流云平台的检测。
结语:让服务器身份不再成谜
在这个混合云、虚拟化、容器化交织的复杂时代,准确识别服务器环境已经成为每个技术人员的必备技能。我们的脚本就像一位经验丰富的侦探,帮你拨开迷雾,看清真相。
无论你是:
运维工程师排查性能问题
架构师规划系统架构
安全专员进行合规检查
开发人员调试环境问题
这个工具都能为你提供可靠的环境洞察。下次当你面对一台陌生服务器时,不必再猜测它的真实身份——让脚本在60秒内给你确切的答案。
在IT的世界里,看清本质比盲目努力更重要。现在就开始使用这个脚本,让你的服务器管理变得更加精准和高效!
免责声明
本文及附带的检测脚本仅供技术参考和学习使用,不能保证在所有场景下100%准确识别服务器环境。限于技术发展的复杂性和多样性,以下情况可能影响检测结果的准确性:
新型虚拟化技术:随着虚拟化技术的不断发展,新的虚拟化方案可能采用未被脚本识别的新型特征和隐藏技术
特殊硬件配置:某些定制化硬件或特殊配置的服务器可能表现出非常规特征,导致误判
云厂商技术更新:各云服务提供商可能随时更新其底层技术架构,改变原有的识别特征
人为干扰因素:故意伪装或安全加固措施可能有意掩盖环境特征,干扰检测结果
边缘案例和特殊情况:某些混合环境或边缘计算场景可能无法被现有检测逻辑完全覆盖
使用者应意识到:
本脚本的检测结果应作为参考依据之一,而非唯一决策标准
重要环境判断建议结合多种工具和手动验证
生产环境的关键决策应基于更全面的技术评估
作者不对因使用本脚本而产生的任何直接或间接损失负责