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

面对陌生系统

不动手也能回答,动了就要还原

在 TT Lab 中继续学习

目标

只用只读手段回答关于客户生产服务器的五个问题。然后编写把目录状态固化成指纹并进行比较的工具,改动一行必须修改的配置,确认效果后真正还原,并证明与快照相比内容不同的文件有 0 个。

为什么重要

调查期间只要改动了什么,之后看到的值就分不清是原来的值还是我们造出来的值。客户在这期间看到的指标也被污染了,之后有人问“是从什么时候开始变成这样的”,我们自己就成了答案的一部分。 改动越小,越容易忘记还原。而且,相信自己已经还原了,与已经还原这件事得到了证明,是两回事。“已经恢复原样”是一句无法验证的话,而“还原之后与快照比较,内容不同的文件有 0 个”,则是可以确认的话。 比这更先要问的是:真的必须改动才能得到答案吗?很多情况下,同一个问题可以用只读的方式回答。不欺骗自己“是不是只读”的办法,是记录所用的命令。 本实验不同于取得客户批准后再实施的变更作业。它是那之前的阶段:调查过程中手滑的那一瞬间,在第一周应当遵守的纪律。 评分器不会相信你写下的文字。五个答案由评分器亲自重新测量;对快照工具,它会构造出新增文件、删除文件、修改内容、只改权限、只改时间这几种位置,看你的工具能否区分这五种情况。

步骤

  1. 创建并运行 /root/readonly/gen_site.py,生成 /root/readonly/site/。其中包含配置、240 行的订单台账、180 行的日志和查询工具。
  2. 只用只读手段回答五个问题,写入 /root/readonly/answers.json。每个答案都要一并留下所用的命令。
  3. 创建 /root/readonly/snapshot.py,遍历目录,为每个文件记录指纹、大小、权限和修改时间,并把当前状态固化到 /root/readonly/baseline.json。
  4. 增加 --baseline <스냅샷>(占位符为快照),让它输出比较结果。分成 added、removed、changed、mtime_only、same 五类。
  5. 把配置中的 max_retry 从 3 改为 5,并在 /root/readonly/change.json 中写明改什么、为什么改,以及还原命令。
  6. 用查询工具确认改动产生的效果,写入 /root/readonly/verify.json。
  7. 还原,并把与快照比较的结果留在 /root/readonly/revert_diff.json 中。内容不同的文件必须是 0 个。
  8. 在 /root/readonly/readonly_report.md 中分四节书写。

参考

掌握生产服务器

创建并运行 /root/readonly/gen_site.py,生成 /root/readonly/site/。其中包含 etc/app.conf、data/app.db(orders 240 行)、var/log/app.log(180 行)和 bin/report.py。

把查询工具 report.py 想成客户服务器上本来就有的工具。它不是我们创建的,而是原本就在那里,我们只能运行它来看。创建完成后,先运行一次查询工具,看看能问些什么。

只靠读取来回答

在 /root/readonly/answers.json 中写入五个问题的答案。id 是 app_version、pending_orders、log_errors、backoff_ms、oldest_pending_days,每个答案都把实际使用的命令留在 how 中。

配置打开来读取,台账以只读方式打开来统计,日志数行数即可。使用已有的查询工具也属于读取。how 中所写的命令如果混入了写入,评分器会发现,所以写的时候要自己确认。

固化改动之前的状态

创建 /root/readonly/snapshot.py,用 --dir --out 遍历目录,并把 site 当前的状态固化到 /root/readonly/baseline.json。为每个文件记录 sha256、bytes、mode 和 mtime。

不固化的话,之后就没有东西可以证明已经还原。路径以 --dir 为基准,记录为相对路径,不记录目录和符号链接。mode 只写三位权限,mtime 写成以秒为单位的整数。

增加比较功能

增加 --baseline <스냅샷>(占位符为快照),让它输出比较结果。分成 added、removed、changed、mtime_only、same 五类,changed 中只在 fields 里放发生变化的项的名称。

如果把内容、大小和权限都相同而只有修改时间不同的情况放进 changed,还原之后的结果就永远是标红,提供不了任何信息。把这种情况单独统计,是这个工具的核心。评分器会把五种情况全部构造出来放进去。

只改一项,并做好还原准备

把配置中的 max_retry 从 3 改为 5,并在 /root/readonly/change.json 中写入 target_file、key、before、after、sha256_before、sha256_after、why、approved_by、baseline、apply 和 rollback。rollback 中必须包含原始值。

还原命令要在改动之前写好。如果改完之后才想写,原始值就只能靠记忆,是 3 还是 30,30 分钟后会模糊得令人吃惊。批准也要用一行留下来:没有它,之后这个改动就成了我们偷偷做的。

用值来确认是否产生了预期的效果

用查询工具确认改动产生的效果,并在 /root/readonly/verify.json 中写入 question、command、before、after 和 confirmed。question 是 retry_budget,before 和 after 分别是改动之前和之后查询工具的输出。

改动了这件事,与所改动的内容产生了预期的效果这件事,是两回事。查询工具可以用 --conf 指定另一个配置文件,所以可以用一份包含改动之前值的临时配置运行一次,得到 before。输出原样写成字符串。

还原并证明

按 change.json 中的 rollback 还原之后,把与快照比较的结果留在 /root/readonly/revert_diff.json 中。added 和 removed 必须为空,并且 changed 必须是 0 个。只有修改时间不同的文件会留在 mtime_only 中。

相信自己已经还原了,与已经还原这件事得到了证明,是两回事。比较的结果就是证明。不要为了隐藏修改时间的差异而把时间也调回去,从那时起,就成了我们在抹掉痕迹。

写明动过什么、还原了什么

在 /root/readonly/readonly_report.md 中分 ## 읽기만으로 답한 것 ## 꼭 바꿔야 했던 한 건 ## 바꾼 뒤 무엇을 확인했나 ## 되돌린 증거 四节书写(韩文标题,依次意为“只靠读取回答的内容”“必须改动的那一项”“改动之后确认了什么”“还原的证据”)。五个问题的 id、所改的键和值、查询工具输出的变化、比较结果的数字,都必须出现。

报告不要手写,而是从 answers、change、verify、revert_diff 四个文件生成。最后一节里,留下的痕迹(仅修改时间不同的文件)也要如实写下来:隐瞒的话,从那时起就成了我们在抹掉痕迹。