🐳

kube-benchの実行結果をSecurity Hubに送ってみた

2023/09/24に公開

はじめに

最近Kubernetesまわりをいじっているので、セキュリティベンチマークツールのkube-benchを実行してみました。
この記事では、kube-benchの実行結果をSecurity Hubに送る方法を紹介します。

kube-benchとは

kube-benchは、Kubernetesクラスターのセキュリティ診断を行うためのオープンソースツールです。
クラスター内のセキュリティリスクや設定問題を特定し、修正案を提供することを目的としています。
CIS Benchmarkに記載されているチェックを実行することで、Kubernetesが安全にデプロイされているかどうかを確認します。

AWS Security Hubとは

AWS Security Hubは、AWS環境のセキュリティ状況を可視化するためのサービスです。
AWS環境のセキュリティ状況を、AWSのサービスやサードパーティ製品からの統合された結果として表示します。

kube-benchの実装

前提条件

  • EKSクラスターが作成済みであること
  • awscliがインストール済み, aws configureが完了していること
  • eksctlがインストール済みであること
  • kubectlがインストール済みであること

AWS Security Hubの設定

まずは、AWS Security Hubの設定を行います。
AWSコンソールからSecurity Hubを開き、統合ページにてkube-benchを検索して、結果を受け入れるをクリックします。

Security Hub - 1
Security Hub - 2

Service Accountの作成

次に、結果を送信するためのkube-bench用のService Accountを作成します。
プロフィール名やクラスター名、ロール名などは適宜変更してください。

REGION="ap-northeast-1"
PROFILE="default"

CLUSTER_NAME="example-eks"
NAMESPACE="default"

ROLE_NAME="kube-bench-service-account-role"

POLICY_NAME="KubeBenchSecurityHubImportFindingPolicy"
POLICY_DESC="Policy for importing findings to SecurityHub"
POLICY_DOCUMENT='{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "securityhub:BatchImportFindings",
            "Resource": "arn:aws:securityhub:'${REGION}'::product/aqua-security/kube-bench"
        }
    ]
}'

POLICY_ARN=$(aws iam create-policy --policy-name $POLICY_NAME --description "$POLICY_DESC" --policy-document "$POLICY_DOCUMENT" --query "Policy.Arn" --output text --profile $PROFILE --region $REGION)

eksctl create iamserviceaccount \
    --name $ROLE_NAME \
    --namespace $NAMESPACE \
    --cluster $CLUSTER_NAME \
    --role-name $ROLE_NAME \
    --attach-policy-arn "$POLICY_ARN" \
    --attach-policy-arn arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy \
    --attach-policy-arn arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly \
    --attach-policy-arn arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy \
    --approve \
    --override-existing-serviceaccounts

manifestの作成

次に、kube-bench用のmanifestを作成します。
下記変数の値は適宜変更してください。

  • AWS_ACCOUNT_ID
  • AWS_REGION
  • CLUSTER_ARN
  • ROLE_NAME
# kube-bench.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: kube-bench-eks-config
data:
  config.yaml: |
    AWS_ACCOUNT: <AWS_ACCOUNT_ID>
    AWS_REGION: <AWS_REGION>
    CLUSTER_ARN: <CLUSTER_ARN>
---
apiVersion: batch/v1
kind: CronJob
metadata:
  name: kube-bench-cron-job
  labels:
    app: kube-bench-cron-job
spec:
  schedule: "* * * * *" # 1分ごとに実行, 適宜変更してください
  jobTemplate:
    spec:
      template:
        spec:
          metadata:
          labels:
            app: kube-bench-cron-job
          hostPID: true
          serviceAccountName: <ROLE_NAME> # Service Accountの名前
          containers:
            - name: kube-bench
              # ECRにpushしたkube-benchのイメージを指定も可能
              image: docker.io/aquasec/kube-bench:latest
              command: [ "kube-bench", "run", "--targets", "node", "--benchmark", "eks-1.2.0" ]
              env:
                - name: NODE_NAME
                  valueFrom:
                    fieldRef:
                      fieldPath: spec.nodeName
              volumeMounts:
                - name: var-lib-kubelet
                  mountPath: /var/lib/kubelet
                  readOnly: true
                - name: etc-systemd
                  mountPath: /etc/systemd
                  readOnly: true
                - name: etc-kubernetes
                  mountPath: /etc/kubernetes
                  readOnly: true
                - name: kube-bench-eks-config
                  mountPath: "/opt/kube-bench/cfg/eks-1.2.0/config.yaml"
                  subPath: config.yaml
                  readOnly: true
          restartPolicy: Never
          volumes:
            - name: var-lib-kubelet
              hostPath:
                path: "/var/lib/kubelet"
            - name: etc-systemd
              hostPath:
                path: "/etc/systemd"
            - name: etc-kubernetes
              hostPath:
                path: "/etc/kubernetes"
            - name: kube-bench-eks-config
              configMap:
                name: kube-bench-eks-config
                items:
                  - key: config.yaml
                    path: config.yaml

manifestの適用

最後に、manifestを適用します。

kubectl apply -f kube-bench.yaml

結果確認

まずはpodの状態を確認します。

❯ kubectl logs -l app=kube-bench-cron-job -n default
0 checks FAIL
3 checks WARN
0 checks INFO

== Summary total ==
13 checks PASS
0 checks FAIL
3 checks WARN
0 checks INFO

次に、Security Hubの結果を確認します。

Security Hub - 3

おわりに

この記事ではkube-benchの実行結果をSecurity Hubに送ることができました。
今回は、EKSクラスターを対象に実行しましたが、他のKubernetesクラスターでも同様に実行できると思います。
具体的な実装は、GitHubを参考にしてください。(例: job-aks.yaml)

Discussion