TT Lab
开始
学习 学习路径 课程

FDE综合实战:仓库收到了三次相同订单

客户说日志不能发到外部

在 TT Lab 中继续学习

目标

制作一个让客户负责人在客户服务器上亲自运行的支持包采集器。按白名单收集、对机密脱敏、设置 manifest 和大小上限,并打成相同输入得到相同字节的 tar.gz。

为什么重要

要从不能把日志发往外部的客户那里拿到包,必须得到客户安全负责人的批准。如果说不清放进了什么、脱敏了什么以及多少处、收到的文件是不是审查过的那个文件,这个包就出不去。每次都由人挑选文件,机密会泄漏,或者打出没有用的包。

材料:/opt/lab/p1a-bundle/site —— 客户服务器副本(VERSION、etc、logs、run/environ、data)。/opt/lab/p1a-bundle/rules.tsv —— 客户安全团队追加的脱敏规则。 工作目录是 /root/bundle。预计 60 分钟,会话结束后 /root/bundle 会消失。

收集规则(本实验的约定):

步骤

  1. 把材料 site 中符合收集规则的文件的相对路径,每行一个写入 /root/bundle/scope.txt。
  2. 制作 /root/bundle/redact.py:对标准输入脱敏后输出到标准输出,并向标准错误打印 redactions=N。
  3. 制作 /root/bundle/collect.py:python3 collect.py SRC OUT 把白名单文件脱敏后放入 OUT/stage。
  4. 让 collect.py 生成 OUT/stage/manifest.json(files 数组:path、size、sha256、redactions、truncated,按 path 排序,total_redactions)。
  5. 对日志文件应用 65536 字节的上限,并让 manifest 的 truncated、redactions 与实际相符。
  6. 让 collect.py 生成 OUT/support-bundle.tar.gz。条目在 support-bundle/ 之下按名称排序,相同输入无论何时何地打包,sha256 都必须相同。
  7. 让它接收 --rules FILE,把 kind<TAB>정규식(占位符为正则表达式)规则应用在默认规则之后,并用 [REDACTED:kind] 脱敏。
  8. 用材料 site 和 rules.tsv 生成 /root/bundle/delivery/support-bundle.tar.gz、SHA256SUMS、REDACTION-REPORT.tsv。

参考

用白名单决定放入什么

把材料 site 中符合收集规则的文件的相对路径,每行一个写入 /root/bundle/scope.txt。

先用 find 浏览一遍整个 site。只放入规则里按名称写明的文件,已轮转的日志、子目录中的日志、客户数据、pid 文件不在规则里,所以会被排除。路径是相对于 site 的相对路径。

窄而准的脱敏过滤器

制作 /root/bundle/redact.py:对标准输入脱敏后输出到标准输出,并向标准错误打印 redactions=N。

正则表达式按形态来定。私钥是多行的,所以要先于逐行规则,用 re.S 整块替换。键名必须是以 password“结尾”,而不是“含有”password,password_min_length 才能保留下来。值可能被引号包住,也可能在 & 或空白处结束。

只收集白名单文件并生成脱敏后的 stage

制作 /root/bundle/collect.py:python3 /root/bundle/collect.py SRC OUT 把白名单文件脱敏后放入 OUT/stage。

在同一目录中 import redact.py,就不用把规则写两遍。遍历 etc 下时,用 os.path.islink 过滤链接;run/environ 用 NUL 拆分、排序后存为 env.txt。重新运行时,不要让上一次 stage 的文件残留下来。

供审查人员核对的 manifest

让 collect.py 生成 OUT/stage/manifest.json(files:path、size、sha256、redactions、truncated,按 path 排序,total_redactions)。

sha256 和 size 按脱敏之后实际写入 stage 的字节来计算。redactions 是该文件中脱敏的次数。如果在这个文件里放入生成时间,请先想一想第 6 步会出什么问题。

大日志脱敏之后只留最近的行

对 logs 中每个文件应用 65536 字节的上限,并让 manifest 的 truncated 和 redactions 与截断后的结果相符。

从脱敏结果的末尾截取 65536 字节,然后如果该窗口的第一行不完整就丢弃它。看窗口前一个字节是否为换行符即可判断。次数要去掉被截掉的部分,在剩下的部分里重新统计。

相同输入得到相同字节

让 collect.py 生成 OUT/support-bundle.tar.gz。条目在 support-bundle/ 之下按名称排序,在不同时间、不同 OUT 打包,sha256 也必须相同。

tar 中含有修改时间、所有者、权限和顺序,而 gzip 头部还会再含一次时间。用 Python 的话,请自己构造 TarInfo 固定这些值,并指定 GzipFile 的 mtime。用 GNU tar 打包的话,请参考 reproducible-builds 文档中的选项。

用文件接收客户安全团队的追加规则

让 collect.py 接收 --rules FILE(kind正则表达式),把它应用在默认规则之后,并把次数合并进 manifest。

跳过注释(#)和空行。不要把规则写进代码,而要从文件读取——评分器每次都会给出不同的种类名称和正则表达式,还会检查不带规则运行时,那个值是否还留着。

交付包与供审查的报告

用材料 site 和 rules.tsv 生成 /root/bundle/delivery/support-bundle.tar.gz、/root/bundle/delivery/SHA256SUMS、/root/bundle/delivery/REDACTION-REPORT.tsv。

SHA256SUMS 的格式要能让接收方用 sha256sum -c 来确认。报告中的次数不要照抄 manifest,而要按种类统计包内文件里的标记次数来写。评分器会用现在的 collect.py 从材料重新打包,检查是否与交付件字节相同。