PVE集群取证

当我们成功仿真出PVE服务器的时候,往往需要进行网络配置,才能搭建出完整的PVE网络架构

PVE 基础知识

什么是 PVE

Proxmox Virtual Environment(PVE)是基于 Debian 的开源虚拟化平台,底层使用 KVM/QEMU 运行虚拟机(VM)、使用 LXC 运行容器(CT),并内置 Web 管理面板。集群模式下通过 Corosync 做节点间通信与仲裁,通过 pmxcfs(基于 FUSE 的集群文件系统)把集群配置同步到所有节点的 /etc/pve 目录。

取证要点速览

类别关键位置
Web 管理面板https://<IP>:8006(root@pam 登录)
集群配置(在线)/etc/pve/(pmxcfs 虚拟文件系统,由 pve-cluster 服务挂载)
集群配置(离线)/var/lib/pve-cluster/config.db(SQLite,pmxcfs 的真实后端)
集群通信配置/etc/pve/corosync.conf、/etc/corosync/corosync.conf
VM 配置/etc/pve/qemu-server/<vmid>.conf
CT 配置/etc/pve/lxc/<vmid>.conf
存储定义/etc/pve/storage.cfg
用户与权限/etc/pve/user.cfg、/etc/pve/priv/acl.cfg、/etc/pve/priv/shadow.cfg
Ceph 配置/etc/pve/ceph.conf、/etc/ceph/ceph.conf
本地存储默认路径/var/lib/vz/(镜像 images/<vmid>/、备份 dump/)
GUI 访问日志/var/log/pveproxy/access.log
任务日志/var/log/pve/tasks/

离线取证技巧:/etc/pve 是空的怎么办

/etc/pve 由 pve-cluster 服务挂载,仿真环境中若该服务未启动,目录会是空的。真实数据保存在 /var/lib/pve-cluster/config.db 中,两种提取方式:

# 方法一:本地模式启动 pmxcfs,强制挂载 /etc/pve
pmxcfs -l

# 方法二:直接解析 SQLite 数据库
sqlite3 /var/lib/pve-cluster/config.db "SELECT * FROM tree;"

仿真环境网络配置

启动网卡

仿真出的 PVE 服务器默认网卡未启用,需手动拉起并获取 IP:

ip link set ens33 up
dhclient ens33

绑定网卡

由于PVE内部存在虚拟网卡vmbr,需要我们绑定真实网卡

brctl addif vmbr0 ens33
# 或无 bridge-utils 时使用 iproute2:
ip link set ens33 master vmbr0

访问 Web 管理面板

https://<仿真机IP>:8006

登录用户为 root@pam,密码即系统 root 密码。若面板无法访问,检查服务状态:

systemctl status pveproxy pvedaemon pve-cluster pvestatd
systemctl restart pveproxy pvedaemon

时钟偏差

有时候仿真出来的几台PVE会有偏差,导致服务中断,需要同步时间

#1. 关闭自动同步(防止 chrony/NTP 与手动设置打架)
timedatectl set-ntp false
systemctl stop chrony && systemctl disable chrony

#2.手动统一时间(在每台节点上执行,时间保持一致)
timedatectl set-timezone Asia/Shanghai
timedatectl set-time "2024-01-01 12:00:00"
hwclock --systohc        # 同步写入硬件时钟 RTC

#3.确认时间一致(逐台执行比对)
date
timedatectl

#4.重启服务(corosync/ceph 对时钟敏感,时间一致后重启恢复集群)
systemctl restart corosync pve-cluster pveproxy pvedaemon
systemctl restart ceph*

系统取证

基本系统信息

主机版本号

pveversion -v          # PVE 及全部相关软件包版本(最重要)
cat /etc/pve/.version  # 仅 PVE 主版本
cat /etc/os-release    # 底层 Debian 版本

主机内核版本

uname -a
uname -r               # PVE 使用定制内核,形如 6.x.x-x-pve
proxmox-boot-tool kernel list   # 已安装内核列表

主机名与节点列表

hostnamectl
cat /etc/hostname
cat /etc/hosts         # 集群各节点的 IP/主机名映射常记录在此

时间服务器地址

PVE 7 及以上默认使用 chrony:

cat /etc/chrony/chrony.conf    # server/pool 行即时间源
chronyc sources                # 在线状态查看
timedatectl                    # 时区与时间同步状态

集群信息

集群状态

pvecm status    # 集群名、配置版本、节点数、Quorum 状态、各节点 IP
pvecm nodes     # 节点 ID 与节点名列表

集群配置文件

cat /etc/pve/corosync.conf      # 集群名、节点列表(ring0_addr 即各节点通信 IP)
cat /etc/corosync/corosync.conf # 若上者不存在时的本地副本

corosync.conf 中 nodelist 段记录了集群全部节点名与 IP,totem 段的 config_version 每变更一次集群配置自增 1,可用于判断配置被修改的次数。

集群证书

/etc/pve/pve-root-ca.pem                    # 集群根 CA
/etc/pve/nodes/<node>/pve-ssl.pem           # 节点 Web 面板证书
/etc/pve/priv/known_hosts                   # 集群节点 SSH 指纹

虚拟机与容器取证

VM 列表与配置

qm list                    # VMID、名称、状态、内存、PID
qm config <vmid>           # 完整配置
qm showcmd <vmid>          # 还原出的完整 QEMU 命令行(含磁盘、网卡、CPU 参数)

配置文件位于 /etc/pve/qemu-server/<vmid>.conf,关键字段:

  • name —— 虚拟机名称
  • memory、cores、sockets —— 资源配置
  • scsi0/virtio0/sata0/ide0 —— 磁盘挂载(含存储池与卷名,如 local-lvm:vm-100-disk-0)
  • net0 —— 网卡 MAC 地址与所接网桥(vmbr)
  • ostype —— 操作系统类型(win10/l26 等)
  • [snapname] 段 —— 快照定义及其时间点配置

导出虚拟机

有时候需要导出PVE内部的虚拟机进行进一步操作(重置密码、静态取证扫描等),这时候就需要导出虚拟机

前置:保证镜像一致性

直接拷贝运行中 VM 的磁盘镜像会得到不一致(损坏)的文件系统,先停机或做快照:

qm shutdown <vmid>        # 优雅关机(推荐)
qm stop <vmid>            # 强制停止
# 不能停机时用快照模式备份(见方法一)

方法一:vzdump 备份导出(推荐)

PVE 官方导出方式,产物自带配置与日志:

vzdump <vmid> --dumpdir /var/lib/vz/dump --compress zstd
# 在线导出(不停机,先打内部快照再备份):
vzdump <vmid> --mode snapshot --dumpdir /var/lib/vz/dump --compress zstd

产物在 /var/lib/vz/dump/:vzdump-qemu-<vmid>-<时间>.vma.zst(数据)+ .log(备份日志)+ .notes。还原成磁盘镜像:

zstd -d vzdump-qemu-<vmid>-<时间>.vma.zst        # 得到 .vma
vma extract vzdump-qemu-<vmid>-<时间>.vma ./out  # 解压出 raw 磁盘 + qemu-server.conf

./out 下的 disk-drive-scsi0.raw 等即为可直接分析的 raw 镜像。

方法二:直接拷贝磁盘镜像

根据 qm config <vmid> 中磁盘行(如 scsi0: local-lvm:vm-100-disk-0)确定存储类型后拷贝:

# 目录存储(qcow2/raw/vmdk 文件)
cp /var/lib/vz/images/<vmid>/vm-<vmid>-disk-0.qcow2 /导出目录/

# LVM-Thin 存储(逻辑卷,用 dd 提取为 raw)
lvs                                                  # 确认卷名
dd if=/dev/pve/vm-<vmid>-disk-0 of=/导出目录/vm-<vmid>.raw bs=4M status=progress

# Ceph RBD 存储
rbd ls rbd                                           # 列出卷
rbd export rbd/vm-<vmid>-disk-0 /导出目录/vm-<vmid>.raw

# Ceph RBD 存储(压缩包方式导出,镜像稀疏空间大时显著减小体积)
rbd export rbd/vm-<vmid>-disk-0 - | zstd -T0 > /导出目录/vm-<vmid>.raw.zst
# 还原:
zstd -d /导出目录/vm-<vmid>.raw.zst
# 也可用 tar 打包并连同 VM 配置一起归档:
tar -I 'zstd -T0' -cvf /导出目录/vm-<vmid>.tar.zst \
    -C /导出目录 vm-<vmid>.raw -C /etc/pve/qemu-server <vmid>.conf

注意:

  • qcow2 快照链:qemu-img info 检查是否有 backing file,有的话必须把整条链一起拷贝,否则镜像打不开
  • Windows VM 的附属磁盘:EFI 启动盘(efidisk0)、TPM 状态盘(tpmstate0)是独立的小卷,开了 BitLocker/安全启动的 Windows 少了它们会无法引导,导出时一并带上

格式转换

取证工具和仿真软件对格式要求不同,用 qemu-img 转换:

qemu-img info vm-<vmid>-disk-0.qcow2                 # 确认格式与快照链
qemu-img convert -O raw  vm-<vmid>-disk-0.qcow2 vm-<vmid>.raw    # 转 raw(取证工具通用)
qemu-img convert -O vmdk vm-<vmid>-disk-0.qcow2 vm-<vmid>.vmdk   # 转 vmdk(导入 VMware 仿真)
qemu-img convert -O vdi  vm-<vmid>-disk-0.qcow2 vm-<vmid>.vdi    # 转 vdi(导入 VirtualBox)

PVE 不支持直接导出 OVA/OVF,需要导入 VMware/VirtualBox 时先转 vmdk/vdi 再手动建虚拟机挂载。

带走配置文件

磁盘之外,VM 的硬件配置(MAC、内存、磁盘顺序)对仿真还原很重要:

cp /etc/pve/qemu-server/<vmid>.conf /导出目录/

传出与校验

# 传出(视网络情况选择)
scp /导出目录/* user@<取证机>:/path/
# 或挂载移动硬盘 / nc 直传

# 完整性校验(取证流程必须)
sha256sum /导出目录/vm-<vmid>.raw | tee vm-<vmid>.sha256

导出后的常见操作

# 挂载分析(Linux 镜像)
modprobe nbd max_part=8
qemu-nbd --connect=/dev/nbd0 vm-<vmid>.raw
mount /dev/nbd0p1 /mnt

# libguestfs 工具集(自动识别分区/系统)
guestmount -a vm-<vmid>.raw -i --ro /mnt
virt-cat  -a vm-<vmid>.raw /etc/shadow

# Windows 镜像重置密码(挂载后操作 SAM 蜂巢)
chntpw -i /mnt/Windows/System32/config/SAM

LXC 容器

pct list                   # CTID、名称、状态
pct config <ctid>          # 完整配置
pct mount <ctid>           # 将容器根文件系统挂载出来直接取证

配置文件位于 /etc/pve/lxc/<vmid>.conf,容器根文件系统默认在 /var/lib/vz/private/<vmid>/ 或 subvol 中。

磁盘镜像

qemu-img info <镜像文件>    # 格式、虚拟大小、实际占用、快照链
  • 目录存储:/var/lib/vz/images/<vmid>/ 下的 qcow2/raw/vmdk
  • LVM-Thin 存储:lvs 查看,卷路径为 /dev/pve/vm-<vmid>-disk-x
  • 仿真中挂载镜像分析:qemu-nbd --connect=/dev/nbd0 <镜像>

快照

qm listsnapshot <vmid>     # 快照树

快照的完整配置(含当时的内存/磁盘状态)嵌在 <vmid>.conf 的 [快照名] 段内。

启动与计划任务

cat /etc/pve/vzdump.cron   # 定时备份计划
crontab -l
systemctl list-timers

存储取证

存储定义

cat /etc/pve/storage.cfg   # 全部存储池定义(dir/lvmthin/nfs/rbd/zfspool…)
pvesm status               # 各存储池容量与使用情况

本地存储

  • local(dir 类型):/var/lib/vz/
    • images/<vmid>/ —— 磁盘镜像
    • dump/ —— vzdump 备份(vzdump-qemu-<vmid>-<时间>.vma.zst/.vma.gz,配套 .log)
    • template/iso/ —— ISO 镜像
    • private/<vmid>/ —— LXC 根文件系统
  • local-lvm(lvmthin 类型):lvs 列出全部逻辑卷

备份文件

ls /var/lib/vz/dump/
vma extract <备份.vma> <输出目录>   # 解压 vma 备份还原磁盘镜像(.zst 需先 zstd -d)

备份日志 vzdump-qemu-<vmid>-<时间>.log 记录了备份时间、耗时、结果。

ceph配置

搭建

查看ceph集群状态

ceph status

查看服务状态

journalctl -u "ceph*" -e --no-pager #里面有ceph的IP信息

起临时IP

ip addr add 192.168.170.50/24 dev vmbr0
ip addr add 192.168.170.51/24 dev vmbr0
ip addr add 192.168.170.52/24 dev vmbr0

重启ceph

systemctl restart ceph*

基本信息

配置信息

ceph osd ls detail

可以看到资源池的名称、类别

集群ID

ceph fsid

存储信息

ceph osd pool get <pool_name> <command>

可以看到存储池的信息,常见如下:

  • 最小副本数
    • ceph osd pool get <pool_name> min_size
  • 副本数
    • ceph osd pool get <pool_name> size
  • 归置组数
    • ceph osd pool get <pool_name> pg_num
  • 一次性列出全部存储池及参数
    • ceph osd pool ls detail

OSD 与磁盘

ceph osd tree            # OSD 拓扑:每台主机挂了哪些 OSD、权重、状态
ceph-volume lvm list     # OSD 对应的物理磁盘/LVM 卷
ceph df                  # 各存储池用量

Monitor 信息

ceph mon dump            # MON 节点 IP 与端口(与仿真时起临时 IP 对应)
ceph quorum_status       # 仲裁状态

认证信息

ceph auth list                          # 全部客户端用户与密钥(admin、osd、mgr…)
cat /etc/ceph/ceph.client.admin.keyring # admin 密钥

配置文件

cat /etc/pve/ceph.conf    # PVE 管理的 Ceph 配置(集群 FSID、MON 列表)
cat /etc/ceph/ceph.conf   # 实际生效的配置

用户与权限取证

用户列表

cat /etc/pve/user.cfg      # 用户、组、Token、资源池

格式示例:user:zhangsan@pve:1:1718000000::::zhangsan@example.com:Zhang San,字段依次为启用状态、过期时间戳、姓名、邮箱等。常见 Realm:

  • root@pam —— 使用 Linux 系统账户认证(密码哈希在 /etc/shadow)
  • xxx@pve —— PVE 内置账户(密码哈希在 /etc/pve/priv/shadow.cfg,可交给 hashcat 破解)
  • xxx@ldap / xxx@ad —— 外部认证源(配置见 /etc/pve/domains.cfg)

权限分配

cat /etc/pve/priv/acl.cfg   # 用户对 VM/存储/路径的角色分配(Administrator/PVEAdmin…)
pveum user list
pveum acl list

双因素认证

cat /etc/pve/priv/tfa.cfg   # TOTP/WebAuthn 配置

日志取证

Web 面板登录日志(重点)

cat /var/log/pveproxy/access.log

记录每次 GUI/API 访问的来源 IP、账号、时间,可还原管理员的登录行为与暴力破解痕迹。

任务日志

ls /var/log/pve/tasks/     # 按 UPID 命名的任务记录:VM 启停、备份、迁移、删除
cat /var/log/pve/tasks/index

谁在什么时间对哪台 VM 做了什么操作,基本都留有 UPID 记录,是操作审计的核心来源。

系统与服务日志

journalctl -u pveproxy -u pvedaemon -u pve-cluster -u corosync
cat /var/log/auth.log                     # SSH/PAM 登录记录
cat /var/log/syslog
cat /var/log/corosync/corosync.log        # 集群成员变动、脑裂记录
cat /var/log/pve/firewall.log             # PVE 防火墙命中记录

Ceph 日志

journalctl -u "ceph*" -e --no-pager
ls /var/log/ceph/        # ceph-mon、ceph-osd、ceph-mgr 的详细日志