無印吉澤

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

AWSの薄い本シリーズ(IAMのマニアックな話など)の読書メモ

年明けから IAM 周りの整理をいろいろしなければいけなくなったので、佐々木拓郎さんの「AWSの薄い本」シリーズ2冊を読みました。今回はその読書メモです。

booth.pm

booth.pm

AWS は普段から使っているので、IAM の基本的な機能はもちろん知っているのですが、最近追加された機能(特にマルチアカウント管理に関する機能)については全然追えてなかったので勉強になりました。

以下、勉強になった点をまとめたメモです。AWS の情報は日々変わっていってしまうので、発行日も併せて記載しました。

AWSの薄い本 IAMのマニアックな話(発行日:2019年9月22日)

第1章 AWSとIAM

第2章 IAMの機能

  • IAMの機能のうち、まず次の5つの機能の認知と理解をしておくことが重要
    • IAM ユーザー
    • IAM グループ
    • IAM ポリシー
    • IAM ロール
    • パーミッション・バウンダリー
  • アクセスキーの発行は原則しないほうがいい。必要になったときに最小の権限で発行する
  • IAMユーザーに権限を直接付与こともできるが、管理上の複雑さが増すので、IAMグループで管理することを推奨
  • 管理ポリシーとインラインポリシー
    • インラインポリシーは管理ポリシーができる前の古い機能
    • AWSが最初から設定しているポリシーをAWS管理ポリシー(AWS Managed Policies)、各ユーザーが独自に作成したポリシーをカスタマー管理ポリシー(Customer Managed policies)と呼ぶ
    • AWS管理ポリシーで大まかな権限を足した後、不要な権限をカスタマー管理ポリシーで引く
  • Permissions Boundary(パーミッション・バウンダリー)
    • 2018年7月に登場した、IAMの移譲権限を制限する機能
    • 他者にIAMユーザーやIAMロールを貸与する際に、それらが持つ権限の一部(パーミッション・バウンダリーで設定した権限)しか使えない状態にすることができる

第3章 IAMチュートリアル

  • Condition で aws:SourceIp を指定するときに、プライベート IP の範囲を指定しても意味がない。VPC 内のリソースを制限するには VPC ID もしくは VPC Endpoint ID を指定する必要がある(6章)
  • IAM ポリシーの基本的な動作は「明示的な Deny > 明示的な Allow > 暗黙的な Deny(デフォルト)」
  • クロスアカウントロール(IAM ロール)を使って、設定変更時のみ、変更権限を持つ IAM ロールにスイッチする例
    • スイッチ元は sts:AssumeRole で制限
    • Principal に、IAM グループでの指定はできない

第4章 IAMポリシーのデザインパターン

  • ホワイトリストパターン
    • 最小権限を付与するのに適している
    • 事前に役割を決めて権限を付与するため、探索的な開発の場合には効率が悪くなる
    • 本番環境、かつ高いセキュリティを求められるエンタープライズ向け
  • ブラックリストパターン
    • 禁止事項のみを定義すればよいので、IAM ポリシーの設計・設定が最小で済む
    • AWS に新しいサービスが始まると、予期せぬ機能が突然使えるようになる
    • 探索的な開発環境、もしくは比較的大きな権限が必要な管理者向け
  • ハイブリッド・パターン
    • AWS の定義済みのポリシーと、自分で作ったブラックリストを組み合わせて利用することで、最小の労力で実用的なポリシーを作ることができる
    • 組み合わせに使われる個々のポリシーは、シンプルに作ることができる

第5章 IAMグループのデザインパターン

  • 以下の2つのパターンが考えられるが、機能的な優劣はない
    • ユーザーが複数グループに所属し、グループ間のポリシーの重複はないパターン
    • ユーザーが1つのグループに所属し、グループ間でポリシーの重複があるパターン
  • IAMグループは、path オプションを使って階層構造を表現できるが、権限の継承のような機能はない

第6章 IAMとセキュリティ

  • AWS が公開している IAM のベストプラクティス
  • 特権ユーザーに関わらず、すべての IAM ユーザーに対して MFA の有効化を原則にすべき
  • ユーザー自身のパスワードと MFA の設定を許可する例
    • ${aws:username} は IAM ポリシーエレメントと呼ばれる変数で、ログインしている IAM ユーザー名に置き換えられる
    • AWS アカウント ID の変数は、IAM ポリシーエレメントに無い。代わりに、CloudFormation の疑似パラメーター参照に AWS::AccountId として存在する
  • Lambda のリソースベースポリシー
  • インターネット公開系の権限(EC2のインスタンスへの通信許可など)は、ホワイトリストで管理するのは大変。そういった際には、ネットワーク系の操作を明示的に拒否する方法と併用するといい
  • S3 へのアクセス元制限は、IAM ポリシーを使うより S3 側のバケットポリシーを使うのが一般的
  • IAM ユーザーを作成する際の原則として、アクセスキー、シークレットアクセスキーを作らないことを推奨
  • Capital One の情報流出事件(S3 からの情報流出)を防ぐために必要だった設定
    • IAM ロールのクレデンシャルが漏洩した際の影響を最小化するため、IAM ロールに付与する権限を絞り込む
    • バケットポリシーで接続元 VPC を制限する

第7章 IAMの運用

  • IAM 運用の目的
    • AWS を安全な状態に保ち続ける
  • 目的の達成のために
    • 維持するために手間が掛からない(現実に許容できるコスト)
    • 利用者によってセキュリティレベルの差異がでないようにする(標準化)
  • まずは利用者(人間、プログラム)を洗い出す
  • AWS を利用する人ごとに適切な最小権限を付与し、必要でなくなったら権限をなくす
    • CloudTrail で AWS コンソール、API 利用履歴のログを取得する
    • Config を利用し、IAM 関係の設定の変更を監視する
    • Config Rules で設定値を監視
    • (月次等の)定期的な IAM ユーザーの棚卸し
  • CLI やプログラムから利用する IAM ユーザーも、棚卸しが必要
    • IAM ユーザーごとの担当者を明確化する
      • 例えば、IAM ユーザーのタグに担当者を書く
    • 最終利用日から一定時間が過ぎた IAM ユーザーは継続の確認をする
      • 使われていなければ、まず無効化して、しばらくして問題がなければ消す
  • CLI 利用のためにアクセスキーを発行する場合、アクセスキーの流出対策が必要
    • CLI 利用時にも IAM ロールへの切り替えが可能
    • IAM ユーザー側に IP アドレスによる利用制限をした上で、必要な場合にスイッチロールで権限を切り替えるという運用をしておけば、万が一流出しても直接の被害を防げる
  • マルチアカウント利用時は、各アカウントに IAM ユーザーを作るのではなく、踏み台 AWS アカウントを1個作り、そこの IAM ユーザーから、他のアカウントのロールにスイッチする

第8章 IAMとCloudFormation

  • 複数の AWS アカウントに、同じようなポリシーやロールを作る場合、CloudFormation 化しておけば人的ミスを排除できる
  • IAM ユーザーは基本的に一度作っておしまいなので、CloudFormation のライフサイクルで管理するメリットがほとんどない。そのため管理対象から外すことを推奨する

第9章 IAMのテンプレート集

  • 本書のテンプレート集のダウンロード URL
  • 管理者グループには IP 制限を加えるべきだが、IP 制限があると CloudFormation 等の一部の機能が使えない場合がある。そのため、スイッチロールを指定して IP 制限を解除できるようにしておく
  • 管理者ロールへスイッチできるユーザーを限定する方法としては、以下の2通りがある
    • ロールに、スイッチ可能なユーザーを記載する(本書のテンプレートはこちらを採用)
    • スイッチロールを原則拒否し、必要なユーザーのみスイッチロールの権限を付与する
  • ネットワークに関連する権限は多岐に渡るため、自分でリストアップするのは難しい。職務機能の AWS 管理ポリシー(AWS managed policies for job functions) にある NetworkAdministrator の利用を推奨する
  • 開発者に、EC2 インスタンスを立ち上げるための権限を付与しようとすると、いまや EC2 に IAM ロールを付与するのは必須であるため、IAM ロールの作成・更新に関する権限が必要。そうすると、実質的に何でもできてしまう
    • 現実的な対応としては、開発環境では管理者権限を付与した上でしっかり監査証跡を残す

第10章 IAM以外のAWSサービスの活用

  • AWS Organizations(組織アカウント)
    • ルートと呼ばれるマスターアカウントと、それに紐づく子アカウントがある。また、子アカウントを階層化するための組織単位がある
    • アカウントに対するポリシーと言う形で、ホワイトリスト/ブラックリスト形式で権限の管理ができる
    • 上位で決めたポリシーは、個々のアカウント単位で打ち消すことはできない(強力な統制)
  • CloudTrail と Config
    • CloudTrail と Config は対となるようなサービス
    • CloudTrail は操作ログの記録
    • Config は操作の結果どういう状態になったのかの記録、および状態変更に対するアクションの定義
  • Amazon GuardDuty
    • 脅威検出と継続的なモニタリングサービス
  • AWS Control Tower と AWS Security Hub
    • AWS Control Tower は複数アカウントの設定および管理
    • Security Hub は複数のアカウントの状況を一括してモニタリング

付録A アカウント開設時の設定チェックリスト

  • セキュリティの強化
    • 1) ルートアカウントの MFA 設定
    • 2) IAM Group と IAM ユーザーの作成
    • 3) IAM パスワードポリシーの適用
  • 状況の出力・見える化
    • 4) CloudTrail の有効化
    • 5) Config の有効化
    • 6) GuardDuty の有効化
    • 7) Trusted Advisor の E メール通知設定
    • 8) Cost Usage Report の出力
  • 機能を使うための設定
    • 9) ルートアカウントで IAM User への請求情報へのアクセス許可
    • 10) 支払い通貨を日本円に変更
    • 11) コスト配分タグの設定
    • 12) 代替連絡先の設定

AWSの薄い本Ⅱ アカウントセキュリティのベーシックセオリー(発行日:2020年3月22日)

第1章 AWSアカウントセキュリティ

  • AWS のセキュリティを3つの観点から分類
    • 1) AWS 上に構築するシステムのセキュリティ
    • 2) AWS アカウント自体の管理(IAM の設計・運用)
    • 3) セキュリティを維持管理するための施策
  • 3は、いわゆる AWS アカウントのガードレール設計。本書の中心テーマの一つ
    • IAM を運用しているうちに抜け漏れが出てきたり、カバーしきれない部分がでてきたときに、それらを予防・検知するための施策がガードレール設計
  • 本書では AWS Organizations は基本的には解説せず、その一部の機能であるサービスコントロール Policy(SCP)のみを扱う

第2章 ガードレールという設計と思想

  • Control Tower にはガードレールという機能がある
  • ガードレール設計の思想と、Control Tower が実際にそれをどのように実現しているのか
  • Control Tower は最小構成で3つの AWS アカウントで構成される
    • マスターアカウント
    • ログ管理用アカウント
    • 監査用アカウント
  • 一元管理と改ざん防止のため、ログ管理用アカウントと監査用アカウントが、その他のアカウント(開発環境用や本番環境用)から分離されている
  • Control Tower は、道から踏み外さないための予防と検知を提供する
    • 予防:自分の権限外の操作(例えばログの削除)を禁止する
    • 検知:ルールから外れた操作(例えばルートアカウントの利用)を検知する
  • Control Tower における予防と検知の実態は、Organization の SCP(Service Control Policy)と Config Rules
    • ただし、Control Tower の個々のガードレール名を見ても、予防なのか検出なのかの区別がつかないという欠点がある

第3章 AWSのセキュリティサービス

  • NIST Cybersecurity Framework
  • CSF コア
    • 特定(Identity)
    • 防御(Protect)
    • 検知(Detect)
    • 対応(Respond)
    • 復旧(Recover)
  • NST CSF コアを参照しながら、AWS のセキュリティサービスを整理する
  • CloudTrail のおすすめの設定の一つに、クロスアカウントロールを利用して他のアカウントに対してログを保存するという方法がある
    • システム内で使う証跡情報はローカルの S3 バケットに保存し、監査用に集積する証跡情報は監査用 AWS アカウントのバケットに保存する
    • こうすることにより、プロジェクトごとの利便性と、組織全体のガバナンスの両方を確保できる
  • GuardDuty の分析対象は、CloudTrail、VPC フローログ、DNS ログの3種類
  • Trusted Advisor は便利だが、現在は通知方法がEメールしか使えない

第4章 サンドボックスアカウントの作成のチュートリアル

  • 実験や検証に使う AWS アカウントのことを、本書ではサンドボックスアカウント(サンドボックス環境)と定義する
  • 今回作るサンドボックス環境の要件
    • 1) アカウントの利用者は一人(多人数でアカウントを共有しない)
    • 2) 利用者はそのアカウント内では、ほぼ全ての権限を持つ(管理者権限)
    • 3) 外部への情報漏えいにつながる行為、権限付与を禁止する
    • 4) 問題となる行為を定義し、自動で検知・通知できるようにする
    • 5) 問題検知時に通知だけでなく自動復旧を目指す
  • 3の設定項目については、以下の4項目に具体化して考える
    • IAM ユーザーの新規作成禁止
    • アクセスキーの作成禁止
    • S3 のパブリックアクセス禁止
    • 不特定多数へのセキュリティグループ開放禁止
  • IAM Access Analyzer を有効にする
  • マスターアカウント側で CloudTrail の設定をして、メンバーアカウントから設定や削除ができないようにする
  • Config アグリゲータの設定をして、マルチアカウント・マルチリージョンで Config のデータを集約する
  • Security Hub を有効化する
  • Config Rule は登録時に設定した間隔で定期的にチェックされる(デフォルト12時間、最短1時間)
  • 自動復旧は、複雑な処理が必要な場合は Lambda でスクリプトを書き、定形処理で済む場合は AWS System Manager(SSM)の Automation を使う
  • SCP の使い方としては、現状の仕様では "Effect": "Allow" を利用せず、"Effect": "Deny" で禁止すべき項目を設定していくほうがよい

第5章 CloudFormation を利用した構成管理

  • CloudFormation StackSets は、1つのテンプレートから複数の AWS アカウント・リージョンに対してスタックの作成・実行ができる機能
  • 2020年2月12日に機能が追加され、Organizations からアカウントの作成・削除時や OU の移動時に指定しておいた StackSets を自動で実行できるようになった

第6章 アカウントセキュリティの設計の考え方の原則

  • AWS Well-Architected フレームワーク(現時点の最新版は2020年7月)
  • NIST CSF コアと、AWS Well-Architected Framework を比べながらの解説
  • SEC 8「データをどのように分類していますか?」に該当する機能に、AWS Macie(機密データを検出、分類、保護するサービス)がある

第7章 障害の検知と復旧の考え方

  • AWS に多数あるセキュリティ関係のサービス同士の関係についての解説
    • 似たようなサービスもあるが、それをどう取捨選択するか
  • Security Hub と個別サービスの使い分けはシンプル
    • システムの運用に関わる障害は、アカウント個別に設定
    • AWS アカウントに対する攻撃については、複数のアカウントで共通設定

第8章 まとめとマルチアカウント管理への道

  • 本書全体のおさらい
  • 予防的統制(Preventive controls)と発見的統制(Detective controls)

Amazon Linux 2 に awscurl を安全にインストールする簡単な方法

f:id:muziyoshiz:20201129180845p:plain

この話の背景

以前のブログ記事で、Amazon Elasticsearch Service を awscurl(AWS 署名に対応した curl ライクなコマンド)経由で管理する方法をまとめました。

muziyoshiz.hatenablog.com

自分が扱っている環境では、管理用サーバ(Amazon Linux 2)に awscurl をインストールして使ってます。

この管理用サーバで使う Python 製のツールは awscurl だけだったので、Amazon Linux 2 標準の Python 2 に pip install awscurl して使ってたんですが、そしたら yum update を実行するたびに urllib3 のアップデートと衝突して使えなくなることが頻発。

まあ、Python 知っている人にしたら「それはそう」って話なんですけど、awscurl を使いたいだけだからいいか、とサボってたんですよ……そしたら案の定という感じ。このためだけに pyenv 入れるのは面倒だなあと悩んでいたら、同僚にいい方法を教えてもらって解決したのでまとめておきます。

結論:pipx 経由で awscurl をインストールする(ただし Python 3 が必要)

pipx とは、Python で書かれたエンドユーザーアプリケーションを、独立した環境で動かすことができるツールです。

github.com

コマンド名からお察しの通り、pipx は pip と同じく The Python Package Index (PyPI) を使えます。それに加えて、pipx はインストールしたツールが依存するパッケージを、ツールごとに独立した環境にインストールしてくれます。アップグレードやアンインストールも、同様にクリーンな環境で行なえます。

サイト内の説明を借りると、いわば pipx は PyPI を Python アプリケーションのための巨大な app store にしてくれる(In a way, it turns Python Package Index (PyPI) into a big app store for Python applications.)というわけです。いいですね。

ただし、pipx の動作には Python 3 が必須です。しかし Amazon Linux 2 に標準添付されているのは Python 2.7 だけ。amazon-linux-extras に Python 3 系があるので、細かいことを考える必要がないなら、これで Python 3 系を入れてしまうのが一番楽でした。

以下、awscurl のインストールが完了するまでの具体的な手順です。

インストール手順

Python 3 のインストール

amazon-linux-extras に関する説明はこちら。これは AWS が Amazon Linux 2 用に管理している yum リポジトリを有効にするコマンドです。ソフトウェアのインストール自体は yum コマンドで行います。

aws.amazon.com

amazon-linux-extras 自体が未インストールの場合は、まず以下のコマンドでインストール。

$ sudo yum install -y amazon-linux-extras

amazon-linux-extras コマンドで、現在利用できるリポジトリ(amazon-linux-extras の用語ではトピック)の一覧が確認できます。現時点では python3.8 が利用できることがわかります。

$ amazon-linux-extras | grep python
 44  python3.8=latest         available    [ =stable ]

そこで、今回は python3.8 のリポジトリを有効にしてから、yum コマンドでインストールします。将来、Python のバージョンが上がったら、python3.8 の部分は読み替えてください。

$ sudo amazon-linux-extras enable python3.8
$ sudo yum install python3.8

pipx のインストール

pipx のインストールは、pipx サイト内の手順 のコマンド名を python3 から python3.8 に置き換えれば OK です。

$ python3.8 -m pip install --user pipx
$ python3.8 -m pipx ensurepath

これで、そのユーザー(EC2 だと ec2-user)は特別なパス指定なしで pipx を使える状態になりました。pipx のインストール先は ~/.local/bin/pipx です。

pipx 経由での awscurl のインストール

awscurl のインストールは、従来の pip を pipx に置き換えるだけで OK です。

$ pipx install awscurl

awscurl のコマンドは ~/.local/bin/awscurl にインストールされますが、awscurl が依存するパッケージ一式は ~/.local/pipx/venvs/awscurl/ 以下にインストールされます。このように、ツールごとに環境が分離されるわけですね。

注意点:シェル変数の扱いが変わる

コマンドごとに環境が分離されるためか、シェル変数の扱いが変わるようです。

以前のブログ記事 では、awscurl コマンドへ自動的に認証情報を渡す awscurl-on-ec2 というシェルスクリプトを紹介しました。

#!/bin/env bash

ROLE_NAME=`curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/`
CRED=`curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/${ROLE_NAME}`
AWS_ACCESS_KEY_ID=`echo $CRED | jq -r ".AccessKeyId"`
AWS_SECRET_ACCESS_KEY=`echo $CRED | jq -r ".SecretAccessKey"`
AWS_SESSION_TOKEN=`echo $CRED | jq -r ".Token"`

awscurl "$@"

pipx でインストールした awscurl には、この方法ではシェル変数が渡されませんでした。以下のように、export を使って環境変数にすれば問題なく渡されました。

#!/bin/env bash

ROLE_NAME=`curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/`
CRED=`curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/${ROLE_NAME}`
export AWS_ACCESS_KEY_ID=`echo $CRED | jq -r ".AccessKeyId"`
export AWS_SECRET_ACCESS_KEY=`echo $CRED | jq -r ".SecretAccessKey"`
export AWS_SESSION_TOKEN=`echo $CRED | jq -r ".Token"`

awscurl "$@"

awscurl の場合はコマンドライン引数を使って、これらの認証情報を明示的に渡すこともできます。環境変数を増やしたくなかったので、自分はこちらの方法で対応しました。

#!/bin/env bash

ROLE_NAME=`curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/`
CRED=`curl -s http://169.254.169.254/latest/meta-data/iam/security-credentials/${ROLE_NAME}`
AWS_ACCESS_KEY_ID=`echo $CRED | jq -r ".AccessKeyId"`
AWS_SECRET_ACCESS_KEY=`echo $CRED | jq -r ".SecretAccessKey"`
AWS_SESSION_TOKEN=`echo $CRED | jq -r ".Token"`

awscurl --access_key $AWS_ACCESS_KEY_ID --secret_key $AWS_SECRET_ACCESS_KEY --session_token $AWS_SESSION_TOKEN "$@"

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

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

SRS 本の読書メモです。

Chapter 7 までは順番に読んでましたけど、途中を飛ばして、気になっていた最終章の Chapter 21 を先に読んでみました。

SRS 本について

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

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

Chapter 21. Building a Culture of Security and Reliability

この章では、セキュリティと信頼性に関する健全な文化の側面について述べる。また、変化を起こすべきときに、良いプラクティスを選ぶことで、あなたがどのように組織文化に影響を与えることができるかについても触れる。そして、セキュリティと信頼性についての同意を得るために、組織を超えてリーダーとチームに対しての影響を与えるかについての洞察を提供する。

Google やその他の組織で有用だったいくつかのプラクティスを共有するが、同じ組織は2つと無いこと、これらのプラクティスをあなたの組織の文化に合わせて応用する必要があることに注意してほしい。また、Google もこれらを完璧に実践できているわけではなく、日々改善を進めていることを添えておく。

例えばこんなシナリオを想像しよう:あなたの組織には大きな取引(Big Deal)が近づいており、みな締切に追われている。しかし、今日あなたは攻撃者がシステムに進入した証拠を発見してしまう。あなたはすぐシステムをオフラインにすべきと気づいているが、もちろん顧客は怒り、大きな取引はリスクに晒されるだろう。おそらくあなたは、先月のセキュリティパッチを適用していなかったことを責められるだろう。こんな状況で、あなたの組織の文化は、どのような決定を促すだろう? 強いセキュリティ文化を持つ健全な組織なら、従業員がそのインシデントについてすぐ報告することを促すだろう。

この章では、セキュリティと信頼性の文化(a culture of security and reliability)を構築するためのパターンとアンチパターンの両方を紹介する。

Defining a Healthy Security and Reliability Culture

健全なシステム(healthy systems)のように、健全なチーム文化は明示的に設計され、実装され、そして維持されることができる。健全なシステムを構築するための設計の原則(design principles)があるように、健全な文化にもそのような設計の原則がある。

Culture of Security and Reliability by Default

Chapter 4 で議論したように、セキュリティと信頼性について考えることは、プロジェクトの最終盤に回されがちである。しかし、あとから技術的負債を支払おうとすると、長期的なベロシティは低下し、その仕組みには一貫性がなく、失敗を招くことになりかねない。

それはさながら、シートベルトやエアバッグが車に標準搭載されておらず、消費者があとから買わなければならない世界のようだ。これらは車の設計時から考慮されるべきだし、そのほうが最適な場所に設置されるだろう。このたとえ話は、システムにとって、最初から(デフォルトで)セキュアかつ信頼できること(secure and reliable by default)ことの必要性を示している。

最初からセキュリティと信頼性について考える健全な文化を持つ組織は、開発者に、それらをプロジェクトの初期段階で(例えば設計段階で)考えること、そして実装のイテレーションを繰り返すなかでも考え続けることを促す。そのように成熟した製品は、セキュリティと信頼性を維持しつづけることが自然にできるようになる。

Google の、最初からセキュリティと信頼性を考える文化(a culture of security and reliability by default)の発展についての知見を、本書の Chapter 12, 13, 19 で示した。

Culture of Review

強いレビュー文化が整っている環境では、誰もが変更を承認する際に、自分の役割について前もって考えることを促される。本書では、以下のようなピアレビューの方法を取り上げてきた。

  • 最小権限(least privilege)を保つための、アクセスや変更の認可に関する複数人でのレビュー(Multi-party authorization reviews)(Chapter 5)
  • コードの変更が適切かつ高品質(セキュリティと信頼性の考慮も含む)であることを保証するためのピアレビュー(Chapter 12)
  • 本番システムに適用される前の、設定変更のピアレビュー(Chapter 14)

このような文化を構築するためには、レビューの価値とそれをどのように実行するかについて、組織全体で幅広い理解が必要である。

レビューで期待されることを明らかにするために、変更レビューのプラクティスは文書化されるべきである。レビューで拒否されたときに、その理由を明確にできることは、感情的にならないためにも必要である。

レビューの文化は、そのレビュープロセスに全員が参加することを必要とする。その人がシニアロールであるとか、参加したくないとかいう理由で、レビューから逃れることを許すべきではない。

(コラム:Reducing Friction) 軽微な変更に対しては、より軽量なレビューを選択肢として提供できるようにすることを考えてみよう。Chapter 14 で述べたとおり、レビューはそれが必須である場合のみ有効に働く。ただし、どのような場合に軽量レビューを実施できるかを、ガイドラインで明確にする必要がある。

レビュアーが、意思決定するための十分なコンテキストを知らない場合は、レビューを断るか、他の人にレビューを回すという選択肢を保証すべきである。

自動チェックは、このようなコンテキストの構築を補助することができる。例として、Chapter 13 では、コードのサブミット前に、開発者とレビュアーに、セキュリティ問題を自動的に示すツール Tricorder を Google がどのように使っているかを示した。

Culture of Awareness

組織のメンバーが、自分たちのセキュリティと信頼性に対する責任に気づいていて、それを実践する方法を知っていたら、良い成果物を効率的に生み出すことができる。認知と教育の戦略は、強いセキュリティ文化を作るための鍵である。

Google では、従業員の教育のために、複数のアプローチを取っている。広範囲には、年1回の必須のトレーニングを全従業員に提供している。さらに、ここで伝えたメッセージを、役割ごとの特別なプログラムで強化している。Google での長年の実践により、有効とわかったいくつかの戦略を以下に示す。

  • Interactive talks
    • 参加型の講演。例えば、Google では重大なインシデントに関する主要な根本原因および緩和策について共有することで、私達がなぜこのようなトピックに集中しているかを従業員によく理解してもらうことができた
  • Games
    • 例えば、ゲームを通して XSS を見つける方法および悪用する方法を学べる XSS game
  • Reference documentation
    • Chapter 12 で、リファレンス文書の重要性を書いた。詳しい情報を口頭で正確に伝えることは難しい
  • Awareness campaigns
    • 開発者に、最近のセキュリティおよび信頼性に関する問題について知ってもらうことは難しい。この問題に対して、Google では1ページ形式の週刊のアドバイス "Testing on the Toilet" を発行している。これを全 Google オフィスのトイレに張り出している
  • Just-in-time notifications
    • なにか、良いプラクティスに反したことをした瞬間にタイミングよく知らせることで、従業員の理解を深めることができる。例えば、ソフトウェアを信頼できないリポジトリからアップグレードしようとしたときや、センシティブデータを未承認のクラウドストレージシステムにアップロードしようとしたときにポップアップを出す。Chapter 13 に、これに関連した話題を書いた

Culture of Yes

時とともに、組織にはリスクに対して保守的な文化が育ちやすい。特に、セキュリティ上の欠陥や信頼性の問題によって、収益を失ったり何らかの悪影響を被ったことがある場合はそうである。

そのような考え方は No の文化(a culture of no)、すなわちリスクのある変更や、ネガティブな結果になりうる変更を回避する文化に繋がりうる。健全な組織は、ある程度のリスクはあるがメリットのある選択を取る際に、"yes" と答えるための方法を持っている。

例えば、Chapter 8 の Google App Engine の例がある。Google App Engine は悪意のあるコードがその上で動く可能性があるサービスである。そのようなリスクはあるが、製品チームとセキュリティチームが連携することで、最終的にこのプロダクトをローンチできた。

リスクを許容するための他のアプローチには、エラーバジェットがある。

(コラム:Balancing Accountability and Risk Taking) コードレビューを行う人が、自分が最後の砦だ、と思うようになると、リスクのある変更は受け入れがたくなっていく。リスクを共用できるようにするためには、このプレッシャーを下げるための、例えば、最小権限や、回復性、テストといった要素のためのデザイン戦略が必要である。多層的なアプローチで、個人に対する重荷を軽くすることができる。例えばレビューでミスを犯しても他の自動的なチェックが働くなど。

Culture of Inevitably

完璧なシステムなどなく、どんなシステムもいつかは失敗する可能性がある。Googleでは、失敗はいつでも起こりうると仮定している。実世界のシステムは、100%セキュアかつ信頼できるとは決して言えないと私達は知っている。

Chapter 16 では、このような不可避の問題に対する準備の必要性について議論した。不可避の文化(culture of inevitability)を持つチームは、大規模な障害(disasters)に備えるために時間を割き、そのような場合に効率的に対応できる。

また、本書の Chapter 18、および SRE 本の Chapter 15 にある、批判のないポストモーテム(blameless postmortems)もその一例である。

Culture of Sustainability

システムの信頼性とセキュリティを長期的に維持するためには、その組織が、それらを改善するための努力を継続的に行う、つまり十分なリソース(スタッフと時間)を割き続けることを保証しなければならない。

この努力を維持するために、チームはリアクティブな仕事と、長期的に報われるプロアクティブな投資の間でバランスを取ることができなければならない。Chapter 17 の例では、効率的なチームは、ある1人に過大な責任を追わせないために、ハードワークを大勢の人の間で分かち合っていることを示した。

持続性の文化(a culture of sustainability)を持つ組織では、改善のための投資と同様に、運用業務(例えばインシデント対応)を扱うために必要な工数も計測する。ストレス、燃え尽き、士気(morale)を考慮する。

Google SRE の "follow the sun" シフトもその一例である(コラム:Sustainable Reliability and Security Culture at Google)。

持続性の文化を持つということは、例外的な状況では通常の業務量から一時的に逸脱することがありうるということを理解し、そのような逸脱を扱うための良いプロセスを持っているということも意味する。そのような例外的な状況が解決したあとで、引き続き持続性の文化を維持するために、以下のようなことを考慮するとよい。

  • 一時的な対応は、問題が解決したらもとに戻す。トイルが増えたまま戻さない、ということにならないようにする
  • 通常のプロセスを迂回する権限を持つ、専任のグループを持つ。ただし、ベストプラクティスを迂回したり覆した点を記録しておき、必ずあとで対処する
  • イベントが完了したら、ポストモーテムにて、今回の障害を導いた報酬システムを必ずレビューすること。開発を優先して信頼性やセキュリティを蔑ろにする文化では、このときに技術的負債を生む可能性がある

Changing Culture Through Good Practice

セキュリティと信頼性に関する新しい活動は、恐れを生じさせる。それは、開発速度を低下させるのではないか、新しいリスクを生じさせるのではないか、という恐れだ。しかし、著者らの意見としては、そのような摩擦を生じさせるというのは神話(myth)である。

もし、ある種の文化的な配慮を行ったうえで変更を実施すれば、それらの変化はすべての人の経験を向上させることができる、と私達は信じている。

この節では、変化を導入するための技術的な戦略について議論する。あなたは CEO やリーダーではないかもしれないが、すべての開発者、SRE、セキュリティ専門家はそれぞれの広さで影響を与えるための手段を持っている。

Align Project Goals and Participant Incentives

信頼を築くのは難しく、失うのは易しい。システムを設計、実装、維持する人々が、異なる役目を超えてコラボレーションするためには、みんなが共通の報酬システム(common reward system)を共有する必要がある。

技術的なレベルでは、プロジェクトの信頼性や安全性は、SLO のような測定可能なメトリクスや、脅威モデル(例:Chapter 2, 14)を通して評価できる。プロセスや人のレベルでは、信頼性や安全性への貢献がキャリアアップに繋がることを保証すべきである。理想的には、そのような評価基準が明文化されているべきである。

プロジェクトのゴールを組織の目的に揃える一方で、個人のインセンティブに揃えない場合、それは非協力的な組織文化に繋がりかねない。

Reduce Fear with Risk-Reduction Mechanisms

大きな変更は、組織の中で反対されることがある。そのような場合は、よいデプロイ上の選択を提示することで、信頼を得ることができる。Chapter 7 で触れた話題だが、組織文化への影響についてここで改めて触れる価値があるだろう。

  • Canaries and staged rollouts
    • 安全なリリースを繰り返すことで、次第に、組織はそのような気配りと勤勉さをすべての変更に期待するようになる。そして変更に対する信頼を構築し、恐れを減らすことができる
    • このようなリリース方法については SRE workbook の Chapter 16 で触れた。また本書の Chapter 19 では Chrome のリリースサイクルについて議論した
  • Dogfood
    • 自分たちが実施しようとしている変更を自分たち自身に適用し、それをユーザーに示すことで、その変更が安定性や生産性に与える影響をユーザーに保証することができる
    • 例えば、多要素認証のような新しいメカニズムを導入する際に、まず自分たちの業務に導入する
  • Trusted Testers
    • 社内でテスターを募集し、フィードバックをオープンに求める。そして、フィードバックを活用して、自分たちがフィードバックを聞いていることを知ってもらう
  • Opt in before mandatory
    • いきなり必須にするのではなく、移行期間を設ける。いつ有効化するかを選択できるようにする
  • Progressive stringency (漸進的な説得力、妥当性、厳密さ)
    • いきなり厳密なポリシーを適用するのではなく、徐々に適用できないかを考える
    • 例えば、最小権限を例に挙げると、最初は対象を開発者に制限したり、権限がないアクセスを拒否するのではなくエラーを出すだけに留めるなど

Make Safety Nets the Norm(セーフティネットを規範にする?)

信頼性およびセキュリティに対する改善が、あなたが今まで頼ってきたリソースを使えなくすることはよくある。例えば、いままで root 権限を使えていたものが使えなくなったら。緊急時の作業の妨げにならないか?といった恐れを抱くことは自然なことである。

breakglass procedures のようなセーフティネット(Chapter 5)を提供することで、変更に対する恐れを減らすことができる。セーフティネットは最後の手段であって、便利な代替手段とみなされないようにすべきである。また、システムを安全に保つための段階的なロールアウト手段が、場合によっては緊急リリースの邪魔になるかもしれない。変更を即座にプッシュするための迂回手段があれば、そのような懸念は避けられる。この種の状況については Chapter 14 で議論した。

Increase Productivity and Usability

セキュリティ及び信頼性の観点での組織的な変更が、生産性や使い勝手を落とすのではないか、という恐れが生じると、その導入を難しくする。そのため、導入戦略について注意深く考えることは重要である。私達は、以下のテクニックが摩擦を減らす助けになることを見てきた。

  • Build transparent functionality
    • Chapter 6, 12 にあるように、デフォルトの選択が良い状態なら、罰を与えるようなことをしなくても、開発者は正しいことをする
    • このアプローチではれば、開発者自身がセキュアかつ信頼できるシステムの恩恵を受けるだけでなく、これらの活動をシンプルかつ簡単にしようとしているあなたの意図を理解できる
  • Focus on usability
    • 今までの仕組みより、新しい仕組みのほうが使いやすければ、導入は簡単に進む
    • chapter 7 の二要素認証の例では、認証はセキュリティキーをタッチするだけで済むようになり、パスワードの定期変更も求められなくなった
  • Self-registration and self-resolution
    • Googleではインストールして良いソフトウェアの allow list と deny list を持っている。中央集中で管理していると、そこが許可のボトルネックになってしまう
    • Googleでは、これらのリストにないソフトをインストールしたいときには、Upvote というポータルを通して、必要な許可を迅速に得られるようにしている。また、大勢の希望があるときは自動的に許可する仕組みもある

Overcommunicate and Be Transparent

システム変更を主張する際に、コミュニケーション手段は結果に影響しうる。Chapter 7 および 19 で議論したように、よいコミュニケーションは変更への同意と信頼を得るための鍵である。

どのように変更が起こるかについての情報とわかりやすい知見を与えることで、人々の恐れを減らし、信頼を構築できる。私達は以下に示す戦略が成功するのを見てきた。

  • Document decisions
    • 変更を行うときは、なぜそれが起こっているのか、成功はどのように見えるのか、操作が状況を悪化させたらどのように変更をロールバックするのか、懸念がある場合は誰に話せばいいのかを明確に文書化する
    • それが従業員に直接影響する場合は特に、なぜあなたがその変更を行っているのかを明確に伝える
    • 注釈に、SRE が行う Production Excellence reviews についての記載あり
  • Create feedback channels
    • 懸念を持つ可能性がある人々が使えるフィードバックチャンネルを作り、双方向のコミュニケーションを作る
    • フィードバックフォームや、バグトラッキングシステムへのリンク、あるいは単なるメールアドレス
    • 関係者を巻き込むことで、恐れを減らすことができる
  • Use dashboards
    • あなたが人々に期待していることを明確に示し、その進捗に対するフィードバックを提供するためにダッシュボードを使う
  • Write frequent updates
    • 変更に長い時間がかかる(Google の場合は数年に渡ることも)場合は、進捗を頻繁に(例えば月1回)ステークホルダーに共有するための担当者をアサインする。これは、特にリーダーへの、信頼を得る役に立つ

Build Empathy

チームを超えた共感(Cross-team empathy)は、それがシステムの信頼性とセキュリティに関わるものであれば特に重要である。なぜなら、Chapter 20 で論じたように、信頼性とセキュリティに対する責任は組織全体で共有されるべきものだからである。

Chapter 19 では、チームを超えた共感を作るためのいくつかのテクニック、特に実装、デバッグ、コード修正に対する責任を共有する方法について述べた。

共感を作るための他のアプローチとしては Job shadowing(他の人の仕事を後ろで観察する)や job swapping(仕事を交換する)がある。これらはトップダウンでの組織的な変更を必要とせずに実施できる。これは数時間から、(マネジメント層の許可は必要だろうが)数ヶ月までの幅がありうる。他の人にあなたのチームの仕事を経験してもらうことで、あなたは組織のサイロを壊して、共通の理解を作ろうとしているというシグナルを送ることができる。

Google の SRE Security Exchange Program は、他の SRE やセキュリティエンジニアを1週間経験できる(shadow, 後ろで観察する)プログラムである。この交換プログラムの最後に、SRE は自分たちのチーム自身と、ホストチームの両方に対する改善提案をレポートに書く。このプログラムは非常に低い投資で、組織をまたいだ知識共有の面で大きな利益を生んでいる。他には、SRE 組織に6ヶ月参加してもらう Mission Control program もある。

最後に、感謝を伝える仕組みの構築(building in mechanisms to say thank you)ーー簡単なメールから、より詳細な形式のものまでーーは、人々がお互いに対して与えるポジティブな影響を強め、正しいインセンティブを与える。Google には、長年に渡るピアボーナスの文化がある。これの、現金のやり取りがないバージョンは Kudos と呼ばれるもので、Googler は全員に見えるフォーム上で感謝を伝えることができる。いくつかのオフィスでは、感謝のポストカードも試してきた。

Convincing Leadership(リーダーを説得する)

もしあなたが大きな組織で働いているなら、あなたが行いたいセキュリティや信頼性に関する変更に対して、支持を得る(原文では get buy-in = 買付を得る?)のは難しいことだろう。多くの組織は、自分たちの数少ないリソースを、利益を生むために使うように動機づけされているため、彼らの目に見えない部分を改善するための支持を得ることは難しい。

この節では、そのような変更に対して、リーダーからの支持を得るための戦略について見ていく。これらは私達が Google で用いたものに加え、他の場所で用いられているのを見たものも含む。

Understand the Decision-Making Process

ここでは、リーダー(leadership)という単語は、方針決定やリソース配分、利害関係の調整にまつわる決定を行うことができる人々を緩やかに指すものとする。

あなたがそれらの人々に影響を与えたいので、それが具体的に誰なのかを明らかにする必要がある。あなたが大企業で働いていたら、それは VP であったり、上位の管理職かもしれない。スタートアップや非営利団体のようなもっと小さな組織なら、それは CEO かもしれない。オープンソースプロジェクトなら、プロジェクトの創設者かトップコントリビューターだろう。

「誰がその変更に対する決定権を持っているのか?」という質問への答えは、解くのが難しい場合がある。それは組織上のリーダーではなく、テックリードのような場合もある。また、複数の人の場合もある。Chapter 7 で述べた Chrome の HTTPS 対応の例のように、コミュニティの場合もある。しかし、この質問の答えを避けて通ることはできない。

意思決定者を見つけたら、その人が直面している困難や要求について理解しようとすべきである。それらを理解することは、あなたの提案する変更がうまくはまる場所を理解するために重要である。

Build a Case for Change

すでに述べたように、変更への抵抗は、恐れや摩擦の認識に起因する。しかし、多くのケースでは、変更の理由を理解していないことにも起因する。

成功する case-building process に必要なステップを以下に示す。

※ ここで言う case はどういう意味? リーダーに問題として認識してもらう、といった意味?

  • Gather data
    • 変更が必要と思うに至った理由があるはず。それをデータで説明できること
  • Educate others
    • 例えば、Google の Red Team postmortems(Chapter 20)。SREが直面するリスクの種類について、リーダーを教育するためのもの。もともとは教育が目的に作られたものではないが、会社の全階層における認識を高めることができる
  • Align incentives
    • 他の面でもメリットが有ることを説明し、お互いにインセンティブがあるという状態にする
    • 例えば、DDoS 攻撃に強いフレームワークを導入することで、セキュリティ上の利点に加えて、より安定したウェブサイトは売上を高めるという効果もある。これは企業のリーダー層にとって強い根拠になる
  • Find allies(支持者を探す)
    • 支持者の存在は説得力を高めるし、あなたの論拠をピアレビューしてより強くしてくれる
  • Observe industry trends
    • あなたが適用しようとしている変更が、他の組織がすでに適用している変更であれば、その他組織の経験はあなたの組織のリーダー層を説得する際の助けになるかもしれない。その特定のトピックおよび業界トレンドに詳しいエキスパートを呼んで、あなたの組織のリーダー層に説明してもらうことさえ可能かもしれない。
  • Change the zeitgeist(時代精神を変える)
    • もしあなたが、あなたの問題について日々考えている人々の考え方を変えられるなら、そのあとで意思決定者を説得するのはより容易だろう。これは、あなたがその変更に対する広いコンセンサスを必要としているときに、特に有効である。Chapter 7 の HTTPS のケーススタディはこれにあたる

Pick Your Battles

組織が信頼性とセキュリティの課題に数多く直面している場合、継続的なアドバイスは、アドバイスされることへの疲れや、追加の変更への抵抗感を生んでしまう。あなたの戦う場所を慎重に選ぶ(pick your battles carefully)、つまり成功する見込みのある取り組みを優先し、勝ち目のない戦い(lost causes)の止めどきを知ることが重要である。

勝ち目のない戦い、つまり棚上げにしなければならない提案にも価値がある。変更をうまく主張できないときでさえ、自分のアイデアを裏付けるデータや、自分の計画を支持してくれる仲間がいること、そして問題について人々を教育することには、価値がある。将来、あなたの組織がその課題に取り組む準備ができたときに、それまでにあなたが準備したものがあれば、チームはより素早く行動することができる。

Escalations and Problem Resolution

最善の努力を尽くしても、セキュリティや信頼性に関わる変更についての意思決定の必要が、爆発的に表面化することがある。重大な障害やセキュリティ脆弱性により、あなたは急遽追加のリソースやスタッフを必要とするかもしれない。あるいは、2つのチームが問題解決の方法について異なる意見を持ち、意思決定の自然な流れが働かないかもしれない。

このような状況では、あなたはマネジメントチェーンから解決手段を探す必要があるかもしれない。意思決定のエスカレーションを行う場合、私達は以下のガイドラインを推奨する。

  • その状況に関する意見を、両方の側から提供するために、同僚、メンター、テックリード、またはマネージャーのグループを作る
  • そのグループに、現在の状況と、提案された選択肢を、マネジメント層のために要約させる
  • あり得る解決手段についてさらに調整するために、あなた自身のチームのリーダーにその要約を共有する
  • 影響を受けるマネジメントチェーン全員にその状況を説明し、それぞれのチェーンでの適切な意思決定者を指名するための会議を設定する

具体例をあげると、Googleでは、セキュリティ問題に対するアクションについて、プロダクトチームとセキュリティレビュアーの間で意見が一致しなかった場合に、エスカレーションが必要になる。このケースでは、セキュリティチームからエスカレーションが開始される。Googleではこのようなエスカレーションを通常の企業文化の一部としているため、エスカレーションは対立的なものとはみなされない。

Conclusion

あなたがシステムを設計して管理するのと同様に、あなたはセキュリティと信頼性の目標を達成するために、時間をかけて組織の文化を設計、実装そして維持することができる。

セキュリティと信頼性の向上は、摩擦の増大に対する恐れや懸念を抱かせることがある。そのような恐れに対処し、変更の影響を受ける人々からの支持を得るのを助けるための戦略がある。あなたのゴールと、リーダーを含むステークホルダーのゴールを揃えることが鍵である。ユーザビリティに焦点を当て、ユーザーへの共感を行動で示すことで、ユーザーが変化を受け入れることを促すことができる。他の人が変化をどのように認識しているかを理解するために小さな投資をすることで、あなたの変更が妥当なものだとユーザーに納得させることができるかもしれない。

この章の冒頭で述べたように、同じ文化は2つとして無いので、本書で紹介した戦略をあなた自身の組織に適合させる必要がある。あなたの組織で最も解決すべき問題領域を選び、それを時間をかけて解決していくことが必要である。

ここまでの感想

最終章だけあって、本書のエッセンスが詰まったような章でした。自分の SRE としての経験からも頷ける内容が多い一方で、本章にある「恐れを抱く側」になっていることも時々あるな、と感じました。

あとは、普段自分でもなんとなく考えていたことがうまく明文化されていたので、他の人と議論するときに本書の概念をうまく使っていきたいと思いました。特に「持続性の文化(a culture of sustainability)」は、そういうふうに表現するのかと感心しました。

さて次はどの章を読もうか……。あとはざっと読むだけで、特に面白かった箇所だけ読書メモを残すようにしようか、とも考えてます。

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.

ここまでの感想

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

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