ブログ
HOME Developer Square ブログ 【SCSK技術者によるブログ】Sysdigと組み合わせて効果的なソリューションのご紹介 ~ポリシーエンジン編~
【SCSK技術者によるブログ】Sysdigと組み合わせて効果的なソリューションのご紹介 ~ポリシーエンジン編~
SCSK技術者によるブログ!
第4回担当の川杉です。早速ですが、セキュリティは要件に応じて複数のソリューションを組み合わせてシステム全体を抜け漏れなく保護することが大切です。Sysdigだけでは満たせない顧客要件をどうやってカバーするか、今回はそんなテーマにフォーカスした記事となります。それでは早速参りましょう。
「Sysdigでできない部分はどうしたらいいですか?」
SysdigをPoC中のお客様からこういった質問をいただくことはよくあります。お客様のやりたいこと(顧客要件)とソリューションにギャップが生じることはどんなソリューションでも起こることです。こういった場合は以下のどちらかで解決することが多いです。
- Sysdigの機能設計コンセプトをご理解いただき、コンセプトに基づいた使い方で要件が満たせるか一緒に検討する
- Sysdigだけでは実現できない要件は他のセキュリティソリューションでカバー可能か検討する
例えば以下のような課題は②に該当します。
例:特定のラベルが付与されていないPodのデプロイを禁止したい。
〇〇を禁止する、といったルールを強制するような機能はSysdigでは提供されていないため他の対策が必要になります(こういった要件の中にはFalcoルールを自作することで対応可能なものもありますが、本来の用途とは異なるため管理が大変です)。Kubernetes(以下k8s)環境でこういった要件が生じた場合はポリシーエンジンと呼ばれるOSSの実装がおススメです。
ポリシーエンジンとは?
ポリシーエンジンはAdmission Controller の一種で、k8s API のリクエストを制御する仕組みです。K8s API へのリクエスト処理にwebhookで介入して、KubernetesリソースのValidate(検証)やMutate(設定の追加、削除など)の処理を追加できます。特にValidateの機能はKubernetesのマニュフェストがユーザーの定義したルールに準拠したか検証することができるため、k8s環境内でセキュリティルールを強制したい場合に有効です。特定の設定がないPodデプロイの禁止、ホワイトリストリポジトリ以外からプルしたコンテナイメージ由来のPodデプロイ禁止など様々なセキュリティルールをk8s環境に強制できます。代表的なポリシーエンジンOSSには以下のものがあります。
- Open Policy Agent/Gatekeeper(以下OPA/Gatekeeper)
https://kubernetes.io/blog/2019/08/06/opa-gatekeeper-policy-and-governance-for-kubernetes/ - Kyverno
https://kyverno.io/docs/introduction/
それぞれ特徴的な機能を提供していますが、それについては今後機会があれば別の回で語ろうと思います。今回はCNCFのGraduated OSSであるOPA/Gatekeeperを実装してどのようなことができるのか実際に見ていきましょう。
事前準備
それでは早速検証の準備から始めていきましょう。
今回の検証で事前に用意するものは以下の通りです。
K8s Cluster
- K8s環境であればなんでもいいです
- 今回私はOpenshift環境を利用します。そのため環境に応じてKubectllコマンドに置き換えてご検証ください
gatekeepr.yamlの取得
- OPAの公式github(下記URL)からgatekeeperデプロイに利用するyamlを取得します
https://github.com/open-policy-agent/gatekeeper/blob/master/deploy/gatekeeper.yaml - Openshift以外の環境は下記URLに記載のあるhelmインストールの方が簡単です
https://github.com/open-policy-agent/gatekeeper/blob/master/charts/gatekeeper/README.md
まずは実装
OPA/GatekeeperをOpenshift環境へデプロイします。
今回はOpenshift環境で私が検証した方法でのデプロイとなります。
手順1. 事前準備で取得したgatekeeper.yamlをデプロイします。
$oc apply -f gatekeeper.yaml
手順2.下記コマンドを実行し、gatekeeperのdeploymentからsecurityContextの設定を削除します。
※私が検証した際は下記コマンドを実施しない場合gatekeeperコンテナは起動しませんでした(後で調べたところ事前に設定していたOpenshiftのSCC (Security Context Constraints)によってgatekeeper内に定義されていたsecurityContextの設定が禁止されていたことが原因でした)
$oc patch Deployment/gatekeeper-audit --type json --patch '[{ "op": "remove", "path": "/spec/template/spec/containers/0/securityContext" }]' -n gatekeeper-system deployment.apps/gatekeeper-audit patched
$oc patch Deployment/gatekeeper-controller-manager --type json --patch '[{ "op": "remove", "path": "/spec/template/spec/containers/0/securityContext" }]' -n gatekeeper-system deployment.apps/gatekeeper-controller-manager patched
手順3.gatekeeperコンテナの起動を確認します。
$oc get pods -n gatekeeper-system NAME READY STATUS RESTARTS AGE gatekeeper-audit-7c84869dbf-r5p87 1/1 Running 0 2m34s gatekeeper-controller-manager-ff58b6688-9tbxx 1/1 Running 0 3m23s gatekeeper-controller-manager-ff58b6688-njfnd 1/1 Running 0 2m54s gatekeeper-controller-manager-ff58b6688-vlrsl 1/1 Running 0 3m11s
これで実装は完了です。
※Tipsとなりますが、"openshift-"などのコアネームスペースにgate-keeperのポリシーを適用したくない場合はadmission.gatekeeper.sh/ignore=trueのラベルをネームスペースに追記することで、ネームスペースごとに有効/無効を設定可能です
いざ検証
早速動かしてみましょう。
と、その前に作成が必要なオブジェクトを紹介します。下記の通りです。
ConstraintTemplate
- k8sリソースを評価するポリシーを定義します。このオブジェクトはRego言語で記述する必要があります。
Constraint
- ConstraintTemplateを適用するリソースやnamespaceを定義します。
ConstraintTemplateの作成でRego言語が必要です、と言いましたがいきなり知らない言語が登場したことに戸惑った方もいらっしゃると思いますので、今回はChat GPTに頼んでConstraintTemplateを作成してもらおうと思います。筆者もRego言語はそこまで詳しくないので日ごろから生成AIに頼りまくっています。便利な世の中になりましたね。閑話休題。 それでは実際に試してみましょう。
まずはChat GPTにマニュフェストの作成を頼みます。
今回のデモではAppArmorというコンテナリースのアクセス制限などに使える機能が設定されていないpodのデプロイを禁止するルールをk8s環境に強制します。
AppArmorについて気になる方は下記URLをご覧ください。
https://kubernetes.io/ja/docs/tutorials/clusters/apparmor/
結果、下記のようなyamlを作ってもらいました。
constraint-template.yaml
apiVersion: templates.gatekeeper.sh/v1beta1 kind: ConstraintTemplate metadata: name: k8srequiredannotations spec: crd: spec: names: kind: K8sRequiredAnnotations targets: - target: admission.k8s.gatekeeper.sh rego: | package k8srequiredannotations violation[{"msg": msg}] { input.review.kind.kind == "Pod" not input.review.object.metadata.annotations["container.apparmor.security"] msg := "Pods must have an annotation starting with 'container.apparmor.security'" }
なんと先ほどの質問の回答でChatGPTがConstraint.yamlも一緒に作ってくれたのでせっかくなのでこちらも使ってみましょう。
constraint.yaml
apiVersion: constraints.gatekeeper.sh/v1beta1 kind: K8sRequiredAnnotations metadata: name: require-apparmor-annotation spec: match: kinds: - apiGroups: [""] kinds: ["Pod"]
では早速デプロイみましょう。
まずはyamlのデプロイから、
$oc apply -f constrainttemplate.templates.gatekeeper.sh/k8sdenypodswithlabel created constrainttemplate.templates.gatekeeper.sh/k8srequiredannotations created
$oc apply -f constraint.yaml k8srequiredannotations.constraints.gatekeeper.sh/require-apparmor-annotation created
Chat GPTに作ってもらったyamlで問題なくデプロイできました。
オブジェクトも作成できたところで実施に試してみましょう。
適当なpodをデプロイしてみます。
$oc run nginx --image=nginx Error from server (Forbidden): admission webhook "validation.gatekeeper.sh" denied the request: [require-apparmor-annotation] Pods must have an annotation starting with 'container.apparmor.security'
設定した通り、AppArmorのannotationがないためデプロイできません。
最後に
いかがでしたでしょうか。今回はOPA/Gatekeeperの紹介でした。K8s環境内のリソースやオブジェクトにユーザーが定義したルールを強制させることができるのでコンプライアンスの向上が期待できます。ポリシーエンジンとSysdigを組み合わせることでよりセキュアなk8s環境が実現できますのでご興味あればお試しください。またモニタリング・セキュリティについてのご相談は本サイトのお問い合わせフォームからよろしくお願いいたします。
・・・余談ですが、OSSとChat GPTは相性抜群ですね!
それでは、またの機会に!
担当者紹介
- 担当者名
- 川杉
- コメント
- 3年ほど前からSysdigを中心にコンテナ・Kubernetes領域で仕事をしています。社内でコンテナ技術の啓蒙活動も積極的に行っています。
- 保有資格
- Certified Kubernetes Administrator
Certified Kubernetes Security Specialist