無印吉澤

Site Reliability Engineering(SRE)、ソフトウェア開発、クラウドコンピューティングなどについて、吉澤が調べたり試したことを書いていくブログです。

Building Secure and Reliable Systems 読書メモ - Chapter 7

f:id:muziyoshiz:20200430014145p:plain:w320

SRS 本の読書メモです。

Chapter 7 は、Google での事例を中心に、変更にはその内容によって異なるタイムライン(短期、中期、長期)があることと、タイムラインの種類ごとに注意すべき点を解説しています。

事例情報がメインなので、要約してしまうと面白さが減ってしまいそうな章でした。そのため、今回のメモは短めです。興味を持たれた方は原文をご参照ください。

SRS 本について

SRS 本はこちらから無償でダウンロードできます。

前回までの読書メモは SRS Book タグ を参照のこと。

Chapter 7. Design for a Changing Landscape

この章では、Googleが長年、どのような変更を行ってきたか、そしてそれをどのように適用してきたかという事例を複数紹介する。そして、その道程で私達が学んできた教訓を示す。

ほとんどの設計上の判断は、特にそれがアーキテクチャに関するものは、システムの設計フェーズで実装するのが最も容易かつ安価である。しかし、この章で示すベストプラクティスのほとんどは、システムライフサイクルの後半のステージで実装されたものである。

私達が日々扱うライブラリやアプリケーションの数は増え続けており、それらには常に新たな脆弱性の影響を受ける可能性がある。また、ユーザーや各種規制からの、セキュリティやプライバシーに対する期待も常に上がり続けている。

このような状況に対応するためには、自分たちのインフラを頻繁かつ迅速に変更できる必要があるが、その一方で高信頼なシステムを維持する必要もある。このバランスをとるためには、変更をいつ、どのくらいのスピードでロールアウトする(展開する)かを決めることが重要になる。

Types of Security Changes

自分たちのセキュリティ体制(security posture)を改善したり、セキュリティインフラの回復力を高めるためには、さまざまな変更が考えられる:

  • Changes in response to security incidents (see Chapter 18)
  • Changes in response to newly discovered vulnerabilities
  • Product or feature changes
  • Internally motivated changes to improve your security posture
  • Externally motivated changes, such as new regulatory requirements

Designing Your Change

セキュリティ上の変更(security changes)は、他のソフトウェア変更と同様、基本的な信頼性要件とリリースエンジニアリング原則の対象となる(本書の Chapter 4 や SRE 本の Chaprter 8 を参照)。セキュリティ上の変更をロールアウトするためのタイムラインは異なるかもしれないが、その全体的なプロセスは同じベストプラクティスに従うべきである。

すべての変更がもつべき特性(characteristics)は以下の通り:

  • Incremental
    • 個々の変更を、小さく、独立したもののする。リファクタリングのような、無関係な変更を混ぜたくなる誘惑に逆らう
  • Documented
    • その変更内容およびロールアウトの相対的な緊急性を理解できるように、変更についての "how" と "why" を記載する
    • 文書に含まれる内容:
      • Requirements
      • Systems and teams in scope
      • Lessons learned from a proof of concept
      • Rationale for decisions (in case plans need to be reevaluated)
      • Points of contact for all teams involved
  • Tested
    • ユニットテスト、および可能ならインテグレーションテストを行う
  • Isolated
    • Feature flag を用いて、機能のオンオフと、バイナリの更新を別に扱う(詳しい情報は SRE workbook の Chapter 16 を参照)
  • Qualified
    • 複数のステージからなる、正規のリリースプロセスに従ってロールアウトする
  • Staged
    • カナリアリリースのような方法で、段階的にリリースする。変更前後でのシステムの振る舞いの違いを確認できるようにすべき

これらのプラクティスは "slow and steady" approach を取ることを勧めているが、スピードと安全さの間にはトレードオフがある。

Architecture Decisions to Make Changes Easier

システムを変更しやすい状態にするための戦略について。

Keep Dependencies Up to Date and Rebuild Frequently

自分がシステムが依存しているソフトウェア(OpenSSL や Linux カーネルなど)について、最新のバージョンを利用するように保ち続ける。最新版を利用していればパッチを当てるのも用意になる。

Release Frequently Using Automated Testing

SRE の基本原則では、巨大なリリースを行う代わりに、そのリリースをより小さなものに分割し、定期的にロールアウトすることを推奨している。リリースに含まれる変更が小さいほど、ロールバックの可能性も減る。SRE Workbook の Figure 16-1 にある "virtuous cycle"(好循環)を参照。

同様に、コンテナやマイクロサービスを用いることで、パッチを当てるべき境界面を減らすことができる。

Use Containers

コンテナは、あなたのアプリケーションに必要なバイナリとライブラリを、その下にあるホスト OS と切り離し、依存関係を減らす。コンテナレジストリを更新したら、その更新後のコンテナが自動的にロールアウトされていく。

脆弱性が発生した場合は、コンテナそのものではなく、コンテナイメージをスキャンすることで影響範囲を特定できる。パッチがあたっていない古いイメージがデプロイされないように、本番環境には最新のイメージのみデプロイされるように強制すべきである。

コンテナに関連する話題は、SRE 本の Chapter 7 の "Case Study 4: Running Hundreds of Microservices on a Shared Platform"、および SRE workbook の Chapter 16(blue/green deployment によるパッチ当ての話)にある。

Use Microservices

マイクロサービス化することで、それぞれのマイクロサービスをスケールアウト、負荷分散、ロールアウトできる。つまりインフラの変更を柔軟に行えるようになる。

マイクロサービス化すると、あらゆるトラフィックがそこを流れるようになるので、limited or zero trusted network が必要になる。マイクロサービス化により、チーム間で共通のライブラリやインフラを使うようになる。そのライブラリやインフラを少数の責任者が更新・管理する。望ましいセキュリティ特性を維持するために、できるだけサービスをシンプルにすることを保証するための制約が必要になる(※本書の Chapter 6 で取り上げられていた話題)。

Example: Google’s frontend design

Google のフロントエンドデザインは、回復性と多層防御(defense in depth)を実現するためにマイクロサービスを用いている。

Google Front End (GFE) は、Google サービスに対するフロントエンド層を提供する。ほとんどの Google サービスはバックエンド層のマイクロサービスとして実装されていて、インターネットに直接公開されていない。

GFE は外部からの通信を終端し、DDoS対策や、ルーティングや、ロードバランシングを提供する。また、個々の開発チームが苦労することなく、新しいセキュリティ機能を導入できる。例えば、Google セキュリティチームが Application Layer Transport Security (ALTS) ライブラリを、自社の RPC ライブラリに組み込むことで、ALTS サポートを迅速に広範囲へ適用できた。

また、バックエンド層とフロントエンド層は、その内部にまた複数のレイヤーを持つことができる。そのそれぞれのレイヤーで負荷分散できる。このようなアーキテクチャにより、それぞれのレイヤーへの変更が適用しやすくなっている。

Different Changes: Different Speeds, Different Timelines

すべての変更が同じタイムライン、または同じ速度で発生するわけではない。以下に示す複数の要素が、変更をどれくらいの速さで更新する必要があるかに影響する。

  • Severity (重大性)
  • Dependent systems and teams
    • 他の人の作業を待つ必要があるケース(ベンダーのパッチ提供、顧客側のクライアントへのパッチ適用など)
  • Sensitivity (※何と訳すべき? 感度?)
    • ※Severity との違いがよくわからなかった。セール期間のような重要なイベント中は変更を後回しにしたいと思うかもしれない、という話が書かれているので、客観的な重大性ではなくて、自分たちの事情と比較した上での緊急性という意味?
  • Deadline
    • 法規制などによる、明確な期限がある場合
    • 脆弱性情報の報道規制(embargo)の期間が終わるまでにパッチを当てなければいけない場合

以下の節では、タイムラインが異なる事例を3つ紹介する。

  • 短期の変更:新しいセキュリティ脆弱性への対応
  • 中期の変更:新しいプロダクトの段階的な適用
  • 長期の変更:規制上の理由による変更(その変更を実装するために Google は新しいシステムを作る必要があったもの)

Short-Term Change: Zero-Day Vulnerability

Shellshock(bash の脆弱性)の事例。

Shellshock に対して、Googleのインシデントレスポンスチームはこの例外的な脆弱性を解決するために Black Swan protocol (?) を開始し、以下を行うための大規模な対応を調整した。

  • Identify the systems in scope and the relative risk level for each
  • Communicate internally to all teams that were potentially affected
  • Patch all vulnerable systems as quickly as possible
  • Communicate our actions, including remediation plans, externally to partners and customers

この対応と並行して、インシデントレスポンスチームは、Google のネットワーク境界内にある脆弱なシステムを検知するためのソフトウェアを開発した。そして、このソフトウェアを、残りのパッチ作業を完了させるために用いるだけでなく、Google の標準セキュリティ監視の機能に追加した。

この対応中に実施したこと(およびしなかったこと)から、他のチームや組織にも適用できるいくつかの教訓が得られた:

  • Standardize software distribution to the greatest extent possible (ソフトウェアの配布を可能な限り標準化する)
  • Use public distribution standards (?)
    • ※読んでも、何を指しているのかわからなかった
  • Ensure that you can accelerate your mechanism to push changes for emergency changes (緊急時の変更のために、自分たちの変更適用メカニズムを高速化できるかどうか確認する)
    • 例えば、validation をスキップするなどして高速化できるか?
  • Make sure that you have monitoring to track the progress of your rollout, that you identify unpatched systems, and that you identify where you’re still vulnerable (ロールアウトの進捗を監視し、パッチが当てられていない=まだ脆弱性のあるシステムを特定できるようにする)
  • Prepare external communications as early in your response efforts as possible (脆弱性対応のできるだけ早い段階で、外部とのコミュニケーションを準備する)
  • Draft a reusable incident or vulnerability response plan (再利用可能なインシデントや脆弱性対応計画の作成)
  • Know which systems are nonstandard or need special attention (どのシステムが標準に従っていないか、または特別な対応を必要とするかを知る)

Medium-Term Change: Improvement to Security Posture

FIDO セキュリティキーを用いた二要素認証の事例。

変更のロールアウトに関しては、2つの対立する哲学がある。

  • Start with the easiest use case, where you’ll get the most traction and prove value.
  • Start with the hardest use case, where you’ll find the most bugs and edge cases.

組織内での賛同をまだ十分に得られていないなら、最も簡単なユースケースから始めることに意味がある。組織の上層部からすでに十分な支持が得られているなら、最も難しいユースケースから始めて、バグや課題を早期に発見したほうがいい。

Phishing 対策として、Google 社内では二要素認証の調査およびテストを2011年に開始した。さまざまな選択肢を考慮したのち、Google は FIDO セキュリティキーを共同設計した。そして、OTP の代わりに FIDO セキュリティキーを導入する活動を2013年から開始した。

社内への展開はセルフサービス的に行った。最初は、志願してこの機能をオプトインしたユーザーから導入した。このデバイスは、各オフィスにある TechStop location(ヘルプデスク)から入手しやすくした。

それと同時に、セキュリティチームは FIDO 対応が必要なアプリケーションの長いリストに対応した。2015年にロールアウトの完了と、OTP サービスの廃止に集中し始め、2015年内に対応を完了した。

この経験から得られた教訓は、セキュリティ及び信頼性に関する文化を作ることに関係するものだった。

  • Make sure the solution you choose works for all users. (そのソリューションを、すべてのユーザーが利用できるものにする)
  • Make the change easy to learn and as effortless as possible. (その変更内容を、学びやすく、できるだけ苦労せずに済むものにする)
  • Make the change self-service in order to minimize the burden on a central IT team. (中央集中的な IT チームの負荷を最小化するために、その変更を、セルフサービス可能なものにする)
  • Give the user tangible proof that the solution works and is in their best interest. (そのソリューションが動作し、自分たちの利益になることを、実際に触れて確認できる証拠を提供する)
  • Make the feedback loop on policy noncompliance as fast as possible. (ポリシーに準拠していないことを、できるだけ早く気付けるようなフィードバックループを作る)
  • Track progress and determine how to address the long tail. (進捗を計測し、ロングテールをどのように解決するかを決定する)

Long-Term Change: External Demand

Google Chrome チーム、Let's Encrypt およびその他の組織による努力により、HTTPS の利用率が増加した事例。

長期の変更では、きちんとしたドキュメンテーションと、進捗の計測&可視化の自動化が必要。長期に渡るプロジェクトでは、担当者が途中で会社を去る可能性がある。

作業にはロングテール(変更が行き届かない部分)がある。全体の80〜90%に適用できたら、それはセキュリティリスクの削減に対する計測可能なインパクトを持つため、成功したとみなされるべきだろう。

ここから得られた教訓:

  • Understand the ecosystem before committing to a strategy.
  • Overcommunicate to maximize reach.
  • Tie security changes to business incentives.
  • Build an industry consensus.

Complications: When Plans Change

変更計画を変更して、変更を加速させたり、遅らせなければいけなくなる潜在的な理由:

  • You might need to delay a change based on external factors.
  • You might need to speed up a change based on a public announcement.
  • You might not be severely impacted.
  • You might be dependent on external parties.

Heartbleed(OpenSSL の脆弱性)は、キャッチーなロゴと名前で、予想外にメディアの衆目を集めた脆弱性だった。そのため、当初の計画より、パッチの適用を加速させる必要が生じた。

Heartbleed の事例からは、いくつかの重要な教訓が得られた:

  • Plan for the worst-case scenario of the embargo breaking or being lifted early.
  • Prepare for rapid deployment at scale.
  • Regularly rotate your encryption keys and other secrets.
    • SRE workbook の Chapter 9 も参照
  • Make sure you have a communication channel to your end users—both internal and external.

ここまでの感想

次にセキュリティ変更を行うタイミングがあったら、読み返して、計画立案の参考にしたいと思える内容でした。

セキュリティ変更を行う際には事前に計画を行い、それが短期〜長期のいずれに該当するかによって適切なアプローチが変わる、ということを事例とともに説明していて説得力がありました。また、変更がロールアウトされた範囲を自動的に検出可能にする(検出のために人手を挟まないようにする)ことで、各開発チームが自律的にセキュリティ変更を進められるようにするというのは、良いプラクティスだと思いました。今後うまく適用できそうな機会があれば、是非試して見たいです。