Upgrade to Pro — share decks privately, control downloads, hide ads and more …

OpenPolicyAgentでValidationするセキュアなパイプライン入門

ipppppei
October 21, 2022

 OpenPolicyAgentでValidationするセキュアなパイプライン入門

ipppppei

October 21, 2022
Tweet

Other Decks in Technology

Transcript

  1. Confidential │ © VMware, Inc. 2 Agenda • OpenPolicyAgentとは •

    OpenPolicyAgent利⽤時のCI/CDと課題 • Konstraint • まとめ
  2. Confidential │ © VMware, Inc. 3 こんなことありませんか︖ あなた (クラスタ管理者) 新⽶のクラスタ利⽤者

    最⾼のアプリが出来たので、とりあえず開発環境に デプロイすっか。 開発⽤途だし、ミドルウェアは適当なものを Dockerhubから拾ってくればいいや。
  3. Confidential │ © VMware, Inc. 4 こんなことありませんか︖ あなた (クラスタ管理者) 新⽶のクラスタ利⽤者

    おい︕デプロイ先が本番⽤クラスタになってるぞ︕ 本番環境にDockerhubから引っ張った イメージおいちゃったよ セキュリティ事故おきたらどうすんだよ おい、アプリがバグってメモリ⾷いすぎて 、本番のサービスが死にだしたぞ
  4. Confidential │ © VMware, Inc. 5 こんなことありませんか︖ あなた (クラスタ管理者) 新⽶のクラスタ利⽤者

    っておい︕Namespaceごと削除すんなーーー︕︕ ひええ、すぐに⽌めます
  5. Confidential │ © VMware, Inc. 7 ⼀般的には・・・ • 認証・認可の仕組みを使って抑⽌する ただし、RBACだけだと難しいことも多い

    今回のケースで欲しかったもの︓ • コンテナレジストリの制限 • 特定のNamespaceのみ利⽤ • limitsの設定必須化
  6. Confidential │ © VMware, Inc. 8 Open Policy Agent(OPA︓オーパ) OPA︓OSSの汎⽤ポリシーエンジン(CNCFのGraduated

    Project) ポリシー実⾏ポイント ポリシーエンジンとは(⼀般論) ポリシーエンジン リソース ①アクセス要求 ②アクセス可否の チェック依頼 ②アクセス可否の 連絡 ③アクセス許可 ③アクセス拒否 Policy 稼働 情報 静的に定義されたポリシー や動的な稼働情報を元に アクセス可否を判断
  7. Confidential │ © VMware, Inc. 9 Open Policy Agent(OPA︓オーパ) OPA︓OSSの汎⽤ポリシーエンジン(CNCFのGraduated

    Project) ポリシー実⾏ポイント ポリシーエンジンとは(OPA) ポリシーエンジン (Admission Controller) リソース ①利⽤要求 ②利⽤可否の チェック依頼 ②利⽤可否の 連絡 ③利⽤許可 ③利⽤拒否 Rego 稼働 情報 RegoというOPAのPolicy 記載⽤⾔語で書かれた Policyを解釈 Admission Cotroller として実装 Gatekeeperとしてだけでなく、 監査⽬的(チェックのみ)でも利⽤可能
  8. Confidential │ © VMware, Inc. 10 Open Policy Agent(OPA︓オーパ) ポリシー実⾏ポイント

    ポリシーエンジン (Admission Controller) リソース ①利⽤要求 ②利⽤可否の チェック依頼 ②利⽤可否の 連絡 ③利⽤拒否 Rego ・dockerhub禁⽌ ・Namespace規制 ・limit必須 稼働 情報 実装イメージ︓ apiVersion: templates.gatekeeper.sh/v1 kind: ConstraintTemplate : spec: targets: - target: admission.k8s.gatekeeper.sh rego: | <Policy> Rego部分
  9. Confidential │ © VMware, Inc. 11 余談︓Tanzu Mission ControlのOPA •

    予めテンプレートが⽤意 • Regoを書かなくてもPolicy設定可能 (勝⼿にRegoを書いてくれる) • OPA Gatekeeperも⾃動インストール
  10. Confidential │ © VMware, Inc. 12 ちなみに・・・ https://kubernetes.io/docs/concepts/security/pod-security-policy/ • 従来⼩回りの効く権限管理のための

    Admission ControllerはPSPだった • v1.25で廃⽌された = 最新版ではもう使えない • 後継はPSA(Pod Security Admission) → OPAはKubernetesのコンポーネントではない あくまでも3rd partyのAdmission Controller その他PSPの代替候補 ・K-Rail ・Kyverno
  11. Confidential │ © VMware, Inc. 13 OPA利⽤時のCI/CD push to /my-app

    push to /my-app-manifest AppのManifest作成 Push Appのコード修正 Push/PR E2E Test Test失敗 Polling Sync Policy 違反 デプロイできないので テストも失敗
  12. Confidential │ © VMware, Inc. 14 OPA利⽤時のCI/CD push to /my-app

    push to /my-app-manifest AppのManifest作成 Push Appのコード修正 Push/PR E2E Test Test成功/失敗 Polling Sync ManifestのValidation 事前にManifestをValidation(検証=テスト)し、 動くもののみをPushするようにする
  13. Confidential │ © VMware, Inc. 15 ManifestのValidation⽅法と課題 ▪Conftest • OpenPolicyAgent標準のPolicyテストツール

    • K8s Manifest以外もDockerfile、AWS SAM、Jsonnet等様々なフォーマットに対応 • 出⼒フォーマットも多彩(json, tap, table, junit, github) $ conftest test -p . -n ns_policy ./nginx.yaml FAIL - ./nginx.yaml - ns_policy - invalid namespace: kube-system 1 test, 0 passed, 0 warnings, 1 failure, 0 exceptions $ conftest test -p . -n ns_policy nginx.yaml -o table +---------+------------+-----------+--------------------------------+ | RESULT | FILE | NAMESPACE | MESSAGE | +---------+------------+-----------+--------------------------------+ | failure | nginx.yaml | ns_policy | invalid namespace: kube-system | +---------+------------+-----------+--------------------------------+ apiVersion: v1 kind: Pod metadata: name: nginx namespace: kube-system deniedNamespaces := [ "kube-system", "gitlab" ] violation[{"msg": msg}] { deniedNamespaces[_] == input.metadata.namespace msg := sprintf("denied namespace: %v", [input.metadata.namespace]) } nginx.yaml ns_policy.rego
  14. Confidential │ © VMware, Inc. 16 ManifestのValidation⽅法と課題 ▪Conftest • OpenPolicyAgent標準のPolicyテストツール

    • K8s Manifest以外もDockerfile、AWS SAM、Jsonnet等様々なフォーマットに対応 • 出⼒フォーマットも多彩(json, tap, table, junit, github) • OPA GatekeeperのRegoはそのままサポートしていない → 検証⽤のRegoとGatekeeper⽤のRegoの2つを管理することになる 例)特定のNamespaceの利⽤を禁⽌する deniedNamespaces := [ "kube-system", "gitlab" ] violation[{"msg": msg}] { deniedNamespaces[_] == input.metadata.namespace msg := sprintf("denied namespace: %v", [input.metadata.namespace]) } conftest (検証⽤Rego) deniedNamespaces := [ "kube-system", "gitlab" ] violation[{"msg": msg}] { deniedNamespaces[_] == input.review.namespace msg := sprintf("denied namespace: %v", [input.review.namespace]) } ConstraintTemplate (Gatekeeper⽤Rego) ※⽐較⽤なので、いい書き⽅ではありません ※ConstraintTemplate⾃体はManifestで ここではRego部分のみ抜粋
  15. Confidential │ © VMware, Inc. 17 ManifestのValidation⽅法と課題 ▪Conftest • OpenPolicyAgent標準のPolicyテストツール

    • K8s Manifest以外もDockerfile、AWS SAM、Jsonnet等様々なフォーマットに対応 • 出⼒フォーマットも多彩(json, tap, table, junit, github) • OPA GatekeeperのRegoはそのままサポートしていない → 検証⽤のRegoとGatekeeper⽤のRegoの2つを管理することになる 例)特定のNamespaceの利⽤を禁⽌する deniedNamespaces := [ "kube-system", "gitlab" ] violation[{"msg": msg}] { deniedNamespaces[_] == input.metadata.namespace msg := sprintf("denied namespace: %v", [input.metadata.namespace]) } conftest (検証⽤Rego) deniedNamespaces := [ "kube-system", "gitlab" ] violation[{"msg": msg}] { deniedNamespaces[_] == input.review.namespace msg := sprintf("denied namespace: %v", [input.review.namespace]) } ConstraintTemplate (Gatekeeper⽤Rego) ※⽐較⽤なので、いい書き⽅ではありません ※ConstraintTemplate⾃体はManifestで ここではRego部分のみ抜粋 ⼀元管理のためのアプローチ ・検証⽤RegoからGatekeeper⽤リソースを⽣成する → Konstraint ★今⽇のメイン (Gatekeeper⽤リソースを管理しない) ・Gatekeeper⽤リソースで検証する → Gator (検証⽤Regoを管理しない)
  16. Confidential │ © VMware, Inc. 18 /template /constraint Policyの共通化︓Konstraint Gatekeeper⽤

    Manifestの作成 検証⽤Rego の作成 /rego 従来︓ RegoとManifestを別々に管理(メンテ) 検証⽤Rego の作成 /rego Konstraint︓ Regoで⼀元管理 konstraint create kubectl apply -f /tmpleate -f /constraint kubectl apply -f /tmpleate -f /constraint Konstraint︓ • Regoファイルを元にGatekeeper⽤Manifestを⾃動⽣成するツール • conftestのPluginとRegoをManifestに変換するCLIから構成
  17. Confidential │ © VMware, Inc. 19 KonstraintのRego deniedNamespaces := [

    "kube-system", "gitlab" ] violation[{"msg": msg}] { deniedNamespaces[_] == input.metadata.namespace msg := sprintf("denied namespace: %v", [input.metadata.namespace]) } conftest (検証⽤Rego) import data.lib.core deniedNamespaces := [ "kube-system", "gitlab" ] violation[{"msg": msg}] { deniedNamespaces[_] == core.resource.metadata.namespace msg := sprintf("invalid namespace: %v", [core.resource.metadata.namespace]) } conftest (Konstaint対応Rego) konstraintのライブラリ (data.lib.core)を利⽤して inputを置き換える 実⾏コマンドは同じ︓ $ conftest test -p . -n ns_policy ./nginx.yaml
  18. Confidential │ © VMware, Inc. 20 KonstraintによるGatekeeper⽤Manifestの⽣成 $ konstraint create

    . -o ./konstraint/ $ ls ./konstraint constraint_Policy.yaml template_Policy.yaml konstraintコマンド実⾏でconftest⽤RegoからManifestが⾃動⽣成される - consraint_Policy.yaml︓ Constraint(Policyをクラスタに適⽤するManifest) - template_Policy.yaml︓ ConstraintTemplate(Policyを定義するManifest) - libs: - |- package lib.core default is_gatekeeper = false is_gatekeeper { has_field(input, "review") has_field(input.review, "object") } ConstraintTemplateの中⾝はKonstraintのライブラリとconftest⽤Regoで構成 rego: |- package ns_policy import data.lib.core deniedNamespaces := [ "kube-system", "gitlab" ] violation[{"msg": msg}] { deniedNamespaces[_] == core.resource.metadata.namespace msg := sprintf("invalid namespace: %v", [core.resource.metadata.namespace]) } Konstraintライブラリ部分 conftest⽤Rego部分
  19. Confidential │ © VMware, Inc. 21 まとめ • 細かい認可の設定にはOPAが有効 •

    OPA Gatekeeperを使った環境でCI/CDパイプラインを実装する場合、 Manifestのpush/PR前にPolicyに合致するか検証すべき • OPA Gatekeeperで使うPolicy(Manifest)はCI/CDパイプライン上で検証⽤途に直接使えない → 検証⽤Rego(conftest⽤Rego)が別途必要に • Konstraintを使うとconftest⽤RegoからOPA Gatekeeperで使うPolicy(Manifest)を ⽣成することが可能に • おまけ︓Regoに疲れたらTanzu Mission Control使いましょう
  20. Confidential │ © VMware, Inc. 22 おまけ︓もう1つPolicyの共通化ツール Gator Gator︓ •

    Regoの代わりにContraintとContraintTemplateを使ってPolicyを評価するツール • OPA Gatekeeperで開発されている(https://github.com/open-policy-agent/gatekeeper/blob/master/website/docs/gator.md) $ conftest test -p . -n ns_policy ./nginx.yaml FAIL - ./nginx.yaml - ns_policy - invalid namespace: kube-system 1 test, 0 passed, 0 warnings, 1 failure, 0 exceptions $ cat nginx.yaml | gator test -f konstraint/ Message: "invalid namespace: kube-system" conftest+konstraint pluginの結果 Gatorでの結果 • 先にConstraintTemplateを作る場合(Tanzu Mission Controlを利⽤する場合など)で有効 • 枯れてない(alpha版)上にドキュメントやサンプルがかなり少ない点に注意 ※Qiitaに紹介記事書いてます https://qiita.com/ipppppei/items/935d19da952ba5369a33