はじめに
kube-benchはAquaSecurity社が開発しているOSSです。
名前から推測できる通り、Kubernetes用のツールで役割は後述しますが、Kubernetsクラスタのセキュリティ強化に利用できるツールです。
今年初めて利用したので、導入ステップと検証結果をまとめてみました。
kube-benchについて
Kubernetesクラスタの設定が、CISが提唱するKubernetes Benchmarkに準拠しているかを検査するツールです。
目的はクラスタの健全性の検査、人でいうところの健康診断に近いのかなと思っています。
なお、CIS Kubernetes Benchmarkへの準拠状況に関しては、公式にも記載ありますが可能な限りとあるので、完全な準拠は保証していないことに注意が必要です。
利用できるKubernetesのクラスタは、セルフホスティングしているものに限らず、PaaSが提供するマネージドのクラスタも含まれます。
それでは、前置きが長くなりましたが、以下から実際の導入ステップの紹介に入ります。
実行環境
対象環境: AWS EKS(Fargate)
Kubernetes Version: 1.22
前提
- 稼働しているEKSクラスタが存在する
- JOBを稼働させるIAM Roleが作成済みである
kube-benchの導入
kube-benchは先程少し触れましたが、各種PaaSのマネージドクラスタもサポートしており、job.yamlも用意されています。
今回は、Benchmarkの結果をSecurityHubに連携サポートをしてくれるjob-eks-asff.yamlを利用します。
kube-benchはjobで単発で稼働させることも可能ですが、今回は定期的に実行するCronJobを作成します。
環境が違ったり、詳しい導入ステップを把握したい方は公式のドキュメント見てください。
Imageの準備
kube-benchのImageをECRに作成します
AWSアカウントやリージョンは各自の環境に置き換えてください
aws ecr create-repository --repository-name k8s/kube-bench
git clone https://github.com/aquasecurity/kube-bench.git
cd kube-bench
git checkout refs/tags/v0.6.6
docker build -t k8s/kube-bench:v0.6.6 .
docker tag k8s/kube-bench:v0.6.6 <AWS_ACCT_NUMBER>.dkr.ecr.<AWS_REGION>.amazonaws.com/k8s/kube-bench:v0.6.6
aws ecr get-login-password --region <AWS_REGION> | docker login --username AWS --password-stdin <AWS_ACCT_NUMBER>.dkr.ecr.<AWS_REGION>.amazonaws.com
docker push <AWS_ACCT_NUMBER>.dkr.ecr.<AWS_REGION>.amazonaws.com/k8s/kube-bench:v0.6.6
SecurityHubとの連携
AWSのSecurityHubの統合画面でkube-benchの結果受け入れを有効にします
manifestの作成
-
CronJob作成
ConfigMapでは対象のAWSアカウント、AWSのリージョン、EKSクラスタを指定します
jobTemplateは公式のものを利用していますが、終了したJOBを削除する為にttlSecondsAfterFinishedを追加します--- apiVersion: v1 kind: ConfigMap metadata: name: kube-bench-eks-config data: config.yaml: | AWS_ACCOUNT: "<AWS_ACCT_NUMBER>" AWS_REGION: "<AWS_REGION>" CLUSTER_ARN: "<AWS_CLUSTER_ARN>" --- apiVersion: batch/v1 kind: CronJob metadata: name: kube-bench namespace: kube-bench spec: schedule: "0 2 * * *" #UTCで設定 jobTemplate: spec: ttlSecondsAfterFinished: 100 template: spec: containers: - name: kube-bench # Push the image to your ECR and then refer to it here # image: <ID.dkr.ecr.region.amazonaws.com/aquasec/kube-bench:ref> command: ["kube-bench", "run", "--targets", "node", "--benchmark", "eks-1.0.1", "--asff"] volumeMounts: - name: kube-bench-eks-config mountPath: "/opt/kube-bench/cfg/eks-1.0.1/config.yaml" subPath: config.yaml readOnly: true restartPolicy: Never serviceAccountName: kube-bench volumes: - name: kube-bench-eks-config configMap: name: kube-bench-eks-config items: - key: config.yaml path: config.yaml
-
ServiceAccountの作成
JOBを動かすIAM Roleを指定します--- apiVersion: v1 kind: ServiceAccount metadata: name: kube-bench labels: app.kubernetes.io/name: kube-bench annotations: eks.amazonaws.com/role-arn: arn:aws:iam::<AWS_ACCOUNT_ID>:role/<IAM_ROLE_NAME>
IAM RoleにSecurityHub用の権限を追加
今回は検出結果をAWSのSecurityHubに連携するため、JOBを稼働させるIAM Roleに以下のポリシーを追加します
Policies:
- PolicyName:'kube-bench'
PolicyDocument:
Id: default_policy_ID
Version: "2012-10-17"
Statement:
- Sid: 'kubebench'
Effect: 'Allow'
Resource: 'arn:aws:securityhub:ap-northeast-1::product/aqua-security/kube-bench'
Action: 'securityhub:BatchImportFindings'
kube-benchの実行結果
実行したCronJobの結果はログに出力されますが、今回はSecurityHubと連携させたので、SecurityHub側で検出結果を確認できます。
重要度、Benchmarkのどの項目に抵触したか、対象リソース、などを確認することができます。
SecurityHubに検出結果を送る際にはASFF(AWS Security Finding Format)にフォーマットで送る必要があります。
kube-bench内部で、検出した結果をASFFにコンバートしてくれています。
https://github.com/aquasecurity/kube-bench/blob/a1e2870e83e9c2dfe0d24210712e69f8adeb6743/check/controls.go#L253-L287
まとめ
今回は、kube-benchというOSSで提供されているツールを利用して、Kubernetsクラスタの健康診断を行いました。
マニフェストなどは公式から提供されており、定期実行も手軽にでき、SecurityHubと連携してくれるのでAWSを利用している方におすすめだと感じました。
検出項目に対する注意点としては、Fargateの場合はAWSの責任共有モデルにある通り、検知されたものの対応が推奨されない項目もあるので、検知項目について調整が必要ということです。
上記のような注意点はありますが、手軽にクラスタの健全性をツールで確認し、結果をSecurityHubに連携できるので、是非試してみてください。