AWS × 形式手法で人知を超えたセキュリティを手に入れろ #jd2018_c #jawsdays / JAWS DAYS 2018

332f89cc697355902a817506b6995f2b?s=47 y_taka_23
March 10, 2018

AWS × 形式手法で人知を超えたセキュリティを手に入れろ #jd2018_c #jawsdays / JAWS DAYS 2018

JAWS DAYS 2018 で使用したスライドです。形式手法の一種、モデル検査器 Alloy を用いて AWS の IAM 設定を検証する手法について解説しました。公式が提供する IAM Policy Simulator でできるのはすでに存在するポリシの検証までですが、本手法では一歩進んで設計の段階からツールがサポートします。

講演概要:https://jawsdays2018.jaws-ug.jp/session/1476/
ブログ:http://ccvanishing.hateblo.jp/entry/2018/05/18/205101

332f89cc697355902a817506b6995f2b?s=128

y_taka_23

March 10, 2018
Tweet

Transcript

  1. 5.

    IAM 設定の難しさ ★ 機能そのものの複雑性 ◦ そもそも設定できる項目が多い ◦ 多数の AWS リソースの連携が必要

    ◦ 最小権限の原則から細分化されがち ★ 運用の中でより複雑化 ◦ 設定ミスすると被害が大きい ◦ 既存の Policy に手を出せなくなる #jd2018_c
  2. 6.

    IAM 設定を補助するツール ★ Policy Validator ◦ 構文的なチェックのみ ★ Visual Editor

    ★ IAM Policy Simulator ◦ 操作主体となる Group や User を選ぶ ◦ 操作対象となる Resource や Action を選ぶ ◦ Allow または Deny を判定してくれる #jd2018_c
  3. 8.

    IAM Policy Simulator の限界 ★ 論理的な不整合が検出できない ◦ 重複や互いに矛盾する Policy の存在

    ★ 具体的な設定は教えてくれない ◦ 結局は経験とカンによる設計に ★ IAM 以外の要素を考慮できない ◦ 例えばセキュリティグループや VPC 設計と合わせて考えたいとき困る #jd2018_c
  4. 11.

    形式手法とは ★ システムを数学的対象として記述 ◦ その対象に関する理論を用いて検証 ◦ 選んだ対象によって特性が変わる ★ いわゆるテストと比較すると ◦

    テストケースの漏れが生じない ◦ 実装以前の設計レベルで検査できる ◦ さほど普及しておらず習熟者が少ない #jd2018_c
  5. 13.

    Alloy の特徴 ★ 関係論理でシステムを定義 ◦ データモデル的な表現に向く ★ SAT ソルバにより具体例を発見 ◦

    条件を満たす例を自動で全列挙 ◦ コーナーケースも含め機械的に網羅 ★ 発見した具体例を可視化 ◦ 直感的で導入のハードルが下がる #jd2018_c
  6. 15.
  7. 16.
  8. 17.
  9. 18.

    システムを関係論理で記述 ★ シグニチャ ◦ 有限集合を表す ◦ さっきの例では User や Policy

    ★ フィールド ◦ シグニチャ上の関係を表す ◦ さっきの例では policy ◦ 実体は部分集合 policy ⊆ User × Policy #jd2018_c
  10. 19.

    (u0, p0) (u0, p1) (u0, p2) (u1, p0) (u1, p1)

    (u1, p2) (u2, p0) (u2, p1) (u2, p2) User0 User1 User2 Policy0 Policy1 Policy2 #jd2018_c
  11. 23.

    関係の多重度 ★ 対応する要素の個数を指定 ◦ one : ちょうど 1 個(デフォルト) ◦

    lone : 0 個または 1 個 ◦ set : 0 個以上 ◦ some : 1 個以上 ◦ no : 0 個 ★ ER 図における 1..* などに相当 #jd2018_c
  12. 24.

    二種類の検査モード ★ assert + check ◦ 必ず満たされてほしい条件を与える ◦ 全探索して違反が存在すれば表示 ★

    pred + run ◦ 満たされるかどうか不明な条件を与える ◦ 全探索して条件を満たす例を発見 #jd2018_c
  13. 28.

    Alloy vs IAM Simulator ★ 論理的な不整合が検出できない ◦ assert + check

    で違反を検出 ★ 具体的な設定は教えてくれない ◦ ★ IAM 以外の要素を考慮できない ◦ #jd2018_c
  14. 29.

    { “Version”: “2012-10-17” “Statement”: [ { “Effect”: “Allow”, “Action”: [“ec2:*”],

    “Resource”: [“*”] }, ] } { “Version”: “2012-10-17” “Statement”: [ { “Effect”: “Deny”, “Action”: [“ec2:*”], “Resource”: [“*”] } ] } #jd2018_c
  15. 30.

    { “Version”: “2012-10-17” “Statement”: [ { “Effect”: “Allow”, “Action”: [“ec2:*”],

    “Resource”: [“*”] }, ] } { “Version”: “2012-10-17” “Statement”: [ { “Effect”: “Deny”, “Action”: [“ec2:*”], “Resource”: [“*”] } ] } 同時に設定されると無意味 #jd2018_c
  16. 31.

    assert noConflictWithAllowAndDeny { no u : User { some p1,

    p2 : u.policy, s1 : p1.statement, s2 : p2.statement { s1.effect = Allow s2.effect = Deny some (s1.resource & s2.resource) some (s1.action & s2.action) } } } fact singleStatement { all p : Policy | lone p.statement } check noConfictWithAllowAndDeny #jd2018_c
  17. 32.

    assert noConflictWithAllowAndDeny { no u : User { some p1,

    p2 : u.policy, s1 : p1.statement, s2 : p2.statement { s1.effect = Allow s2.effect = Deny some (s1.resource & s2.resource) some (s1.action & s2.action) } } } fact singleStatement { all p : Policy | lone p.statement } check noConfictWithAllowAndDeny s1 と s2 がバッティング #jd2018_c
  18. 33.

    assert noConflictWithAllowAndDeny { no u : User { some p1,

    p2 : u.policy, s1 : p1.statement, s2 : p2.statement { s1.effect = Allow s2.effect = Deny some (s1.resource & s2.resource) some (s1.action & s2.action) } } } fact singleStatement { all p : Policy | lone p.statement } check noConfictWithAllowAndDeny Policy ごとに Statement が高々1 つなら大丈夫 (?) #jd2018_c
  19. 35.

    Alloy vs IAM Simulator ★ 論理的な不整合が検出できない ◦ assert + check

    で違反を検出 ★ 具体的な設定は教えてくれない ◦ ★ IAM 以外の要素を考慮できない ◦ #jd2018_c
  20. 36.

    Alloy vs IAM Simulator ★ 論理的な不整合が検出できない ◦ assert + check

    で違反を検出 ★ 具体的な設定は教えてくれない ◦ pred + run で仕様から実装を発見 ★ IAM 以外の要素を考慮できない ◦ #jd2018_c
  21. 37.

    sig Statement { effect : one Effect, resource : set

    Resource, action : set Action, notAction : set Action } fact exclusiveAction { all s : Statement { some s.action => no s.notAction some s.notAction => no s.action } } pred deniedByStatement(s : Statement, r : Resource, a : Action) { s.effect = Deny r in s.resource a in s.action or (some s.notAction and a not in s.notAction) } #jd2018_c
  22. 38.

    sig Statement { effect : one Effect, resource : set

    Resource, action : set Action, notAction : set Action } fact exclusiveAction { all s : Statement { some s.action => no s.notAction some s.notAction => no s.action } } pred deniedByStatement(s : Statement, r : Resource, a : Action) { s.effect = Deny r in s.resource a in s.action or (some s.notAction and a not in s.notAction) } 除外アクション #jd2018_c
  23. 39.

    sig Statement { effect : one Effect, resource : set

    Resource, action : set Action, notAction : set Action } fact exclusiveAction { all s : Statement { some s.action => no s.notAction some s.notAction => no s.action } } pred deniedByStatement(s : Statement, r : Resource, a : Action) { s.effect = Deny r in s.resource a in s.action or (some s.notAction and a not in s.notAction) } 除外アクションが指定されているが a は該当せず #jd2018_c
  24. 40.

    pred allowedByStatement(s : Statement, ...) {...} pred deniedByPolicy(p : Policy,

    ...) {...} pred allowedByPolicy(p : Policy, ...) {...} pred allowed(u : User, r : Resource, a : Action) { no p : u.policy | deniedByPolicy[p, r, a] some p : u.policy | allowedByPolicy[p, r, a] } pred requirement { some u : User, r : Resource, a : Action { allowed[u, r, a] } } run requirement #jd2018_c
  25. 41.

    pred allowedByStatement(s : Statement, ...) {...} pred deniedByPolicy(p : Policy,

    ...) {...} pred allowedByPolicy(p : Policy, ...) {...} pred allowed(u : User, r : Resource, a : Action) { no p : u.policy | deniedByPolicy[p, r, a] some p : u.policy | allowedByPolicy[p, r, a] } pred requirement { some u : User, r : Resource, a : Action { allowed[u, r, a] } } run requirement 禁止する Policy がなく、かつ許可する Policy が存在 #jd2018_c
  26. 42.

    pred allowedByStatement(s : Statement, ...) {...} pred deniedByPolicy(p : Policy,

    ...) {...} pred allowedByPolicy(p : Policy, ...) {...} pred allowed(u : User, r : Resource, a : Action) { no p : u.policy | deniedByPolicy[p, r, a] some p : u.policy | allowedByPolicy[p, r, a] } pred requirement { some u : User, r : Resource, a : Action { allowed[u, r, a] } } run requirement アクセスが許可される具体例は? #jd2018_c
  27. 45.

    Alloy vs IAM Simulator ★ 論理的な不整合が検出できない ◦ assert + check

    で違反を検出 ★ 具体的な設定は教えてくれない ◦ pred + run で仕様から実装を発見 ★ IAM 以外の要素を考慮できない ◦ #jd2018_c
  28. 46.

    Alloy vs IAM Simulator ★ 論理的な不整合が検出できない ◦ assert + check

    で違反を検出 ★ 具体的な設定は教えてくれない ◦ pred + run で仕様から実装を発見 ★ IAM 以外の要素を考慮できない ◦ サービス単位でモジュール分割 #jd2018_c
  29. 47.

    module s3 enum Resource { Bucket, Object, ...} enum Action

    { ListBucket, PutObject, GetObject, ...} module ec2 open s3 enum Resource { Instance, SecurityGroup, ...} enum Action { StartInstances, StopInstances, ...} pred accessibleViaEndpoint(i : Instance, b : s3/Bucket) { ... } #jd2018_c
  30. 48.

    module s3 enum Resource { Bucket, Object, ...} enum Action

    { ListBucket, PutObject, GetObject, ...} module ec2 open s3 enum Resource { Instance, SecurityGroup, ...} enum Action { StartInstances, StopInstances, ...} pred accessibleViaEndpoint(i : Instance, b : s3/Bucket) { ... } S3 用モジュール EC2 用モジュール #jd2018_c
  31. 49.

    module s3 enum Resource { Bucket, Object, ...} enum Action

    { ListBucket, PutObject, GetObject, ...} module ec2 open s3 enum Resource { Instance, SecurityGroup, ...} enum Action { StartInstances, StopInstances, ...} pred accessibleViaEndpoint(i : Instance, b : s3/Bucket) { ... } モジュールの読み込み #jd2018_c
  32. 50.

    module s3 enum Resource { Bucket, Object, ...} enum Action

    { ListBucket, PutObject, GetObject, ...} module ec2 open s3 enum Resource { Instance, SecurityGroup, ...} enum Action { StartInstances, StopInstances, ...} pred accessibleViaEndpoint(i : Instance, b : s3/Bucket) { ... } IAM 外、EC2 特有の条件 #jd2018_c
  33. 51.

    module main open s3 open ec2 open iam one sig

    Binder { res : iam/Resource one -> one (s3/Resource + ec2/Resource) act : iam/Action one -> one (s3/Action + ec2/Action) } pred requirement { some u : iam/User, b : s3/Bucket, i : ec2/Instance { iam/allowed[u, Binder.res.b, Binder.act.s3/GetObject] ec2/accessibleViaEndpoint[i, b] } } #jd2018_c
  34. 52.

    module main open s3 open ec2 open iam one sig

    Binder { res : iam/Resource one -> one (s3/Resource + ec2/Resource) act : iam/Action one -> one (s3/Action + ec2/Action) } pred requirement { some u : iam/User, b : s3/Bucket, i : ec2/Instance { iam/allowed[u, Binder.res.b, Binder.act.s3/GetObject] ec2/accessibleViaEndpoint[i, b] } } 個別サービス + IAM を読み込み #jd2018_c
  35. 53.

    module main open s3 open ec2 open iam one sig

    Binder { res : iam/Resource one -> one (s3/Resource + ec2/Resource) act : iam/Action one -> one (s3/Action + ec2/Action) } pred requirement { some u : iam/User, b : s3/Bucket, i : ec2/Instance { iam/allowed[u, Binder.res.b, Binder.act.s3/GetObject] ec2/accessibleViaEndpoint[i, b] } } S3 系リソースと EC2 系リソースの和集合 #jd2018_c
  36. 54.

    module main open s3 open ec2 open iam one sig

    Binder { res : iam/Resource one -> one (s3/Resource + ec2/Resource) act : iam/Action one -> one (s3/Action + ec2/Action) } pred requirement { some u : iam/User, b : s3/Bucket, i : ec2/Instance { iam/allowed[u, Binder.res.b, Binder.act.s3/GetObject] ec2/accessibleViaEndpoint[i, b] } } IAM 側の (抽象的な) リソースと 1 : 1 対応 #jd2018_c
  37. 55.

    module main open s3 open ec2 open iam one sig

    Binder { res : iam/Resource one -> one (s3/Resource + ec2/Resource) act : iam/Action one -> one (s3/Action + ec2/Action) } pred requirement { some u : iam/User, b : s3/Bucket, i : ec2/Instance { iam/allowed[u, Binder.res.b, Binder.act.s3/GetObject] ec2/accessibleViaEndpoint[i, b] } } IAM 以外の条件も混ぜて扱える #jd2018_c
  38. 56.

    Alloy vs IAM Simulator ★ 論理的な不整合が検出できない ◦ assert + check

    で違反を検出 ★ 具体的な設定は教えてくれない ◦ pred + run で仕様から実装を発見 ★ IAM 以外の要素を考慮できない ◦ サービス単位でモジュール分割 #jd2018_c
  39. 58.

    まとめ ★ 形式手法とは何か ◦ システムを数学的に記述し検査 ◦ Alloy の場合は関係論理ベース ★ Alloy

    のアドバンテージ ◦ 意図しない設定の不整合を例とともに検出 ◦ 仕様から考えられる実装を発見・列挙 ◦ モジュール化・拡張可能なモデル #jd2018_c
  40. 60.

    Credits Special thanks to all the people who made and

    released these awesome resources for free: ▷ Presentation template by SlidesCarnival ▷ Photographs by Unsplash 60 #jd2018_c