NTS: Metaにおける認証済み時刻
NTS: Authenticated Time at Meta (engineering.fb.com)
要約
Metaは、公開時刻サービスにネットワーク時刻セキュリティ(NTS)を導入し、時刻同期のセキュリティと検証可能性を向上させました。NTSは、証明書の検証やトークンの有効期限管理など、セキュリティ上の重要な決定の基盤となる時刻情報が改ざんされていないことを保証します。MetaはNTSプロトコル、サーバー、クライアントライブラリをオープンソース化し、モバイルOSでのNTSサポートの普及を呼びかけています。
全文翻訳
NTS: Metaにおける認証済み時刻
- Metaの公開時刻サービスが、nts.meta.comでNTS(Network Time Security, RFC 8915)に対応しました。パケットは認証されるため、デバイスは時刻がMetaから提供されたものであり、転送中に改ざんされていないことを検証できます。
- 当社のNTSサーバーは、クライアントごとの状態を保持しません。Cookieキーは導出されるもので、保存・複製されるものではありません。
- プロトコル、サーバー、クライアントライブラリ(GitHub上のMeta’s Timeライブラリ)を含むすべてをオープンソース化しました。
- 特にAndroidまたはiOSでNTPクライアントを保守している方々に、NTSサポートの有効化にご協力いただくことを奨励しています。
以前、Metaスケールでより正確な時刻サービスを構築することについて執筆しました。ntpdからchronyへの移行、10ミリ秒から100マイクロ秒への精度向上、time.meta.comの一般公開などです。
その作業で時刻は精密になりました。今回の作業で検証可能になります。
なぜNTSなのか?
インターネットの多くの基盤プロトコルと同様に、NTPは1985年以来認証されていません。しかし、すべての証明書、トークン、署名がチェックされる基盤となっています。クライアントは48バイトを送信し、何かが48バイトを返信し、クライアントはそれを信じます。署名もIDもありません。
これは孤立した問題ではありません。インターネットの基盤プロトコルの多くは、敵対的なネットワークを想定しない環境で設計されており、業界はそれ以来、それらを後付けで安全にしています。時刻が異なるのは、単に安全にするべきもう一つのプロトコルではないことです。それは、他のすべてのセキュリティ上の決定が測定される入力なのです。
NTPの歴史のほとんどでは、時計が数秒ずれていても運用上の迷惑でしかなかったため、これはそれほど重要ではありませんでした。しかし今日では、それは負荷を支えるものとなっています。
- 証明書の検証:
notBeforeとnotAfterはローカルクロックと比較されます。時計が間違っていれば、答えも間違います。 - トークンと認証情報の有効期限: 「15分間有効」は時計に関する主張です。
- リプレイウィンドウ: N秒より古いリクエストを拒否するには、現在時刻を知る必要があります。
- ログの相関と順序付け: 合意しない2つのホストは、実際には起こらなかったタイムラインを生成します。
そして、そのチェック自体が循環的です。現在の時刻を知らなければ、X.509のnotBefore/notAfter検証を実行できません。実質的には、証明書の時刻検証を無効にするか、提案された回避策のいずれかを実装する必要があります。
一般的な回避策は2つあります。どちらも良くありません。時計が設定されるまで検証をスキップできますが、これはデバイスが最も脆弱なときに保護されないままになります。あるいは、インスラック(in-slack)を構築できます。12:00:00に発行された証明書は、11:59:30を指すクライアントによって拒否されるため、発行者はnotBeforeを数分間過去の日付にし、検証者は静かにそのウィンドウを広げます。両者は相手がどれだけ間違っているかを推測しています。
これは、証明書が398日間有効だった頃は生存可能でした。CA/Browser Forum ballot SC-081v3がそれを変更しました。新しく発行される公開信頼TLS証明書の期間上限は、2026年3月に200日、2027年3月に100日、2029年3月には47日になり、ドメイン検証の再利用は同じ時点で10日に低下します。
47日では、手動での証明書管理はどのような規模でも実行不可能になります。更新はほぼ月次になり、通常はACME経由で自動的に行われます。クロックがずれているホストでの自動更新ループは、チケットを発生させません。誰も監視していないスケジュールで、再発行するか失敗します。
NTSの仕組み
NTSは段階的に機能し、それらを分離することが展開を可能にします。
フェーズ1 – キー確立(NTS-KE): TLS 1.3をTCP/4460上で使用し、ALPN ntske/1でネゴシエートします。クライアントとサーバーはAEADアルゴリズムに合意し、RFC 5705 exporterから直接、2つの方向性セッションキー(C2SとS2C)を導出します。サーバーは8つのCookieを発行し、TLSセッションを閉じます。これはパケットごとではなく、一度だけ行われます。
3つのAEADをネゴシエートします:AES-SIV-CMAC-256(ID 15)(RFC 8915で実装が必須とされており、未知のクライアントが最も要求する可能性が高い)、AES-SIV-CMAC-512(17)、AES-128-GCM-SIV(30)。クライアントの好みが優先されます。
フェーズ2 – 認証済みNTP: 標準NTPv4をUDP/123でアドバタイズされたサーバーに送信し、NTS拡張フィールドを使用します。リクエストは一意の識別子、Cookie、および認証子を含みます。認証子はそれ以前のすべてをカバーしますが、何も暗号化しません。サーバーはCookieを開いてセッションキーを復旧し、その認証子を検証し、一意の識別子をエコーバックした応答と、ペイロードを持つ独自の認証子を返します。この認証子の中には、新しいCookieが暗号化されて含まれています。
偽造されたパケットは検証に失敗し、破棄されます。NTS NAKは送信しないため、失敗はパケットロスと区別がつかず、クライアントを新しいキー交換に誘導するために使用されることはありません。リプレイされた応答は、間違った一意の識別子を持ち、未処理のリクエストと一致しません。置換Cookieは、レスポンス認証子の中に平文ではなく含まれているため、オブザーバーは交換ごとに異なる不透明なブロブを見て、ネットワーク間でのクライアントを追跡できません。各Cookieを一度だけ使用することは、クライアント側の取引です。サーバーはステートレスであり、それらを追跡しません。
状態を持たないCookie
Cookieは、クライアントに安全に保管させるためにサーバーからクライアントに渡されるサーバー状態です。セッションキーを保持し、AES-SIVでシールされているため、サーバーのみが開くことができます。明白な実装は、すべてのサーバーに複製されたキーリングであり、時刻サービスを分散状態の問題に変えます。
キーを複製しません。各サーバーは、共有マスターシークレットと現在の日付からシーリングキーを導出します。
key = HKDF-SHA256(master, salt = BE32(day), info = “fbnts-cookie-seal-v1”)
Unixエポック以来、日はカレンダー日ではなく、24時間単位で測定されます。そのため、タイムゾーンやDSTはなく、すべてのホストが同じ瞬間に同じ整数を計算します。その整数はCookieのキーIDであり、平文で送信されます。サーバーが、話したことのないホストによって生成された、見たこともないCookieを受け取った場合、キーを再導出して開きます。ローテーション境界周辺のスキューをカバーするために、2日前から1日後まで受け入れます。
結果として、キーリング、複製、セッションテーブル、同期ずれを起こす共有状態、攻撃者が悪用できるものがなくなります。また、上記の分割を可能にするものでもあります。KEサーバーと、それに引き渡されるNTPサーバーは、異なる場所にある異なるマシンであり、互いに何も交換しません。サーバーを追加することは、サーバーを追加することです。
通常のNTPパスは変更されていません。レスポンダーは拡張フィールドが存在する場合にのみ解析するため、認証されていないクライアントは以前と同じコストで同じコードにヒットします。
NTSの使用
chronyの設定は1行です。
pool nts.meta.com nts iburst maxsources 5
nts.meta.comはキー交換のみを終端します。ハンドシェイク中、サーバーネゴシエーションレコードでNTPレスポンダーをアドバタイズするため、クライアントはtime.meta.comに誘導され、そこで認証済みNTPを送信します。設定するホストは、最終的に通信するホストではありません。
その間接的な理由から、serverではなくpoolを使用します。単一のサーバー行は、1つのアソシエーションと1つのレスポンダーを提供し、それは単一障害点となります。NTPは、悪いものを投票で排除するために複数のソースを必要とするプロトコルです。poolは、最大maxsourcesの独立したアソシエーションを要求します。それぞれが独自のTLSハンドシェイクを通じて独自のキー交換を実行するため、それぞれが個別のセッションキーペアを持つことになります。
$ chronyc authdata
| Name/IP address | Mode | KeyID | Type | KLen | Last | Atmp | NAK | Cook | CLen |
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
| time1.meta.com | NTS | 5 | 30 | 128 | 27 | 0 | 0 | 8 | 68 |
| time2.meta.com | NTS | 7 | 30 | 128 | 142 | 0 | 0 | 8 | 68 |
| time3.meta.com | NTS | 10 | 30 | 128 | 548 | 0 | 0 | 8 | 68 |
| time4.meta.com | NTS | 1 | 30 | 128 | 1177 | 0 | 0 | 8 | 68 |
| time5.meta.com | 2 | 30 | 128 | 1177 | 0 | 0 | 8 | 68 |
5行、5つの独立した認証済みソースが、1行の設定と1つのKEエンドポイントから得られます。
読み進めると、Type 30はネゴシエートされたAEAD、AES-128-GCM-SIVで、KLenは128ビットのセッションキーです。chronyはそれを最初にリストし、クライアントの好みが優先されます。CLen 68はCookieです。内部の2つの16バイトキーを囲む36バイトのエンベロープです。Cook 8は手元にあるCookieの数で、NAK 0は拒否されたものがないことを意味します。
より興味深い半分はテーブルにはありません。各行のセッションキーは、独自のTLSハンドシェイクから生成され、そのアソシエーションでのみ機能します。それらをCookieにシールするキーは共有キーです。導出されたエポック日番号は、当社が実行するすべてのレスポンダーで同一であり、各Cookie内にスタンプされ、クライアントには決して表示されません。この分割により、単一のキー交換が、互いに通信したことのない5つの異なるレスポンダーにクライアントをハンドオフできるようになります。
プールメンバーがキー交換を完了し、ネゴシエートされたレスポンダーに移動すると、解放されたKEアドレスは次の未解決メンバーに渡され、maxsourcesレスポンダーが応答するまで繰り返されます。各メンバーが順番に独自のキー交換を完了すると、約20分で5つのソースが確立されます。
NTSは攻撃から保護する
NTPとは異なり、NTSは中間者(MITM)攻撃による応答の偽造を阻止します。古典的なMITM攻撃は、暗号化を破る必要はなく、実際のサーバーより先にクライアントに応答するだけで済みます。攻撃者が時計を巻き戻すと、有効期限切れの証明書を再度有効にしたり、取り消されたトークンを再度機能させたりできます。有効期限が切れたことに依存するあらゆる制御がリセットされます。時計を進めると、すべてが一度に期限切れになります。これは対処がより困難な方向であり、ある点を超えると失敗は回復不能になります。
デバイスが2037年であると確信させられた場合に何が起こるかの例を見てみましょう。NTPは32ビットフィールドで秒をカウントし、2036年2月にラップアラウンドします。その境界を越えて取り残されたクライアントは、誤った時代への補正を計算します。そのため、誤った時計を修正するためのメカニズムが、さらにそれを遠ざけます。同時に、デバイスが持つすべての証明書は期限切れになっているため、TLSは失敗し、ヘルプになりうるもの(自身のアップデートサービスを含む)に到達できなくなります。それを修正するパッチは配信できません。なぜなら、それを配信するには壊れた時計が必要だからです。
デバイスは損傷していません。すべてのコンポーネントは設計通りに機能しています。単にネットワークの範囲外に置かれる数値を保持しているだけです。待っても再起動しても修正されません。回復には工場出荷時リセット、またはサービスセンターへの持ち込みが必要です。これをフリート全体に掛け合わせると、間違った整数のコストはロジスティクス問題になります。
次に、認証情報を発行するホストに対するクロックフォワード攻撃を検討してください。 短期間の認証情報は、すぐに期限切れになるため安全だと考えられています。これは、短期間の有効期間が、本来なら失効処理が行うべき役割を果たしていることを意味します。この特性は、発行ホストのクロックに完全に依存します。来年であると確信している発行者は、設計したウィンドウを超える認証情報に署名します。
NTSで修正されないこと
遅延攻撃。 RFC 8915は明確です。パケットを保持する攻撃者は、導入された遅延の最大半分だけクロックをシフトさせることができ、プロトコルの暗号化はいかなるバイトも本物であるため、それを検出できません。認証は、パケットの作成者が誰であるかを伝えますが、それがどれだけ飛行中に費やされたかは伝えていません。緩和策は通常のものです。複数の独立したソース、健全性チェック、制限、バウンドステップです。
したがって、主張は限定的です。オンパス攻撃者は依然としてパケットを遅延させたり、ドロップしたりできます。彼らができなくなったのは、内容について嘘をつくことだけです。
ブートストラップ。 NTS-KEはTLS上で実行され、TLSは動作する時計を必要とします。これは上記の同じ循環問題です。RTCが停止しているデバイスは、最初のハンドシェイクの前に、おおよそ正確な時刻を取得する必要があります。
間違ったサーバー。 NTSはパスを認証しますが、応答は認証しません。正しく設定され、正しく認証されたサーバーが単に間違っている場合、完璧な署名付きで間違った時刻を提供します。クォーラム、健全性チェック、監視は依然として必要です。
単調性。 認証済み時刻は依然として壁時計時刻であり、壁時計は後退します。うるう秒のとき、または補正が着陸したときです。Cloudflareの権威DNSは2016年末にこれをヒットしました。うるう秒を横断して測定されたリゾルバーのラウンドトリップは負になり、アップストリーム選択に伝播し、Goのrand.Int63n()をパニックさせました。何も偽造されず、何も誤配されませんでした。コードが経過時間を測定する場合、単調クロックを使用してください。
普及
RFC 8915、Network Time Security for the Network Time Protocolは、2020年9月にIETF標準トラックで提案標準として公開されました。Cloudflareは15ヶ月前の2019年6月に、当時のドラフトに対してtime.cloudflare.comをNTSでローンチし、スケールで機能することを示しました。
サーバー側では、公開NTSリストは現在数十件に及び、そのほとんどが国立計量研究所やPTB、Netnod、time.nlなどのインターネットインフラストラクチャオペレーターです。私たちはさらに1つ追加します。
より大きなギャップはクライアント側にあります。NTSサポートは、サーバーの世界で期待される場所に存在します。chronyとntpsecはそれを実装しています。インターネット上のエンドポイントの大部分を占めるプラットフォームの標準時刻クライアントには、まったく存在しません。
Androidのプラットフォーム時刻同期は、UDP/123上の通常のSNTPです。これは、NITZおよびGNSSと並んで、拡張フィールド処理のない固定48バイトパケットです。そのため、NTSパスは含まれていません。Appleデバイスはtimedを介してtime.apple.comと同期しますが、そこにもNTSサポートがあるとは認識していません。
これらの2つのスタックは、数十億台の電話、時計、ヘッドセットのクロックを設定しており、それらはすべて認証されていないUDPパケットを信頼しています。デバイスベンダーは今日、別のNTS対応クライアントを配布できます。chronyはAndroid上で問題なく動作しますが、これはプラットフォームが自身で行うべきことの回避策です。
プロトコルは完成し、サーバーは出現し、クライアント実装は存在します。
欠けているのはモバイルです。
NTSの有効化にご協力ください
nts.meta.comはライブで無料です。コードはgithub.com/facebook/timeにあります。
公開時刻サービスを実行している場合は、NTSを有効にしてください。NTPクライアントを保守している場合は、RFC 8915を実装してください。モバイルOSの時刻スタックを所有している場合は、ここがギャップです。AndroidとiOSは、世界のほとんどの時計が設定される場所であり、どちらもまだ認証されていないパケット経由で行っています。
私たちは長年、時刻をより精密にしてきました。精度だけでは、未知の情報源からの非常に正確な数値しか得られません。今や、両方を実現できます。
謝辞
このプロジェクトにご協力いただいたSofia Scalzo、Pablo Mazzini、Vadim Fedorenko、Patrick Cullen、Yixin Weiに感謝いたします。