Velociraptor 端点取证的价值在于把「一台台 SSH 上去敲命令」变成「写一条查询、批量下发、回收结构化结果」。它用一个服务端加若干轻量客户端组成 mTLS 通道,客户端主动外连,不需要在防火墙上为每台机器开入向端口;服务端用 VQL(一种类 SQL 的查询语言)描述采集逻辑,把进程、网络连接、账号、文件时间线统一成可回放的证据。本文给出一套从零部署到批量响应的完整流程,适用于 Linux 与 Windows 混合环境。
适用场景
- 服务器出现异常登录、可疑进程或不明外连,需要在多台主机上同时定位,而不是逐台排查。
- 需要保留可复核的取证结果,事后能说明「当时查了什么、查到什么」。
- 主机分散在不同网段或云上,没有统一堡垒机,也不允许开放入向管理端口。
- 应急响应需要一次性拉取全量进程、监听端口、计划任务、近期改动的文件清单。
前置条件
- 一台 2 核 4G 以上的 Linux 主机作服务端,磁盘按「每台客户端 200MB」预留。
- 一个可解析的域名,例如 velo.example.com,指向服务端公网或内网地址。
- 客户端可主动外连服务端的 8000(前端 GUI/API)与 8889(gRPC 客户端通道)端口。
- 服务端与客户端时间同步,NTP 偏差控制在 1 分钟内。
- 具备在客户端安装 systemd 服务或 Windows 服务的权限。
原理说明
Velociraptor 采用「服务端拉、客户端推」的反向连接模型。客户端启动时用内置的 CA 证书向服务端 8889 端口发起 gRPC 长连接,双方以 mTLS 互相校验;连接建立后,服务端可以下发查询请求,客户端在本地执行并把结果回传。因此客户端不需要任何入向端口,NAT 与云安全组都能正常工作。
采集逻辑由 VQL 表达,本质是对一组 Plugin(如 process、netstat、glob、registry)做查询与关联,输出是行式结果集。把 VQL 封装成带参数的 Artifact,就能复用;对多台客户端同时下发同一个 Artifact 的动作叫 Hunt,结果按客户端分目录归档,可导出为 JSON 或 CSV。这条链条让取证从「手工操作」变成「可版本化、可复跑的证据采集」。
操作步骤
第一步:部署服务端并生成配置
下载官方二进制后,用交互式向导生成配置。向导会要求填写主机名、前端端口与数据目录,其余保持默认即可:
# 1) 下载并解压(版本号按官方最新稳定版替换)
curl -L -o velo.tar.gz \
https://github.com/Velocidex/velociraptor/releases/latest/download/velociraptor-v0.7.2-linux-amd64
mkdir -p /opt/velociraptor && mv velo.tar.gz /opt/velociraptor/
cd /opt/velociraptor && chmod +x velociraptor-v0.7.2-linux-amd64
ln -sf velociraptor-v0.7.2-linux-amd64 velociraptor
# 2) 交互式生成配置,Frontend hostname 填 velo.example.com
./velociraptor config generate -i
# 3) 校验配置
./velociraptor --config server.config.yaml config show > /dev/null && echo OK
生成的 server.config.yaml 含服务端私钥与 CA,权限必须收紧到 600,只给运行用户可读。数据目录默认在配置的 Datastore.location 下,建议单独挂一块盘。
第二步:用 systemd 托管服务端
cat > /etc/systemd/system/velociraptor.service <<'EOF'
[Unit]
Description=Velociraptor Server
After=network.target
[Service]
Type=simple
User=velociraptor
Group=velociraptor
ExecStart=/opt/velociraptor/velociraptor --config /opt/velociraptor/server.config.yaml frontend
Restart=always
RestartSec=5
LimitNOFILE=65536
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload && systemctl enable --now velociraptor
systemctl status velociraptor --no-pager | head -12
ss -lntp | grep -E "8000|8889"
前端 8000 建议不直接对公网开放,而是在前面挂一层 Nginx 做 TLS 终止与访问控制,只放行运维出口 IP。客户端通道 8889 必须对客户端网段可达,且要支持 HTTP/2,反代时不要关掉长连接。
第三步:生成客户端安装包并部署
# 1) 导出客户端配置(内含服务端地址与证书,属于敏感文件)
./velociraptor --config server.config.yaml config client > client.config.yaml
# 2) 打包成自解压安装包,repo 指向服务端
./velociraptor --config server.config.yaml config repack \
--exe velociraptor-v0.7.2-linux-amd64 \
client.config.yaml client_linux.tar.gz
# 3) 在目标主机安装(systemd 方式,自动注册为服务)
tar xzf client_linux.tar.gz -C /tmp
/tmp/velociraptor client.config.yaml service install --config /tmp/client.config.yaml
systemctl status velociraptor_client --no-pager | head -8
Windows 主机用同一个 client.config.yaml 配合 velociraptor.exe 执行 service install,或用 MSI 打包后通过组策略分发。客户端配置里含有服务端证书与私钥信息,不要放进公开的制品库或镜像层。
第四步:VQL 查询与 Hunt 批量下发
先进 GUI(https://velo.example.com:8000/)创建独立运维账号,不要共用 admin。随后在「Notebook」里跑查询验证语法,再封装成 Hunt 下发。以下三条查询覆盖应急中最常用的取证面:
-- 1) 可疑进程:无签名、异常父进程、从临时目录启动
SELECT Pid, Ppid, Name, Exe, CommandLine, Username, StartTime
FROM process()
WHERE Exe =~ "(?i)/tmp/|/dev/shm/|AppData\\\\Temp"
OR CommandLine =~ "(?i)curl .*\\| *sh|base64 -d|nc -e"
ORDER BY StartTime DESC
-- 2) 外连排查:非标准端口 ESTABLISHED 连接
SELECT Pid, Laddr.IP AS LocalIP, Laddr.Port AS LocalPort,
Raddr.IP AS RemoteIP, Raddr.Port AS RemotePort, Status
FROM netstat()
WHERE Status = "ESTABLISHED"
AND Raddr.Port NOT IN (80, 443, 53, 22, 3306)
ORDER BY RemotePort
-- 3) 近期被改动的可执行文件(24 小时内)
SELECT FullPath, Size, Mtime, Mode
FROM glob(globs="/usr/bin/*,/usr/sbin/*,/etc/cron*")
WHERE Mtime > timestamp(epoch=now() - 86400)
ORDER BY Mtime DESC
把查询保存为自定义 Artifact(参数化 globs 与时间窗口),然后在客户端列表里全选 → Run Hunt → 选择该 Artifact → 设定并发与超时。Hunt 的默认并发是有限制的,几百台规模建议把 Resources 里的并发调到 20~30,避免客户端同时被拉满 IO。
配置验证
- 服务端存活:
systemctl is-active velociraptor返回 active,ss -lntp能看到 8000 与 8889 处于 LISTEN。 - 客户端上线:GUI 的 Client List 出现新主机,Last Seen 在两分钟内刷新;离线客户端在该列会显示较早时间。
- 本地自测:在客户端主机执行
velociraptor query "SELECT * FROM info()",能返回 hostname、OS、架构即说明二进制与配置正常。 - Hunt 结果:Hunt 详情页的 Completed 数等于目标客户端数,展开后每台机器都有 JSON 结果;若出现大量 Timeout,先查客户端到 8889 的连通性与 MTU。
- 权限验证:用只读账号登录,确认无法删除客户端、无法修改配置,避免取证平台本身成为权限放大器。
常见问题(FAQ)
FAQ 1:客户端一直显示离线,但端口是通的?
先看客户端日志(Linux 在 /var/log/velociraptor.log,Windows 在安装目录的 logs 下),最常见的原因是证书不匹配:client.config.yaml 必须来自当前服务端的同一份配置,服务端重建过 CA 之后旧客户端全部失效,需要重新下发。其次是时间偏差,mTLS 校验对时钟敏感,NTP 未同步时会直接握手失败。第三种是反向代理:Nginx 默认会缓冲并超时切断长连接,gRPC 通道需要显式开启 HTTP/2 并设置较长的 proxy_read_timeout。
FAQ 2:Hunt 一次下发几百台会不会把网络打满?
会,如果不限制并发与结果大小。三个参数必须调:Hunt 的并发数控制在 20~30;Artifact 里对 glob 的范围做收敛,不要用 /** 全盘扫描;对返回行数设上限,否则单台机器几万行的进程历史会把服务端磁盘吃掉。建议先在 5 台机器上跑一次,看单机结果体积与耗时,再按线性关系估算全量规模。
FAQ 3:采集到的数据涉及员工隐私或业务数据,怎么合规?
把采集范围写进应急响应预案并留存审批记录:只采集与事件相关的进程、网络连接、账号与指定目录文件,不做全盘镜像、不采集浏览器历史与个人目录内容。数据目录按事件编号隔离,设定保留期(例如 90 天)后自动清理,访问权只给事件负责人。Velociraptor 的 Hunt 结果可以按 Hunt ID 整体导出与删除,正好对应「一事一档」的管理方式。
总结
Velociraptor 端点取证的落地可以归纳为四步:服务端用 systemd 托管并对内网暴露 8000/8889,前端再套一层反代做访问控制;客户端通过 client.config.yaml 反向连接,不需要任何入向端口;用 VQL 把排查动作写成可复跑的查询,重点是进程、网络、文件时间线三个面;用 Hunt 批量下发并归档结果,配合并发与保留期控制规模。把这三类查询固化成 Artifact 之后,下一次事件的定位时间通常能从几小时压到十几分钟。