TT Lab
はじめる
学ぶ 学習パス コース

閉域網の現場 — 防衛ドメイン

バッチがキューより先に動いた — 時計が 2.4 秒進んでいた

TT Labで続きを見る

目標

表記がばらばらな5つのホストのログを1つの軸にまとめ、時刻の系統から孤立したホストを探し、リクエストとレスポンスの矛盾で時計誤差の下限を求めたあと、補正で説明できるものとできないものを分けて、時刻信頼性陳述書を書きます。

なぜ重要なのか

調査も監査も、「何が先に起きたか」を問います。その答えは記録の時刻から出ますが、記録の時刻は、それを残した機械の時計が示した値です。2秒ほどずれた時計は、誰にも気づかれないまま、原因と結果をひっくり返します。エアギャップ環境では、外部の時刻源がなく、ネットワークの中の時刻源1つにみんなが合わせるので、互いの順序は合っても、絶対時刻は保証されません。陳述書にその限界を書かなければ、あとでその文書全体が崩れます。

なぜデータで判定するのか

実習用のPodには、capabilityがないので、chronyc・ntpdateを使えず、システム時計も変えられません。そのため、このラボは、同期状態のレポートとログだけで判定します。実際の現場でも、監査に出すのは、コマンドの出力ではなく、この判定の結果であり、chronyc trackingとsourcesの出力が、ここでsync.jsonが置かれている場所を占めます。このラボの仮定です。

ステップ

  1. python3で/root/clock/dataに、sync.json・meta.json・ログ5つ・requests.csvを作ります。
  2. 5つのログを/root/clock/normalized.csvにhost,seq,epoch_ms,evtでまとめ、オフセットのないログをUTCとして誤って読んだときの影響を/root/clock/naive.jsonに書きます。
  3. ホストごとの時刻源のチェーンを/root/clock/chain.jsonに、宣言された時刻源に届かないホストを/root/clock/isolated.txtに書きます。
  4. レスポンスがリクエストより先の案件を/root/clock/paradox.csvに、時計誤差の下限を/root/clock/bound.jsonに書きます。
  5. 1つのホストのログの中で、時刻が戻った場所を/root/clock/backward.csvに書きます。
  6. オフセットで補正した時刻を/root/clock/corrected.csvに、補正前後の矛盾の数を/root/clock/paradox_after.jsonに書きます。
  7. ホストごとに記録の信頼等級を/root/clock/trust.csvにhost,level,reasonで書きます。
  8. /root/clock/statement.jsonと/root/clock/statement.mdに、時刻信頼性陳述書を書きます。

参考

同期レポートと5つのホストのログを作る

python3で/root/clock/dataにsync.json・meta.json・node-a.logからnode-e.logまで・requests.csvを作ります。乱数を使わない生成スクリプトをそのまま使ってください。

エアギャップ環境にはダウンロードできるサンプルがないので、まずデータを自分で作ります。乱数を使わないからこそ、誰が何回回しても同じデータが出て、互いの判定を突き合わせられます。採点ツールは、データを標準形に変えてフィンガープリントを突き合わせるので、手で直すと、後のステップがすべて止まります。

4つの表記を1つの軸にまとめる

/root/clock/normalized.csvに先頭行host,seq,epoch_ms,evtを置き、5つのログの出来事をすべて書いてください。/root/clock/naive.jsonには、naive_utc_hosts・shifted_events・shift_hoursを書きます。

epoch_msは、UTC基準のミリ秒の整数です。オフセットが付いたものはそのまま読め、オフセットのないものは、meta.jsonが教えてくれるタイムゾーンで読む必要があります。それをUTCとして読むと何時間ずれるかが、naive.jsonの内容です。

時刻源の系統を最後までたどる

/root/clock/chain.jsonにホストごとにたどった時刻源のチェーンを一覧で書き、宣言された時刻源に届かないホストを、/root/clock/isolated.txtに1行に1つずつ書いてください。

チェーンは、そのホストのsourceから始めて、1歩ずつたどります。LOCALに出会うか、すでに通った名前に再び出会ったら、そこで止まり、その名前までチェーンに入れます。宣言された時刻源自身は、孤立の判定から除いてください。

レスポンスがリクエストより先の案件で誤差の下限を求める

/root/clock/paradox.csvに先頭行req_id,sender,receiver,delta_msを置いて、delta_msが負の案件を書き、/root/clock/bound.jsonにmin_skew_ms・sender・receiverを書いてください。

delta_msは、受信時刻から送信時刻を引いた値です。負なら、2つの時計が、少なくともその大きさだけ開いているという意味で、最も大きい負の値の大きさが下限です。下限は正の数で書きます。

1つのホストの中で時刻が戻った場所を探す

/root/clock/backward.csvに先頭行host,seq,prev_epoch_ms,epoch_msを置き、同じホストのログで、すぐ前の行より時刻が小さくなった地点を書いてください。

ホストごとにseq順に読みながら、すぐ前の行の時刻と比べます。ホストが混ざらないように分けて見てください。時刻が戻った区間の記録は、順序を根拠に使えません。

オフセットで補正して残るものを見る

/root/clock/corrected.csvに先頭行host,seq,epoch_msを置いて補正した時刻を書き、/root/clock/paradox_after.jsonにbefore・after・remainingを書いてください。

補正は、観測値からそのホストのoffset_msを引くことです。符号を逆にすると、矛盾がかえって増えます。リクエストも同じ方法で両側を補正してから、もう一度負の値を数えると、残るものが、時計では説明できない本物の欠陥です。

ホストごとに記録の信頼等級を付ける

/root/clock/trust.csvに先頭行host,level,reasonを置き、ログがある5つのホストを判定してください。ルールは、ラボの案内の順序どおりに適用します。

ルールは、最初に当てはまるものを1つだけ適用します。系統が届かないホストは、他の根拠を見るまでもなく、説明不能です。補正前に矛盾に絡んだものの、補正後に消えたなら、条件付きで使える区間です。

信頼できるものとできないものを一緒に書いた陳述書を書く

/root/clock/statement.jsonにroot・root_has_external_reference・confirmed・corrected・unexplained・min_skew_ms・remaining_contradictionsを書き、/root/clock/statement.mdに、## 판단・## 근거・## 믿을 수 없는 것・## 남은 의심の4つの節で、500字以上書いてください(見出しは順に、韓国語で「判断」「根拠」「信頼できないもの」「残る疑い」を意味する語です)。

陳述書の値は、手で数えず、前のステップと同じ計算から持ってきます。時刻源が外部の基準を持っているかは、その時刻源のsourceが何かで決まります。信頼できないホストは、名前を書いてはじめて、読む人が何を除いて読めばよいかがわかります。