audit-bridgeを試す

ekscloudwatchと比較のためfalco-eks-audit-bridgeを試したメモ。

コンポーネント バージョン
EKS 1.19
プラットフォームバージョン eks.5
Falco 0.29.1
Falcoチャート 1.15.3
audit-bridge v1.0.3

参考リンク

クラスターの準備

1.19でクラスターを作成する。

cat << EOF > cluster.yaml
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig

metadata:
  name: audit-bridge
  region: ap-northeast-1
  version: "1.19"
vpc:
  cidr: "10.0.0.0/16"

availabilityZones:
  - ap-northeast-1a
  - ap-northeast-1c

managedNodeGroups:
  - name: managed-ng-1
    minSize: 2
    maxSize: 2
    desiredCapacity: 2
    privateNetworking: true

cloudWatch:
  clusterLogging:
    enableTypes: ["*"]

iam:
  withOIDC: true
EOF
eksctl create cluster -f cluster.yaml

Falcoのデプロイ

初期化コンテナを使う方法でFalcoをインストールする。auditLog.enabled=trueとすることでServiceが作られる。

cat << EOF > values.yaml
image:
  repository: falcosecurity/falco-no-driver

auditLog:
  enabled: true

extraInitContainers:
  - name: driver-loader
    image: docker.io/falcosecurity/falco-driver-loader:0.29.1
    imagePullPolicy: Always
    securityContext:
      privileged: true
    volumeMounts:
      - mountPath: /host/proc
        name: proc-fs
        readOnly: true
      - mountPath: /host/boot
        name: boot-fs
        readOnly: true
      - mountPath: /host/lib/modules
        name: lib-modules
      - mountPath: /host/usr
        name: usr-fs
        readOnly: true
      - mountPath: /host/etc
        name: etc-fs
        readOnly: true

falcosidekick:
  enabled: true
  webui:
    enabled: true
EOF
$ helm upgrade --install falco falcosecurity/falco -n falco --create-namespace -f values.yaml
Release "falco" does not exist. Installing it now.
NAME: falco
LAST DEPLOYED: Wed Jul 14 04:32:51 2021
NAMESPACE: falco
STATUS: deployed
REVISION: 1
NOTES:
Falco agents are spinning up on each node in your cluster. After a few
seconds, they are going to start monitoring your containers looking for
security issues.


No further action should be required.

PodとServiceを確認する。

$ k -n falco get po
NAME                                      READY   STATUS    RESTARTS   AGE
falco-falcosidekick-5cbc97b7d9-l7flk      1/1     Running   0          3m3s
falco-falcosidekick-5cbc97b7d9-nshb2      1/1     Running   0          3m3s
falco-falcosidekick-ui-79c4d8b546-zz62f   1/1     Running   0          3m3s
falco-m4n5s                               1/1     Running   0          3m3s
falco-vd55b                               1/1     Running   0          3m3s
$ k -n falco get svc
NAME                     TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
falco                    ClusterIP   172.20.101.21    <none>        8765/TCP   3m13s
falco-falcosidekick      ClusterIP   172.20.103.152   <none>        2801/TCP   3m13s
falco-falcosidekick-ui   ClusterIP   172.20.30.23     <none>        2802/TCP   3m13s

ポートフォワードでfalcosidekick-uiにアクセスする。

k -n falco port-forward svc/falco-falcosidekick-ui 2802

ログのS3への転送

コントロールプレーンのログをS3に転送するように設定する。

バケットを作成する。

ACCOUNT_ID=$(aws sts get-caller-identity --output text --query Account)
BUCKET_NAME="eks-audit-bridge-bucket-${ACCOUNT_ID}"
AWS_REGION=$(aws configure get region)
aws s3api create-bucket \
    --bucket ${BUCKET_NAME} \
    --region ${AWS_REGION} \
    --create-bucket-configuration LocationConstraint=${AWS_REGION}

SSE-S3でのバケットのデフォルト暗号化を有効にする。要件に応じて設定する。

aws s3api put-bucket-encryption \
    --bucket ${BUCKET_NAME} \
    --server-side-encryption-configuration '{"Rules":[{"ApplyServerSideEncryptionByDefault":{"SSEAlgorithm":"AES256"}}]}'

Kinesisのコンソールでデリバリーストリームを作成する。

項目
Delivery stream name eks-audit-bridge-stream
Source Direct PUT or other sources
Enable server-side encryption for source records in delivery stream チェックしない
Data transformation Disabled
Record format conversion Disabled
Destination Amazon S3
S3 bucket 上で作成したバケットを選択
S3 prefix 指定しない
S3 error prefix 指定しない
Buffer size 5 MiB
Buffer interval 300 seconds
S3 compression GZIP
S3 encryption Disabled
Error logging Enabled
IAM role Create or update IAM role KinesisFirehoseServiceRole-...

サブスクリプションフィルターで使用するIAMロールを作成する。マネコンだと信頼されたエンティティにCloudWatch Logsが指定できないので、CLIで作成する。

ポリシーを作成する。

STREAM_NAME="eks-audit-bridge-stream"
cat <<EOF >eks-audit-bridge-firehose-policy.json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "firehose:PutRecord",
                "firehose:PutRecordBatch"
            ],
            "Resource": [
                "arn:aws:firehose:${AWS_REGION}:${ACCOUNT_ID}:deliverystream/${STREAM_NAME}"
            ]
        }
    ]
}
EOF
aws iam create-policy \
    --policy-name eks-audit-bridge-firehose-policy \
    --policy-document file://eks-audit-bridge-firehose-policy.json

ロールを作成する。

cat <<EOF > eks-audit-bridge-firehose-role-trust.json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "logs.ap-northeast-1.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}
EOF
aws iam create-role \
    --role-name eks-audit-bridge-firehose-role \
    --assume-role-policy-document file://eks-audit-bridge-firehose-role-trust.json

ロールにポリシーをアタッチする。

aws iam attach-role-policy \
    --role-name eks-audit-bridge-firehose-role \
    --policy-arn arn:aws:iam::${ACCOUNT_ID}:policy/eks-audit-bridge-firehose-policy

マネコンからだとLambdaとElasticsearchのサブスクリプションフィルターしか作成できないので、CLIで作成する必要がある。

aws logs put-subscription-filter \
    --log-group-name "/aws/eks/audit-bridge/cluster" \
    --filter-name "eks-audit-bridge-firehose" \
    --filter-pattern "" \
    --destination-arn "arn:aws:firehose:${AWS_REGION}:${ACCOUNT_ID}:deliverystream/${STREAM_NAME}" \
    --role-arn "arn:aws:iam::${ACCOUNT_ID}:role/eks-audit-bridge-firehose-role"

しばらく待ってログが送られることを確認する。

イメージのビルド

イメージのビルド日が古いので、ビルドし直す。

リポジトリをクローンする。

git clone https://github.com/xebia/falco-eks-audit-bridge.git
cd falco-eks-audit-bridge

ビルドエラーになったので、Dockerfileにgo env -w GOPROXY=directを追加した。

RUN GOPROXY=direct go mod download && \
    CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -ldflags '-extldflags "-static"' -o falco-eks-audit-bridge -v
docker build -t sotoiwa540/falco-eks-audit-bridge:0.0.1 .
docker push sotoiwa540/falco-eks-audit-bridge:0.0.1

イメージを確認する。大きくなってるが、ベースイメージが大きくなったのか。

$ docker images | grep falco-eks-audit-bridge
sotoiwa540/falco-eks-audit-bridge                          0.0.1               fca66666b7a0   2 minutes ago   35.1MB
xebia/falco-eks-audit-bridge                               v1.0.3              378b55c00b1b   18 months ago   17.7MB

audit-bridgeのデプロイ

ServiceAccountを作成する。

k -n falco create sa audit-bridge

IRSAで必要な権限を与える。本来はバケットを限定するべき。

eksctl create iamserviceaccount \
    --name audit-bridge \
    --namespace falco \
    --cluster audit-bridge \
    --attach-policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess \
    --override-existing-serviceaccounts \
    --approve

READMEによると、環境変数を2つ渡すだけ。

cat << EOF > audit-bridge-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: audit-bridge
  name: audit-bridge
  namespace: falco
spec:
  replicas: 1
  selector:
    matchLabels:
      app: audit-bridge
  template:
    metadata:
      labels:
        app: audit-bridge
    spec:
      serviceAccountName: audit-bridge
      containers:
      - image: sotoiwa540/falco-eks-audit-bridge:0.0.1
        name: falco-eks-audit-bridge
        env:
        - name: BUCKET
          value: ${BUCKET_NAME}
        - name: FALCO_ENDPOINT
          value: http://falco:8765/k8s-audit
EOF

デプロイする。

k apply -f audit-bridge-deployment.yaml

Podが動いていることを確認する。

$ k -n falco get po
NAME                                      READY   STATUS    RESTARTS   AGE
audit-bridge-8467568967-f5h5w             1/1     Running   0          15s
falco-falcosidekick-5cbc97b7d9-l7flk      1/1     Running   0          58m
falco-falcosidekick-5cbc97b7d9-nshb2      1/1     Running   0          58m
falco-falcosidekick-ui-79c4d8b546-zz62f   1/1     Running   0          58m
falco-m4n5s                               1/1     Running   0          58m
falco-vd55b                               1/1     Running   0          58m

しかしこれだと権限が不足している。

$ k -n falco logs audit-bridge-8467568967-f5h5w
Started monitoring services
Processing: 2021/07/13/20/eks-audit-bridge-stream-1-2021-07-13-20-18-01-bca35eb8-eabc-456e-9250-382653c8de2a.gz
Could not copy file to processed folder:
AccessDenied: Access Denied
        status code: 403, request id: W8F84855ZX6DCQBM, host id: 14NfekBhqqWdfG7HNf5ermqDiVlFlVeEd2efRVoJH0aOxdxu0iUTn5FI/MHPsKuMfFp8efAMaOI=
Processing: 2021/07/13/20/eks-audit-bridge-stream-1-2021-07-13-20-23-05-25e24f0c-864e-4fde-95d1-26552b0c0566.gz

試しにAmazonS3FullAccessを与えると動作した。権限の精査が必要。

$ k -n falco logs audit-bridge-8467568967-mrctc
Started monitoring services
Processing: 2021/07/13/20/eks-audit-bridge-stream-1-2021-07-13-20-23-05-25e24f0c-864e-4fde-95d1-26552b0c0566.gz
Processing: 2021/07/13/20/eks-audit-bridge-stream-1-2021-07-13-20-43-11-585ffcfd-ae65-4776-9ac5-dc7d7a78d9e3.gz
No new Firehose events found, waiting for next check interval.

処理済みのログをprocessed/フォルダに移動するという処理をやっているようだ。そういえば、ekscloudwatchはどの範囲のログを送っているのかよくわからなかった。

f:id:sotoiwa:20210714060200p:plain

以下を参考にテストする。

テストのため、AWSアクセスキーを含むConfigMapを作成する。

cat << "EOF" > my-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: my-config
  namespace: default
data:
  ui.properties: |
    color.good=purple
    color.bad=yellow
    allow.textmode=true
  access.properties: |
    aws_access_key_id = MY-ID
    aws_secret_access_key = MY-KEY
EOF
k apply -f my-config.yaml

しばらくログを見ておく。

以下のログが出た。falcosidekickを有効にしたのでjson形式になっている。

{"output":"20:52:49.501943040: Notice K8s ConfigMap Created (user=kubernetes-admin configmap=my-config ns=default resp=201 decision=allow reason=)","priority":"Notice","rule":"K8s ConfigMap Created","time":"2021-07-13T20:52:49.501943040Z", "output_fields": {"jevt.time":"20:52:49.501943040","ka.auth.decision":"allow","ka.auth.reason":"","ka.response.code":"201","ka.target.name":"my-config","ka.target.namespace":"default","ka.user.name":"kubernetes-admin"}}

f:id:sotoiwa:20210714060246p:plain