SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

翔泳社の本(AD)

Kubernetesクラスタを不正に操作されないように、今すぐやるべきセキュリティ対策

  • X ポスト
  • このエントリーをはてなブックマークに追加

 Kubernetesでは、ServiceAccountを使用すればPodに対して様々な権限を付与できます。ですが、付与する権限を誤ったり、過剰に権限を付与したりすると、思わぬリスクに晒されます。重大なリスクの1つに、Podを含むコンテナに侵入した攻撃者によるKubernetesクラスタの不正操作があります。どのような対策をすればこうした事態を防げるのでしょうか。『リスクから学ぶ Kubernetesコンテナセキュリティ』(翔泳社)から、2つの対策を紹介します。

  • X ポスト
  • このエントリーをはてなブックマークに追加

 本記事は『リスクから学ぶ Kubernetesコンテナセキュリティ コンテナ開発者がおさえておくべき基礎知識』(著:望月敬太)の「CASE8:PodからKubernetesクラスタを不正に操作されてしまった」から抜粋したものです。掲載にあたって編集しています。

対策の基本原則

 ServiceAccountにはRBACの仕組みを使用することで、Kubernetesクラスタに関する様々な権限を付与できます。また、パブリッククラウドでは、クラウドサービスの権限をServiceAccountに紐付ける機能も提供されています(例えばAmazon EKSにはIAM roles for service accountsという機能があります)。

 これらの仕組みを利用する際に意識すべきことは、Podに紐付けるServiceAccountにはPodが正常に動作するために必要な権限のみを付与し、過剰な権限を付与しないという最小権限の原則に準拠することです(図1)。

図1 Podに対する最小権限の付与
図1 Podに対する最小権限の付与

 一般的なアプリケーションをPodとしてデプロイする場合、Kubernetesクラスタに対する権限を必要とすることはほとんどありません。そのため、そのようなPodには可能な限り権限を付与しないことが望ましいと言えます。

 また、例えばOperatorなどKubernetesクラスタに対して何かしらの操作を行うコンポーネントをPodとしてデプロイする場合や、Podとしてデプロイしたアプリケーションがクラウドサービスにアクセスする必要がある場合などは、特定の権限をPodに付与する必要があります。その場合も、付与する権限を必要最小限に留めることが重要です。

対策1 default ServiceAccountを使用する

 KubernetesではNamespaceごとに、defaultというServiceAccountが存在します。このServiceAccountは、Namespaceの作成にあわせて自動的に作成され、基本的に権限が何も付与されていません(厳密にはAPI discovery rolesというKubernetesのAPI情報を参照するURLへのアクセスを許可する権限が付与されますが、特にセキュリティ上問題になる性質のものではなく、Kubernetesクラスタの設定で無効化することもできます)。

 Podをデプロイする際、serviceAccountNameフィールドでServiceAccountを指定しない場合は、このdefaultServiceAccountが自動的にPodに紐付けられるようになっています。

 基本原則でも触れた通り、一般的にPodがKubernetesクラスタに対する権限を必要とする場面は限られており、特にアプリケーションをPodとしてデプロイする場合は、そのような権限が必要になることはほとんどありません。

 そのため、特に理由がない限りは、Podをデプロイする際にServiceAccountを指定せず、Podにdefault ServiceAccountを紐付けることで、不要な権限が付与されないようにすると良いでしょう。

 ただし、default ServiceAccountに対してRoleBindingやClusterRoleBindingを用いて権限の紐付けを行うと、ServiceAccountを指定せずにデプロイした全てのPodに対して権限が付与されてしまうため注意が必要です。

 default ServiceAccountをPodに紐付けても、PodからKubernetesクラスタに対する操作を行えないことを確認します。まずは、Namespaceにdefault ServiceAccountが存在することを確認します。

リスト1 default ServiceAccountの確認
$ kubectl get serviceaccount default
NAME      SECRETS   AGE
default   0         2d

 リスト2のマニフェストを作成します。このマニフェストでは、serviceAccountNameフィールドでServiceAccountを指定していません。そのため、Podにはdefault ServiceAccountが自動的に紐付けられます。

リスト2 default-sa-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: default-sa-pod
  labels:
    app: default-sa-pod
spec:
  containers:
  - name: ubuntu
    image: ubuntu:22.04
    command: ["/bin/sh", "-c", "while :; do sleep 10; done"]

 リスト2のマニフェストを適用してPodをデプロイすると、リスト3のようにdefault ServiceAccountが自動的に紐付けられた状態でPodがデプロイされることを確認できます。

リスト3 default ServiceAccountを紐付けたPodのデプロイ
$ kubectl apply -f default-sa-pod.yaml

$ kubectl get pod default-sa-pod -o yaml
apiVersion: v1
kind: Pod
metadata:
  ...
  name: default-sa-pod
  namespace: default
.  ..
spec:
  ...
  serviceAccountName: default
  ...

 default ServiceAccountには、権限が何も付与されていません。そのため、このPodに含まれるコンテナ内で先ほどのようにkubectlコマンドを実行すると、Kubernetesクラスタに対してアクセスを行い認証を行うことはできても認可エラー(Forbidden)となり、Kubernetesクラスタに対する操作を行うことはできません(kubectlコマンドのインストール手順はリスト4を参照してください)。

リスト4 PodからKubernetesクラスタを操作できないことの確認
$ kubectl exec -it default-sa-pod -- /bin/bash

< kubectl コマンドのインストール(略)>
root@default-sa-pod:/# kubectl get nodes
Error from server (Forbidden): nodes is forbidden: User "system:serviceaccount:
default:default" cannot list resource "nodes" in API group "" at the cluster scope

root@default-sa-pod:/# exit
exit

対策2 ServiceAccount 情報の自動マウントを無効化する

 Podに紐付けられたServiceAccountの情報は、Podに含まれるコンテナの/var/run/secrets/kubernetes.io/serviceaccountディレクトリにマウントされることを解説しました。Podをデプロイする際にautomountServiceAccountToken: falseというフィールドを指定することで、コンテナにServiceAccountの情報が自動的にマウントされるのを無効化できます※12。

 特にtokenというファイルには、Podに紐付けられたServiceAccountがKubernetesクラスタにアクセスする際の認証情報が含まれているため、必要がなければこのマウントを無効化しておくことを推奨します。なお、automountServiceAccountToken: falseという設定は、ServiceAccountでも行うことができますが、ここではPodのフィールドで設定する例を解説します。まずは、リスト5のマニフェストを作成します。

リスト5 no-sa-token-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: no-sa-token-pod
  labels:
    app: no-sa-token-pod
spec:
  containers:
  - image: ubuntu:22.04
    name: ubuntu
    command: ["/bin/sh", "-c", "while :; do sleep 10; done"]
  automountServiceAccountToken: false

 リスト5のマニフェストを適用してPodをデプロイすると、/var/run/secrets/kubernetes.io/serviceaccountディレクトリにServiceAccountの情報がマウントされていないことを確認できます。

リスト6 ServiceAccount情報がマウントされていないことの確認
$ kubectl apply -f no-sa-token-pod.yaml

$ kubectl get pod no-sa-token-pod -o yaml
apiVersion: v1
kind: Pod
metadata:
  annotations:
    ...
  name: no-sa-token-pod
  namespace: default
  ...
spec:
  automountServiceAccountToken: false
  ...
  serviceAccountName: default
  ...

$ kubectl exec -it no-sa-token-pod -- ls /var/run/secrets/kubernetes.io/serviceaccount
ls: cannot access '/var/run/secrets/kubernetes.io/serviceaccount': No such file or directory
command terminated with exit code 2

 設定上はこのPodにdefault ServiceAccountが紐付けられていることになりますが、実際はこのPodにはdefault ServiceAccountの情報はマウントされていません。そのため、リスト7のようにPodはKubernetesクラスタに対する認証を行い、アクセスすることができない状態です

リスト7 PodからKubernetesクラスタにアクセスできないことの確認
$ kubectl exec -it no-sa-token-pod -- /bin/bash

< kubectl コマンドのインストール(略)>

root@no-sa-token-pod:/# kubectl get nodes
E0207 15:03:35.039747 2804 memcache.go:265] couldn't get current server API
group list: Get "http://localhost:8080/api?timeout=32s": dial tcp [::1]:8080:
connect: connection refused
...

root@no-sa-token-pod:/# exit
exit

まとめ

 ここまで、Podに付与された過剰な権限が要因となり発生し得るリスクの対策について解説しました。

 Podに紐付けたServiceAccountに権限が付与されている場合、Podに侵入した攻撃者はServiceAccountに紐付けられた権限をそのまま利用できることになるため、特に必要がない場合は権限を付与するべきではありません。また、Podになんらかの権限が必要な場合は、付与する権限を必要最小限に留めることが重要です。

 最後に、今回作成したリソースを削除します。

リスト7 PodからKubernetesクラスタにアクセスできないことの確認
$ kubectl delete pod sample-pod \
    malicious-pod \
    default-sa-pod \
    no-sa-token-pod

$ kubectl delete clusterrolebinding sample-crb

$ kubectl delete serviceaccount sample-sa
リスクから学ぶ Kubernetesコンテナセキュリティ コンテナ開発者がおさえておくべき基礎知識

Amazon  SEshop  その他

 
リスクから学ぶ Kubernetesコンテナセキュリティ
コンテナ開発者がおさえておくべき基礎知識

著者:望月敬太
発売日:2024年9月19日(木)
定価:3,740円(本体3,400円+税10%)

本書について

本書では、コンテナセキュリティを理解するために、「コンテナへの侵入」や「コンテナイメージの流出」などの代表的なリスクとそれらの対策を、ハンズオンを交えた具体例を通して学ぶことができます。

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
翔泳社の本連載記事一覧

もっと読む

この記事の著者

渡部 拓也(ワタナベ タクヤ)

 翔泳社マーケティング課。MarkeZine、CodeZine、EnterpriseZine、Biz/Zine、ほかにて翔泳社の本の紹介記事や著者インタビュー、たまにそれ以外も執筆しています。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

望月 敬太(モチズキ ケイタ)

株式会社NTT データグループ。CloudFoundry やKubernetes をベースとしたコンテナ基盤の開発およびそれらを活用したアプリケーション開発に2年ほど従事したのち、2020年より株式会社NTT データグループにてKubernetes を中心としたコンテナ技術に関するR&D や...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

【AD】本記事の内容は記事掲載開始時点のものです 企画・制作 株式会社翔泳社

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/20205 2024/09/26 07:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング