aws は形式手法の夢を見るか? - モデル検査器 alloy によるインフラ設計
TRANSCRIPT
AWS は形式手法の夢を見るか?
モデル検査器 Alloy によるインフラ設計
チェシャ猫 (@y_taka_23)
NGK2015B 昼の部 (2015/12/05)
自己紹介
● 名前 : チェシャ猫
○ Twitter: @y_taka_23
○ GitHub: y-taka-23
● 仕事 : インフラ担当
○ 主に AWS 周り
○ もうちょいアプリ側やりたい
Amazon Web Service
AWS のネットワーク周り
● セキュリティ系
○ Security Group
○ Network ACL
● ルーティング系
○ Route Table
○ VPC Peering
○ Route 53
しかし現実は……
複雑化、破綻しがちな運用
● セキュリティ系()
○ 場当たり的に開けられるポート
○ 誰も把握できない許可・禁止ルールの重複
● ルーティング系()
○ あちらが通じればこちらが通じない Route Table
○ なぜか解決できないドメイン名
○ どんどん増える VPC Peering
インフラをきちんと設計したい?
形式手法を使ってみよう!
Alloy Analyzer って?
● 形式手法の一種、モデル検査のツール
● 低い検証コスト + 強力な可視化
○ 関係によってモデルを定義
○ 検査したい制約を記述
○ 制約を満たす / 満たさない例を全数探索
○ 発見した例をいい感じに可視化
例えば Security Group
https://gist.github.com/y-taka-23/89a98fdb2ba48710a39c
関係でモデルを定義する
sig Instance { priIPs : some IP, secGrps : set SecurityGroup,}
sig SecurityGroup { inRules : set Rule, outRules : set Rule,}
関係でモデルを定義する
sig Instance { priIPs : some IP, secGrps : set SecurityGroup,}
sig SecurityGroup { inRules : set Rule, outRules : set Rule,}
インスタンス 1 個に対してIP アドレスが 1 個以上複数個対応
関係でモデルを定義する
sig Instance { priIPs : some IP, secGrps : set SecurityGroup,}
sig SecurityGroup { inRules : set Rule, outRules : set Rule,}
インスタンス 1 個に対してセキュリティグループが 0 個以上複数個対応
検査したい制約を記述する
pred inboundOK(src, dest : Instance, proto : Protocol, port Port) { some r : dest.secGrps.inRules | proto = r.protocol && port in r.ports && some (src.priIPs in r.source.ips + src.secGrps in r.souce)}
検査したい制約を記述する
pred inboundOK(src, dest : Instance, proto : Protocol, port Port) { some r : dest.secGrps.inRules | proto = r.protocol && port in r.ports && some (src.priIPs in r.source.ips + src.secGrps in r.souce)}
通信先インスタンスのセキュリティグループのあるインバウンドルール r について
検査したい制約を記述する
pred inboundOK(src, dest : Instance, proto : Protocol, port Port) { some r : dest.secGrps.inRules | proto = r.protocol && port in r.ports && some (src.priIPs in r.source.ips + src.secGrps in r.souce)}
ルール r は指定されたプロトコルで
検査したい制約を記述する
pred inboundOK(src, dest : Instance, proto : Protocol, port Port) { some r : dest.secGrps.inRules | proto = r.protocol && port in r.ports && some (src.priIPs in r.source.ips + src.secGrps in r.souce)} ルール r は指定されたポート番号を含み
検査したい制約を記述する
pred inboundOK(src, dest : Instance, proto : Protocol, port Port) { some r : dest.secGrps.inRules | proto = r.protocol && port in r.ports && some (src.priIPs in r.source.ips + src.secGrps in r.souce)}
ルール r は送信元インスタンスのプライベート IPまたはセキュリティグループを含む
具体例を全数探索
run { some disj i1 i2 : Instance, proto : Protocol, port : Port | inboundOK[i1, i2, proto, port] && outboundOK[i1, i2, proto, port]}
具体例を全数探索
run { some disj i1 i2 : Instance, proto : Protocol, port : Port | inboundOK[i1, i2, proto, port] && outboundOK[i1, i2, proto, port]}相異なる 2 つのインスタンス i1, i2 について
具体例を全数探索
run { some disj i1 i2 : Instance, proto : Protocol, port : Port | inboundOK[i1, i2, proto, port] && outboundOK[i1, i2, proto, port]}
Security Group の設定上、通信が可能
この間、わずか 0.3 秒
発見された具体例いろいろ
発見された具体例いろいろ
発見された具体例いろいろ
こんな応用どうだろう?
● 通信の到達可能性 / 不可能性の確認
● 不要なルール設定の発見
● IAM によるアクセス権限制御の検証
● 無駄に課金しない運用フローの作成
まとめ
● インフラ設計に形式手法の力を
● Alloy Analyzer でお手軽モデリング
● アイデア次第で色々な応用が