HOME

ESXi 6.0 与 VCSA 6.0 日志集中转发到 Linux 审计中转机

文章目录13 节

这次实验来自一个审计场景:现场有一套比较老的 vSphere 6.0 环境,需要审计 ESXi 6.0VCSA 6.0 的日志,但审计系统只接入一台 Linux 中转机。也就是说,最终被审计的对象不是每台 VMware 设备本身,而是这台 Linux 日志中转机。

一开始容易想到的方案是:只把 ESXi 和 VCSA 上的关键进程日志收集出来,再发到 Linux。实际验证后,这个思路在 ESXi 侧并不适合作为主方案。ESXi 的远程 syslog 更适合做整机日志转发,细粒度筛选应该放到 Linux 中转机上完成。

所以本次实验采用的方案是: 通过这篇记录,我们会完成三件事:

  • 在 Linux 上搭建 VMware 日志接收入口;
  • 让 ESXi 6.0 和 VCSA 6.0 把日志完整发到 Linux;
  • 在 Linux 侧同时保存全量日志和筛选后的审计日志。

实验环境

本次实验使用三台机器:

角色IP系统或版本用途
ESXi10.0.100.5VMware ESXi 6.0.0 build-9313334被审计主机
VCSA10.0.100.7VMware vCenter Server Appliance 6.0.0,底层为 SLES 11 SP4被审计 vCenter
Linux 中转机10.0.100.8Rocky Linux 9.7接收、筛选、保存日志

实验阶段使用 TCP 514。生产环境如果有合规要求,建议把链路升级到 TLS 6514。这篇先把最小可验证链路跑通,TLS 放在后续加固步骤中处理。

为什么把筛选放到 Linux

syslog 是传统日志转发协议,常见传输方式包括 UDPTCPTLS over TCP。审计场景里不建议优先使用 UDP,因为 UDP 不保证送达,丢日志时很难证明链路完整性。

ESXi 支持配置远程 syslog,例如通过 esxcli system syslog config set --loghost=... 指向远端日志服务器。但 ESXi 侧不适合把“只转发某几个日志文件”作为设计前提。对于审计来说,更稳妥的边界是:

  • 源端只负责完整转发;
  • Linux 中转机保存一份 raw 原始日志;
  • Linux 中转机再按程序名、标签或内容筛选出 audit 日志;
  • 审计系统只审 Linux 中转机上的结果。

这样做有两个好处。第一,源端改动少,不需要在 ESXi 或 VCSA 上做复杂采集脚本。第二,审计链路更好解释:完整日志先进入中转机,筛选规则也集中在中转机上,后续调整审计范围不用频繁改 VMware 设备。

Linux 中转机准备

中转机使用 rsyslog 接收 TCP syslog。先确认服务状态:

hostnamectl
systemctl is-active rsyslog
systemctl is-enabled rsyslog
ss -lntup | grep -E ':(514|6514)\b' || true
df -h /

本次实验确认到的信息如下:

Operating System: Rocky Linux 9.7 (Blue Onyx)
rsyslog: active / enabled
SELinux: Disabled
NTP: active
根分区可用空间约 34G

实验目录设计如下:

/data/vmware-logs/raw
/data/vmware-logs/audit
/data/vmware-logs/hash

其中:

  • raw 保存源端发来的完整日志;
  • audit 保存筛选后的审计日志;
  • hash 保存每日 sha256 摘要。

注意:本次实验里 /data 实际仍在根分区上。正式环境建议给 /data/vmware-logs 单独挂载磁盘,并按保留周期计算容量。

配置 Linux 接收和筛选规则(主要规则)

在中转机上创建目录:

mkdir -p /data/vmware-logs/raw /data/vmware-logs/audit /data/vmware-logs/hash

新增 rsyslog 配置文件:

vi /etc/rsyslog.d/10-vmware-audit-relay.conf

写入以下内容:

# VMware audit relay: receive full ESXi/VCSA syslog over TCP/514.
# All remote VMware logs go to raw/. Selected audit-relevant tags also go to audit/.
module(load="imtcp")

template(name="vmwareRawBySource" type="string" string="/data/vmware-logs/raw/%$.src%/%$YEAR%-%$MONTH%-%$DAY%.log")
template(name="vmwareAuditBySource" type="string" string="/data/vmware-logs/audit/%$.src%/%$YEAR%-%$MONTH%-%$DAY%.log")

ruleset(name="vmware_remote") {
    set $.src = $fromhost-ip;
    if ($fromhost-ip == "") then set $.src = $fromhost;

    action(
        type="omfile"
        dynaFile="vmwareRawBySource"
        createDirs="on"
        dirCreateMode="0750"
        fileCreateMode="0640"
    )

    if (
        $syslogtag contains_i "hostd" or
        $syslogtag contains_i "vpxa" or
        $syslogtag contains_i "vmkernel" or
        $syslogtag contains_i "vmkwarning" or
        $syslogtag contains_i "auth" or
        $syslogtag contains_i "shell" or
        $syslogtag contains_i "fdm" or
        $syslogtag contains_i "esxupdate" or
        $syslogtag contains_i "vpxd" or
        $syslogtag contains_i "sso" or
        $syslogtag contains_i "vmdird" or
        $syslogtag contains_i "vapi" or
        $syslogtag contains_i "vsphere-client" or
        $syslogtag contains_i "vpostgres" or
        $syslogtag contains_i "eam" or
        $syslogtag contains_i "sps" or
        $programname contains_i "hostd" or
        $programname contains_i "vpxa" or
        $programname contains_i "vmkernel" or
        $programname contains_i "vmkwarning" or
        $programname contains_i "auth" or
        $programname contains_i "shell" or
        $programname contains_i "fdm" or
        $programname contains_i "esxupdate" or
        $programname contains_i "vpxd" or
        $programname contains_i "sso" or
        $programname contains_i "vmdird" or
        $programname contains_i "vapi" or
        $programname contains_i "vsphere-client" or
        $programname contains_i "vpostgres" or
        $programname contains_i "eam" or
        $programname contains_i "sps"
    ) then {
        action(
            type="omfile"
            dynaFile="vmwareAuditBySource"
            createDirs="on"
            dirCreateMode="0750"
            fileCreateMode="0640"
        )
    }

    stop
}

input(type="imtcp" port="514" ruleset="vmware_remote")

这份配置做了两层保存:

  • 所有远端日志都写入 raw/<来源IP>/<日期>.log
  • 命中 VMware 关键组件标签的日志,再写入 audit/<来源IP>/<日期>.log

筛选条件里使用了 contains_i,这是大小写不敏感匹配。实际 ESXi 发来的标签可能是 Vpxa,如果只写小写精确匹配,容易漏掉。

校验并重启 rsyslog

rsyslogd -N1
systemctl restart rsyslog
ss -lntp | grep ':514'

如果启用了 firewalld,放通 TCP 514我做实验的时候是直接防火墙和 selinux 都关了的:

firewall-cmd --permanent --add-port=514/tcp
firewall-cmd --reload

本次实验校验结果:

rsyslogd: End of config validation run. Bye.
LISTEN 0 25 0.0.0.0:514 users:(("rsyslogd",pid=1907,fd=4))
LISTEN 0 25 [::]:514 users:(("rsyslogd",pid=1907,fd=5))

配置日志轮转和每日摘要

实验阶段先设置每日轮转,保留 14 份,这个就要根据审计的需要保留多少天了,如果是等保那就把天数改成 6 个月:

vi /etc/logrotate.d/vmware-audit-relay

内容如下:

/data/vmware-logs/raw/*/*.log /data/vmware-logs/audit/*/*.log {
    daily
    rotate 14
    missingok
    notifempty
    compress
    delaycompress
    dateext
    create 0640 root root
    sharedscripts
    postrotate
        /bin/systemctl kill -s HUP rsyslog.service >/dev/null 2>&1 || true
    endscript
}

再创建每日 hash 脚本:

vi /etc/cron.daily/vmware-log-hash
chmod 0755 /etc/cron.daily/vmware-log-hash

脚本内容:

#!/bin/sh
set -eu
base=/data/vmware-logs
out="$base/hash/$(date +%F).sha256"
find "$base/raw" "$base/audit" -type f -name '*.log*' -print0 | sort -z | xargs -0 sha256sum > "$out.tmp"
mv "$out.tmp" "$out"
chmod 0640 "$out"

实验中手动执行一次:

/etc/cron.daily/vmware-log-hash
ls -l /data/vmware-logs/hash/$(date +%F).sha256
sed -n '1,10p' /data/vmware-logs/hash/$(date +%F).sha256

这一步不是为了替代专业的日志防篡改平台,而是给中转机上的日志保全留一条最低成本的证据链,不然一会儿审计的时候说我们伪造日志那就麻烦了,一个小步骤可以省很多麻烦。

配置 ESXi 6.0 远程 syslog(重要配置之一)

先查看 ESXi 版本和当前 syslog 配置:

vmware -v
hostname
esxcli system syslog config get
esxcli network firewall ruleset list | grep -i syslog
esxcli system time get

本次实验的 ESXi 信息:

VMware ESXi 6.0.0 build-9313334
hostname: localhost.lan
Remote Host: udp://10.0.100.3:514
syslog firewall ruleset: true

现场已经存在一个旧的 syslog 目标 udp://10.0.100.3:514,所以本次没有覆盖它,而是追加新的 Linux 中转机目标:

current=$(esxcli system syslog config get | awk -F': ' '/Remote Host:/ {print $2}')

case "$current" in
  *tcp://10.0.100.8:514*) new="$current" ;;
  ""|none|None) new="tcp://10.0.100.8:514" ;;
  *) new="$current,tcp://10.0.100.8:514" ;;
esac

esxcli system syslog config set --loghost="$new"
esxcli network firewall ruleset set --ruleset-id=syslog --enabled=true
esxcli network firewall refresh
esxcli system syslog reload

再发一条 marker:

esxcli system syslog mark --message="codex-esxi-syslog-marker-20260624"

配置完成后,ESXi 当前远端目标为:

Remote Host: udp://10.0.100.3:514,tcp://10.0.100.8:514

配置 VCSA 6.0 远程转发

VCSA 6.0 登录后默认可能进入 appliance shell,不一定直接是 Linux bash。可以先启用并进入 shell:

shell.set --enabled true
shell

查看 VCSA 系统和日志服务:

hostname
uname -a
cat /etc/*release 2>/dev/null | head -20
ps -ef | grep -E '[r]syslog|[s]yslog-ng|[v]msyslog|[s]yslog'
/etc/init.d/vmware-syslog status

本次实验确认到:

VMware vCenter Server Appliance 6.0.0
SUSE Linux Enterprise Server 11 SP4
/sbin/rsyslogd -c 5 -f /etc/vmware-rsyslog.conf
syslog is running

VCSA 6.0 的主配置 /etc/vmware-rsyslog.conf 已经包含:

$IncludeConfig /etc/vmware-syslog/tls.conf
$IncludeConfig /etc/vmware-syslog/syslog.conf
$IncludeConfig /etc/vmware-syslog/custom-file-location.conf

其中 /etc/vmware-syslog/syslog.conf 是合适的转发配置入口。本次先备份原文件:

stamp=$(date +%Y%m%d%H%M%S)
cp -a /etc/vmware-syslog/syslog.conf /etc/vmware-syslog/syslog.conf.bak.$stamp

写入远程转发规则(记得要改成现场实际的 IP 地址,文章其他地方也是别跟我写的一样):

cat > /etc/vmware-syslog/syslog.conf <<'EOF'
# Added for VMware audit relay experiment on 2026-06-24.
# Forward all VCSA syslog messages to Linux relay 10.0.100.8 over TCP/514.
*.* @@10.0.100.8:514
EOF

在 rsyslog 5.x 语法中,@@host:port 表示 TCP 转发;单个 @host:port 表示 UDP,踩了这个小坑。

校验并重启 VCSA 的 syslog 服务:

/sbin/rsyslogd -c 5 -f /etc/vmware-rsyslog.conf -N1
/etc/init.d/vmware-syslog restart
/etc/init.d/vmware-syslog status

实验中校验结果:

rsyslogd: version 5.10.1, config validation run (level 1), master config /etc/vmware-rsyslog.conf
rsyslogd: End of config validation run. Bye.
syslog is running, PID: 31381

然后发送测试日志:

logger -t Vpxd 'codex-vcsa-syslog-marker-20260624'
logger -t vsphere-client 'codex-vcsa-vsphere-client-marker-20260624'
logger -t vpostgres 'codex-vcsa-vpostgres-marker-20260624'

在 Linux 中转机验证

先查 ESXi:

grep -R "codex-esxi-syslog-marker-20260624" /data/vmware-logs/raw /data/vmware-logs/audit 2>/dev/null || true
tail -n 10 /data/vmware-logs/raw/10.0.100.5/$(date +%F).log
tail -n 10 /data/vmware-logs/audit/10.0.100.5/$(date +%F).log

实验中收到的 ESXi marker:

/data/vmware-logs/raw/10.0.100.5/2026-06-24.log:Jun 24 08:35:36 localhost.localdomain mark: codex-esxi-syslog-marker-20260624

audit 中也能看到持续的 hostdVpxa 相关日志,例如:

Jun 24 08:40:01 localhost.localdomain hostd-probe: Section for VMware ESX, pid=37723, version=6.0.0, build=9313334, option=Release
Jun 24 08:40:02 localhost.localdomain Vpxa: verbose vpxa[3314EB70] [Originator@6876 sub=SoapAdapter] Responded to service state request

再查 VCSA:

grep -R "codex-vcsa" /data/vmware-logs/raw /data/vmware-logs/audit 2>/dev/null || true
tail -n 20 /data/vmware-logs/raw/10.0.100.7/$(date +%F).log
tail -n 20 /data/vmware-logs/audit/10.0.100.7/$(date +%F).log

实验中收到的 VCSA marker:

/data/vmware-logs/raw/10.0.100.7/2026-06-24.log:Jun 24 08:38:20 localhost Vpxd: codex-vcsa-syslog-marker-20260624
/data/vmware-logs/audit/10.0.100.7/2026-06-24.log:Jun 24 08:38:20 localhost Vpxd: codex-vcsa-syslog-marker-20260624
/data/vmware-logs/audit/10.0.100.7/2026-06-24.log:Jun 24 08:39:27 localhost vsphere-client: codex-vcsa-vsphere-client-marker-20260624
/data/vmware-logs/audit/10.0.100.7/2026-06-24.log:Jun 24 08:39:27 localhost vpostgres: codex-vcsa-vpostgres-marker-20260624

同时,VCSA 的 raw 日志里能看到更多系统和组件日志,例如 audispdvmafddsuvpostgres。这说明“全量进入 raw,关键标签进入 audit”的链路已经成立。

最后看文件结构:

find /data/vmware-logs -maxdepth 3 -type f -printf '%p %s bytes\n' | sort

实验输出:

/data/vmware-logs/audit/10.0.100.5/2026-06-24.log
/data/vmware-logs/audit/10.0.100.7/2026-06-24.log
/data/vmware-logs/raw/10.0.100.5/2026-06-24.log
/data/vmware-logs/raw/10.0.100.7/2026-06-24.log
/data/vmware-logs/hash/2026-06-24.sha256

生产环境要补上的几件事

再次提醒!实验链路跑通后,生产环境不能只照搬 IP 和路径,还要补几项设计。

单独规划日志磁盘

全量日志会持续增长,尤其是 ESXi 上 vpxahostdrhttpproxy 这类日志在繁忙环境中增长很快。正式环境建议:

  • /data/vmware-logs 单独挂载;
  • 日志盘最好使用 LVM 进行管理,方便空间的管理。
  • raw 保留周期短一些,例如 7 到 30 天,如果是等保的话就对应改成 6 个月,但是要注意空间;
  • audit 按审计要求保留,例如 180 天或 1 年;
  • hash 和归档文件放到更难被误删的位置。

保留回滚路径

ESXi 配置前先记录旧值:

esxcli system syslog config get

如果要撤回新增的中转机目标,重新设置原来的 Remote Host 后 reload:

esxcli system syslog config set --loghost='udp://10.0.100.3:514'
esxcli system syslog reload

VCSA 配置前已经备份:

/etc/vmware-syslog/syslog.conf.bak.<时间戳>

回滚时恢复备份并重启:

cp -a /etc/vmware-syslog/syslog.conf.bak.<时间> /etc/vmware-syslog/syslog.conf
/sbin/rsyslogd -c 5 -f /etc/vmware-rsyslog.conf -N1
/etc/init.d/vmware-syslog restart

来个本次实验小结

本次实验最终验证了这条链路:

ESXi 6.0 -> Linux 中转机 raw/audit
VCSA 6.0 -> Linux 中转机 raw/audit
Linux 中转机 -> logrotate/hash

从实施角度看,这个方案比“在 VMware 源端只采关键进程日志”更稳。源端只做完整转发,Linux 层做筛选、保留和审计,后续调整范围也集中在一台中转机上完成。

参考与引用

VMware ESXi VCSA Linux 日志审计