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

闭网现场 — 国防领域

用材料证明没有对外通信

在 TT Lab 中继续学习

目标

仅凭产品配置文件和三种日志,判定“不存在未经授权的对外通信”,并生成可以直接提交给监理方的摘要。确认的范围和未能确认的内容必须在同一份文档中。

为什么重要

在网络隔离环境的交付中,“不会向外发送”这句话是不会被接受的。产品中内置了更新检查、许可证校验、远程诊断、使用统计和时间同步,大多数默认是开启的。 这个实验用的 Pod 没有任何内核权限,tcpdump 和 iptables 都无法运行。意思是根本没有抓包并展示的途径。在真实现场,这个位置同样由网络团队提供的防火墙策略副本和设备日志来填补,而开发者能提交的材料,就是配置和日志。所以本实验以设置和日志为依据来判定。这就是本实验的假设。 比猜对数字更重要的,是区分三件事:被注释遮住的条目与默认开启的条目,被阻断的尝试与已经发出的通信,以及因为无法按名称核对而尚不知道的内容。

步骤

  1. 用 python3 /root/egress/mkdata.py 生成作为判定基础的数据。会生成 3 个配置、白名单,以及代理、DNS、配置变更日志。
  2. 从配置中提取全部指向外部的地址,以 host port scheme state source 的格式写入 /root/egress/endpoints.tsv。
  3. 与白名单比对,分成三类,以 host port state verdict 的格式写入 /root/egress/classify.tsv。
  4. 从代理日志中统计前往未允许目的地的尝试次数,以 host port attempts ok auth blocked 的格式写入 /root/egress/attempts.tsv。
  5. 把只存在于查询日志中的目的地,以 host queries nxdomain 的格式写入 /root/egress/dns-only.tsv,并亲自观察这个 Pod 的名称解析,把结果留在 /root/egress/resolver.txt 中。
  6. 用时间把三份日志连起来,以 host change_id first_dns first_proxy 的格式写入 /root/egress/timeline.tsv。
  7. 保留原件,在 /root/egress/conf-after/ 中关闭配置,然后用 python3 /root/egress/collect.py 重新提取日志,并把关闭前后的数字写入 /root/egress/after.txt。
  8. 在 /root/egress/egress-report.json 和 /root/egress/egress-report.txt 中输出供监理提交的摘要。

参考

在网络内生成作为判定基础的数据

保存并运行 /root/egress/mkdata.py,同时获取重新收集工具 /root/egress/collect.py。

这是隔离网络,无法从外部获取数据。生成脚本就原样放在本步骤的参考答案中,请保存后运行。必须直接使用不含随机数的脚本,这样无论谁来运行,得到的数据都相同,彼此的判断才能比对。如果手工修改文件,后面步骤的数字就会全部对不上。

从配置中不遗漏地提取外部地址

从三个配置文件中找出全部指向外部的地址,以 host port scheme state source 的格式写入 /root/egress/endpoints.tsv。

段外的 listen 是接收的位置,不属于外部地址。用注释遮住的目的地要作为关闭列入表中,不要漏掉。在 plugins.json 中,没有 enabled 键与值为 false 是不同的。source 只写文件名。

与白名单比对,分成三类

以 host port state verdict 的格式写入 /root/egress/classify.tsv。verdict 是 allowed、denied、unknown 中的一个。

白名单是以名称和端口书写的。配置中直接写着地址的目的地,没有办法与该名单核对,所以既不是允许也不是未允许。“因为是私有网段,所以发送到外部的可能性低”与“已经确认过”,是两回事。

从代理日志中按响应统计实际尝试

在 /root/egress/attempts.tsv 中,以 host port attempts ok auth blocked 的格式写入前往未允许目的地的尝试。

ok 是 200 的次数,auth 是 407 的次数,blocked 是 403 的次数,attempts 是三者之和。白名单中的目的地不要放入这张表。如果有配置中没有、只出现在日志里的目的地,那也是未允许的。

找出没有连接、只查询了名称的目的地

在 /root/egress/dns-only.tsv 中写入 host queries nxdomain,并在 /root/egress/resolver.txt 中写入亲自观察这个 Pod 名称解析的结果。

不经过代理的通信,在访问日志中什么也不会留下。查询日志中有、访问日志中没有的名称,就是它的痕迹。已批准的目的地要去掉。resolver.txt 有 nameserver、query、status 三行,status 照抄 dig 输出的字符串。

用时间把三份日志连起来,指出从什么时候开始

在 /root/egress/timeline.tsv 中,为每个未允许的目的地写入 host change_id first_dns first_proxy。没有的位置用一个连字符表示。

对象是第 4 步和第 5 步中出现的目的地的合集。看 change.log 的 item 值指向配置的哪一段,变更和目的地就能连起来。没有可配对的变更时用连字符。揭示在配置管理之外产生的目的地,正是这张表的用处。

关闭后重新收集,证明它们已经消失

在 /root/egress/conf-after/ 中关闭未允许的目的地,用 python3 /root/egress/collect.py 重新提取日志,然后在 /root/egress/after.txt 中写入四个数字。

原始配置是证据,所以在副本上修改。不要删除条目,只要关闭。确实必需的功能,不要关闭,而是改道指向白名单内的目的地。不能靠手工删除日志来做出 0 笔。评分器还会检查已批准的目的地是否仍然保留。

给出供监理提交的摘要

在 /root/egress/egress-report.json 和 /root/egress/egress-report.txt 中,给出同时写明确认的范围和未能确认的内容的摘要。

数字全部来自前面步骤的表格。unverified_hosts 中只放无法按名称核对的目的地。direct_egress_checked 和 packet_capture_checked 是用这份材料无法确认的内容,请如实填写。供人阅读的表格中,连只出现在日志中的目的地也必须各占一行。