Hadoop集群取证
当我们成功仿真出 Hadoop 集群的各个节点(NameNode、DataNode、ResourceManager、NodeManager)后,往往需要恢复 HDFS 与 YARN 服务,才能提取集群元数据、业务数据和作业日志。Hadoop 集群对主机名解析和时钟同步非常敏感,仿真后第一步通常是修通网络与时间。
Hadoop 基础知识
什么是 Hadoop
Hadoop 是开源的分布式存储与计算平台,核心由两部分组成:
- HDFS(分布式文件系统):NameNode(NN)保存全部元数据(目录树、文件→块映射、权限),元数据以 fsimage(全量快照)+ edits(增量编辑日志)形式持久化在磁盘;DataNode(DN)保存实际数据块(block),默认副本数 3,定期向 NN 发送心跳与块报告。
- YARN(资源调度框架):ResourceManager(RM)统一分配集群资源;NodeManager(NM)运行在每个数据节点上,负责启动容器(Container)执行 MapReduce/Spark 等任务。
- 可选组件:SecondaryNameNode(定期合并 fsimage+edits,并非热备)、JournalNode(HA 模式下共享 edits)、ZKFC(HA 自动故障切换)、JobHistoryServer(MapReduce 历史作业)、TimelineServer(YARN 应用历史)。
生产环境常见发行版:Apache 原生(配置在 $HADOOP_HOME/etc/hadoop/)、CDH/CDP(/etc/hadoop/conf/)、HDP/Ambari。
取证要点速览
| 类别 | 关键位置 |
|---|---|
| 配置文件目录 | $HADOOP_HOME/etc/hadoop/(原生)或 /etc/hadoop/conf/(CDH/CDP,软链到 conf.<版本>/) |
| 核心配置 | core-site.xml、hdfs-site.xml、yarn-site.xml、mapred-site.xml、workers(旧版 slaves) |
| NameNode 元数据 | dfs.namenode.name.dir 指定目录下的 current/fsimage_* 与 edits_*,默认 file://${hadoop.tmp.dir}/dfs/name |
| DataNode 数据块 | dfs.datanode.data.dir 下的 current/BP-*/current/finalized/subdir*/blk_*,默认 ${hadoop.tmp.dir}/dfs/data |
| JournalNode(HA) | dfs.journalnode.edits.dir,默认 /tmp/hadoop/dfs/journalnode |
| 服务日志 | $HADOOP_LOG_DIR(默认 $HADOOP_HOME/logs):hadoop-*-namenode-*.log、hadoop-*-datanode-*.log、yarn-*-resourcemanager-*.log、yarn-*-nodemanager-*.log |
| HDFS 审计日志 | $HADOOP_LOG_DIR/hdfs-audit.log(每次文件读写的用户/IP/操作记录,重点) |
| YARN 容器日志(本地) | yarn.nodemanager.log-dirs,默认 ${hadoop.tmp.dir}/logs/userlogs/application_*/container_* |
| YARN 聚合日志(HDFS) | yarn.log-aggregation-enable=true 时在 HDFS /tmp/logs/<用户>/logs/<appid>/ 或 /app-logs/ |
| Web 界面 | NN :9870(3.x)/:50070(2.x),RM :8088,DN :9864,NM :8042,JobHistory :19888 |
| RPC 端口 | NN :8020(fs.defaultFS,部分老环境 :9000),RM :8032 |
| Kerberos | core-site.xml 中 hadoop.security.authentication=kerberos,keytab 常在 /etc/security/keytabs/ 或配置内指定路径 |
离线取证技巧:服务起不来也能拿到元数据
即使集群完全无法启动,NameNode 磁盘上的 fsimage/edits 就是全部元数据,可直接离线解析(详见”工作负载取证”一节)。先定位元数据目录:
# 从配置文件读出真实目录
grep -A1 'dfs.namenode.name.dir' /etc/hadoop/conf/hdfs-site.xml
grep -A1 'hadoop.tmp.dir' /etc/hadoop/conf/core-site.xml
find / -name 'fsimage_*' -o -name 'edits_inprogress*' 2>/dev/null # 兜底全盘搜索
仿真环境网络配置
启动网卡
仿真出的节点默认网卡可能未启用,逐台拉起并获取 IP:
ip link set ens33 up
dhclient ens33
修复主机名解析(关键)
Hadoop 各进程通过主机名互相寻址,配置里写死的都是原集群的主机名。仿真后 IP 变了,必须把 /etc/hosts 改成新 IP 映射:
hostnamectl # 确认本机主机名
cat /etc/hosts
# 每台节点都写入全集群的映射,例如:
# 192.168.170.10 master
# 192.168.170.11 slave1
# 192.168.170.12 slave2
若不确定集群有哪些节点,从 workers(旧版 slaves)文件和 hdfs-site.xml 的 HA 配置中获取:
cat /etc/hadoop/conf/workers
grep -E 'dfs.ha.namenodes|dfs.namenode.rpc-address' -A1 /etc/hadoop/conf/hdfs-site.xml
启动集群服务
原生 Apache 集群用自带脚本(需在配置了免密 SSH 的启动节点执行,否则逐台手动起):
$HADOOP_HOME/sbin/start-dfs.sh # 启动 NN + 所有 DN(读 workers 文件)
$HADOOP_HOME/sbin/start-yarn.sh # 启动 RM + 所有 NM
mapred --daemon start historyserver # 启动 MapReduce 历史服务器(可选)
逐台手动启动(免密 SSH 失效时):
hdfs --daemon start namenode
hdfs --daemon start datanode
yarn --daemon start resourcemanager
yarn --daemon start nodemanager
CDH/CDP 环境:
systemctl status hadoop-hdfs-namenode hadoop-hdfs-datanode hadoop-yarn-resourcemanager hadoop-yarn-nodemanager
systemctl restart hadoop-hdfs-namenode hadoop-hdfs-datanode
访问 Web 界面
http://<NN节点IP>:9870 # HDFS 概览、DataNode 列表、文件浏览器(Utilities → Browse the file system)
http://<RM节点IP>:8088 # YARN 应用列表与资源使用
若 NameNode 卡在安全模式(Safe Mode)无法写入,确认块报告收齐后强制退出:
hdfs dfsadmin -safemode get # 查看当前是否处于安全模式
hdfs dfsadmin -safemode leave # 强制离开安全模式(仿真恢复常用)
时钟偏差
仿真出来的几台节点之间有时钟偏差时,Kerberos 票据校验会失败(C\lock skew too great),YARN 心跳与块报告也可能异常,需要统一时间:
#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.重启 Hadoop 服务(Kerberos 对时钟最敏感,统一后重启恢复)
$HADOOP_HOME/sbin/stop-dfs.sh && $HADOOP_HOME/sbin/start-dfs.sh
$HADOOP_HOME/sbin/stop-yarn.sh && $HADOOP_HOME/sbin/start-yarn.sh
系统取证
基本系统信息
Hadoop 版本
hdfs version # Hadoop 版本、编译时间、源码校验和(最重要)
yarn version
dpkg -l | grep -i hadoop # Debian 系安装的组件包版本
rpm -qa | grep -i hadoop # RHEL/CentOS(CDH/HDP)组件版本
cat /etc/os-release # 底层操作系统版本
主机内核版本
uname -a
uname -r
主机名与节点列表
hostnamectl
cat /etc/hostname
cat /etc/hosts # 集群各节点 IP/主机名映射常记录在此
cat $HADOOP_HOME/etc/hadoop/workers # 全部 DataNode/NodeManager 节点名
时间服务器地址
cat /etc/chrony/chrony.conf # server/pool 行即时间源
chronyc sources # 在线状态查看
timedatectl # 时区与时间同步状态
cat /etc/ntp.conf # 老版本可能用 ntpd
配置文件取证
配置文件是还原集群架构的第一手资料,先整体打包带走再逐条分析:
tar -czf hadoop-conf.tar.gz -C /etc/hadoop conf 2>/dev/null
tar -czf hadoop-conf-home.tar.gz -C $HADOOP_HOME etc/hadoop
关键字段速查:
core-site.xmlfs.defaultFS—— NameNode RPC 地址(hdfs://master:8020),HA 模式下为 nameservice 名hadoop.tmp.dir—— 所有默认数据目录的根,元数据/数据块默认都在其下hadoop.security.authentication——simple(用户名直传,无认证)或kerberoshadoop.proxyuser.<用户>.hosts/groups—— 允许冒充其他用户的代理配置,权限滥用高发点
hdfs-site.xmldfs.namenode.name.dir/dfs.datanode.data.dir—— 元数据与数据块的真实落盘位置dfs.replication—— 副本数dfs.permissions.enabled、dfs.permissions.superusergroup—— 权限开关与超级组dfs.nameservices、dfs.ha.namenodes.<NS>—— HA 模式下的 NameNode 列表dfs.namenode.keytab.file、dfs.namenode.kerberos.principal—— Kerberos 凭据位置dfs.namenode.audit.log.async等 —— 审计日志开关
yarn-site.xmlyarn.resourcemanager.hostname—— RM 所在节点yarn.log-aggregation-enable/yarn.nodemanager.remote-app-log-dir—— 日志聚合去向yarn.nodemanager.local-dirs/yarn.nodemanager.log-dirs—— 容器工作目录与本地日志目录yarn.acl.enable、yarn.admin.acl—— YARN 管理员名单
mapred-site.xmlmapreduce.jobhistory.address、mapreduce.jobhistory.done-dir—— 历史作业数据位置
hadoop-env.sh/yarn-env.shHADOOP_LOG_DIR、JAVA_HOME、各进程的 JVM 参数
集群信息
HDFS 集群状态
hdfs dfsadmin -report # 集群总容量、各 DataNode 的 IP/主机名/容量/存活状态(核心命令)
hdfs dfsadmin -safemode get
hdfs dfsadmin -printTopology # 机架感知拓扑:节点在哪个机架
-report 输出中可提取:Configured Capacity、DFS Used、各节点 Last contact 时间(判断节点掉线时间点)、Decommission 状态。
HDFS 文件系统健康检查
hdfs fsck / -files -blocks -locations > fsck.txt # 每个文件的块分布、缺失/损坏块、副本不足块
hdfs fsck / -list-corruptfileblocks # 仅列出损坏文件(入侵删库痕迹)
YARN 集群状态
yarn node -list -all # 全部 NodeManager 及其状态(RUNNING/LOST/DECOMMISSIONED)
yarn application -list -appStates ALL # 全部应用(含已完成):AppID、用户、队列、类型、最终状态
yarn queue -status root # 队列资源分配
MapReduce 历史作业
mapred job -list all # 全部历史作业(需 JobHistoryServer 运行)
mapred job -status <job_id> # 单个作业详情:提交用户、起止时间、输入输出路径
历史作业数据同时落盘在 mapreduce.jobhistory.done-dir(默认 HDFS /tmp/hadoop-yarn/staging/history/done/),.jhist 文件可离线解析。
高可用(HA)状态
hdfs haadmin -getServiceState nn1 # 当前哪个 NN 是 Active
hdfs haadmin -getAllServiceState
HA 集群的共享 edits 在 JournalNode 的 dfs.journalnode.edits.dir(默认 /tmp/hadoop/dfs/journalnode/<NS名>/current/)下,是元数据取证的另一处来源。
工作负载与数据取证
HDFS 目录树与文件清单
hdfs dfs -ls -R / > hdfs_tree.txt # 全量目录树:权限、属主、大小、时间戳
hdfs dfs -count -q / # 各目录配额、文件数、总大小
hdfs dfs -du -h / # 各目录实际占用(快速定位大数据目录)
hdfs dfs -ls /snapshottable 2>/dev/null; hdfs lsSnapshottableDir # 快照目录
重点关注目录:/user/(用户数据)、/tmp/logs/(YARN 聚合日志)、/apps/、/hbase/、/hive/ 或 /user/hive/warehouse/(Hive 数仓)、/tmp/hadoop-yarn/staging/(作业暂存)。
导出 HDFS 文件
hdfs dfs -get /user/alice/data /导出目录/ # 递归下载整个目录到本地
hdfs dfs -get /user/alice/secret.txt /导出目录/ # 单文件
hdfs dfs -cat /user/alice/secret.txt > secret.txt # 直接输出到本地文件
大量小文件可先归档再导出:
hadoop archive -archiveName data.har -p /user/alice /archive # HAR 归档(集群上执行)
hdfs dfs -get /archive/data.har /导出目录/
hdfs dfs -cat /user/alice/bigfile | zstd -T0 > bigfile.zst # 边下边压缩
导出后做完整性校验:
hdfs dfs -checksum hdfs:///user/alice/secret.txt # HDFS 端校验和(MD5-of-CRC 组合)
sha256sum /导出目录/secret.txt | tee secret.sha256
NameNode 元数据取证(fsimage / edits,核心)
fsimage 记录某一时刻的完整命名空间,edits 记录其后的每次变更。即使不启动集群也能离线解析:
# fsimage 转可读格式(XML 或 Delimited,含全路径、属主、权限、时间戳、块列表)
hdfs oiv -i fsimage_0000000000000123456 -o fsimage.xml -p XML
hdfs oiv -i fsimage_0000000000000123456 -o fsimage.csv -p Delimited
hdfs oiv -i fsimage_... -o fsimage_rev.txt -p FileDistribution # 块大小分布统计
# edits 转 XML:每一次创建/删除/重命名/权限变更的操作序列(时间线取证关键)
hdfs oev -i edits_0000000000000123457-0000000000000234567 -o edits.xml -p XML
edits 解析出的 <RECORD> 中 OP_DELETE、OP_RENAME、OP_SET_PERMISSIONS、OP_SET_OWNER 等操作可还原文件删除与篡改的时间线。注意 edits_inprogress_* 是当前未滚动的编辑日志,也必须一并提取。
DataNode 数据块离线取证
NN 不可用、或怀疑有未登记的残留数据时,直接翻 DataNode 磁盘:
ls <dfs.datanode.data.dir>/current/BP-*/current/finalized/subdir*/
# blk_<块ID> 数据本体
# blk_<块ID>_<时间戳>.meta 块校验和元数据
块文件名本身不含原始路径,需用 fsimage/-report/块报告建立 块ID → 文件路径 映射后再还原内容。dfs.datanode.data.dir 支持逗号分隔多磁盘,逐盘检查。删除文件后的残留块可能仍在 finalized/ 中,是数据恢复的重点区域。
YARN 应用日志
yarn logs -applicationId application_1700000000000_0001 # 导出该应用全部容器日志(重点)
yarn logs -applicationId <appid> -containerId <cid> -nodeAddress <node:8041> # 精确到容器
yarn logs -applicationId <appid> -log_files stderr # 只看某类日志
yarn logs 要求日志聚合开启且聚合文件还在 HDFS 上(默认 /tmp/logs/<提交用户>/logs/<appid>/)。聚合日志被清理时,退而取 NodeManager 本地目录:
ls ${hadoop.tmp.dir}/logs/userlogs/application_*/container_*/
# 每个容器目录下:stdout、stderr、syslog、launch_container.sh(启动命令,含完整 classpath 与环境变量)
launch_container.sh 能还原作业实际执行的命令,是恶意作业分析的直接证据。
存储取证
NameNode 存储目录
ls <dfs.namenode.name.dir>/current/
# fsimage_* / fsimage_*.md5 命名空间镜像及其校验和
# edits_* 编辑日志段
# edits_inprogress_* 当前编辑日志
# seen_txid 已应用的最新事务 ID
# VERSION 集群 ID(clusterID)、命名空间 ID、创建时间、存储类型
# in_use.lock 进程锁
VERSION 文件中的 clusterID 必须与 DataNode 上 BP-*(块池 ID 内嵌 clusterID)一致,可用于确认多块磁盘是否属于同一集群;cTime/layoutVersion 记录集群初始化时间与版本。
DataNode 存储目录
ls <dfs.datanode.data.dir>/current/
# BP-<随机数>-<NN地址>-<时间戳>/ 块池目录(每集群一个)
# current/finalized/subdir*/blk_* 已完成的数据块
# current/rbw/ 正在写入的块(replica being written)
# VERSION storageID、cTime、clusterID
YARN 本地工作目录
ls ${hadoop.tmp.dir}/nm-local-dir/ # yarn.nodemanager.local-dirs:作业 jar、依赖、分布式缓存的本地副本
作业提交的可执行文件(jar/python 脚本)会以分布式缓存形式分发到每个 NM 的 nm-local-dir/usercache/<用户>/filecache/ 下,是提取恶意代码样本的直接位置。
Hive/HBase 等组件数据(若存在)
- Hive 表数据:HDFS
/user/hive/warehouse/,元数据在外部 RDBMS(MySQL/PostgreSQL,连接串在hive-site.xml的javax.jdo.option.ConnectionURL) - HBase:HDFS
/hbase/,元数据在 HBase 自身系统表
用户与权限取证
认证体系
grep -A1 'hadoop.security.authentication' /etc/hadoop/conf/core-site.xml
simple:无真正认证,客户端自报用户名(HADOOP_USER_NAME环境变量即可冒充),此时属主信息只能作为参考kerberos:强认证,继续按下节提取 Kerberos 信息
HDFS 权限与超级用户
grep -A1 'dfs.permissions' /etc/hadoop/conf/hdfs-site.xml # 权限开关与超级用户组(默认 supergroup)
hdfs dfs -ls / # 各路径属主/属组/权限位
hdfs dfs -getfacl /user # ACL 明细
hdfs groups <用户名> # 该用户在集群侧的属组解析结果
超级用户 = 启动 NameNode 的操作系统用户(通常 hdfs)+ dfs.permissions.superusergroup 组内成员,检查 /etc/passwd、/etc/group 中这些账号与组成员,以及 hdfs、yarn、mapred 等服务账号的 sudo 权限。
Kerberos 集成
cat /etc/krb5.conf # KDC 地址、默认 Realm
cat /var/kerberos/krb5kdc/kdc.conf # KDC 配置(若本机是 KDC)
klist -kt /etc/security/keytabs/hdfs.headless.keytab # 列出 keytab 中的 principal(不需密码)
ls /etc/security/keytabs/ # CDH/HDP 标准 keytab 目录
keytab 文件可直接用于以该服务身份认证(kinit -kt <keytab> <principal>),仿真恢复 Kerberized 集群时经常需要。同步确认所有节点时钟(见”时钟偏差”),否则票据校验失败。KDC 数据库(MIT KDC 默认 /var/kerberos/krb5kdc/principal)包含全部 principal,可用 kadmin.local 列出:kadmin.local -q "listprincs"。
代理用户与授权
grep -B1 -A1 'hadoop.proxyuser' /etc/hadoop/conf/core-site.xml # 允许 Hue/Oozie 等冒充用户的白名单
grep -B1 -A1 'yarn.admin.acl\|yarn.acl.enable' /etc/hadoop/conf/yarn-site.xml
grep -B1 -A1 'hadoop.security.authorization' /etc/hadoop/conf/core-site.xml
cat /etc/hadoop/conf/hadoop-policy.xml # 服务级授权:哪些用户/组可调哪些 RPC 协议
hadoop.proxyuser.*.hosts=* + groups=* 是最危险的配置,意味着该服务账号可冒充任意用户从任意机器接入。
日志取证
HDFS 审计日志(重点)
cat $HADOOP_LOG_DIR/hdfs-audit.log
每个文件级操作一行,格式形如:
2024-01-01 12:00:00,123 INFO FSNamesystem.audit: allowed=true ugi=alice (auth:SIMPLE) ip=/192.168.1.100 cmd=open src=/user/bob/secret.txt dst=null perm=null proto=rpc
可提取的关键信息:ugi(操作用户与认证方式)、ip(来源客户端)、cmd(open/create/delete/rename/setPermission/setOwner 等)、src/dst(路径)。据此可还原:谁读了什么数据(数据窃取溯源)、谁删除/改权限了哪些文件(破坏痕迹)。若服务起不来,直接到日志目录翻历史文件与滚动归档(hdfs-audit.log.*)。
NameNode / DataNode 服务日志
ls $HADOOP_LOG_DIR/
cat $HADOOP_LOG_DIR/hadoop-*-namenode-*.log # NN 启动、安全模式进出、块分配、节点上下线
cat $HADOOP_LOG_DIR/hadoop-*-datanode-*.log # DN 块接收/删除、心跳异常
grep -i 'decommission\|shutdown\|corrupt' $HADOOP_LOG_DIR/hadoop-*-namenode-*.log
NN 日志中的 BLOCK* NameSystem.delete、节点 join/leave 记录可补充审计日志之外的基础设施级事件。
YARN 服务日志
cat $HADOOP_LOG_DIR/yarn-*-resourcemanager-*.log # 应用提交/完成/杀死、队列调度、节点注册与失联
cat $HADOOP_LOG_DIR/yarn-*-nodemanager-*.log # 容器启动/停止、本地化下载记录
grep -E 'Submitted application|application_.*to RUNNING|Killing application' $HADOOP_LOG_DIR/yarn-*-resourcemanager-*.log
RM 日志可还原每个应用的提交用户、提交来源 IP 与执行时间线,与 yarn logs 提取的容器日志互相印证。
系统层日志
journalctl -u hadoop-hdfs-namenode -u hadoop-hdfs-datanode -u hadoop-yarn-resourcemanager --no-pager # CDH/CDP
cat /var/log/auth.log /var/log/secure # SSH/PAM 登录记录(看谁登过集群节点)
last -f /var/log/wtmp # 登录历史
cat /var/log/cron /var/log/crontab 2>/dev/null # 定时任务(自动化作业/后门)
history; cat ~/.bash_history # 各账号执行过的 hdfs/yarn 命令(重点找 dfsadmin、rm -r、kinit)