はじめに
Kubernetesのセキュリティについて調べている際、CNCFのこちらの記事を発見しました。今回はこちらの記事の和訳 (+一部意訳) をして、Kubernetesのセキュリティを考える際に重要なことを学びたいと思います。
記事の文章自体は少ないですが、補足の必要な箇所があり、十分追いきれていない部分もあるため、分かり次第随時更新する予定です。
記事の内容
冒頭
先月Kubernetesの大きなセキュリティの欠陥が初めて報告され、Kubernetesを利用する人々は動揺しました。この脆弱性 (CVE-2018-1002105) は、攻撃者がKubernetes API serverを通じてクラスターにアクセスできるようにし、マルウェアのインストールなどの攻撃をシステムに行うことを可能にします。
また2018年の初め、TeslaのAWS環境が仮想通貨採掘マルウェアに感染する出来事がありましたが、その攻撃は、パスワードで保護されていない特定のKubernetesのコンソールから発生しました。
企業がコンテナやオーケストレーションツールを次々採用するにつれ、ITインフラの重要な箇所を守るためのステップを踏む必要が生じます。それをサポートするため、利用者からのインプットをもとに作られた以下の9つのBest Practiceを遵守するべきでしょう。
1. 最新バージョンにアップグレードする
Kubernetesは四半期毎にアップデートされ、その度に新しいセキュリティ機能が追加されるので、最新のバージョンを利用しましょう。バージョンが離れるほどアップグレードが難しくなる場合があるので、少なくとも四半期に一度はアップグレードする予定を入れましょう。マネージドサービスを利用すればアップグレードがとても簡単にできます。
2. RBACを利用可能にする
Kubernetes APIにアクセスできる人と与える権限をRBAC (Role-Based Access Control)で制御しましょう。RBACはKubernetes ver 1.6以降は利用可能です。1.6以前のバージョンからアップグレードしたけどコンフィグを変更していない場合、RBACを利用可能にすると共に、ABAC (Attribute-Based Access Control) を利用できないようにしましょう。
RBACを利用可能にしたら、それを効率的に使う必要があります。クラスターをまたがった範囲の権限付与は避け、namespace毎に権限を付与すべきです。また、デバッグの時であろうと、誰かにcluster-admin権限を与えるべきではありません。ケースバイケースで必要な時にのみアクセスできるようにする方がよりセキュアです。
cluster roleとroleに関してはkubectl get clusterrolebinding
kubectl get rolebinding --all-namespaces
で確認できます。取り急ぎ、cluster-admin権限を誰に付与しているか確認しましょう。
アプリケーションがKubernetes APIにアクセスする必要がある場合は、個別にService Accountを作り、最小限の権限を与えましょう。一つのnamespaceのために、デフォルトのアカウントに対して無駄な権限を与えるよりは、この方が良いです。
大半のアプリケーションはAPIに一切アクセスする必要はありませんので、automountServiceAccountToken
をfalseにセットしましょう。
※automountServiceAccountToken
はservice accountのコンフィグで設定できるパラメータです。公式ページはこちら
3. Namespaceを利用してセキュリティの境界線を設定する
個別のnamespaceを作ることはコンポーネント間を隔離する上で最も重要です。個別のnamespaceに異なるタイプのworkloadがデプロイされている場合は、Network Policyなどのセキュリティコントローラを導入する方がより簡単です。
4. より重要なworkloadを隔離する
何かあった時のインパクトを抑えるため、より重要なworkloadは、それ専用のマシン上で動かすのがベストです。コンテナランタイムやホストを共有している場合、セキュアでない別のアプリケーションからアクセスされる可能性が生じます。
node pool, namespace, taint, tolerationなどの機能を利用することで、この隔離を実現することができます。
※node poolはGKEに特有の機能で、Nodeの数やタイプを管理することのできる機能です。
5. Metadataへのアクセスをセキュアにする
重要なmetadata (kubeletのadmin credentialなど)は、クラスター内での権限を操作するために、盗まれたり誤用されることがあります。GKEのmetadata concealmentはこれを避けることが可能であるため、より良い解決策が見つかるまではこの機能を利用することを推奨します。
※Kubernetes ver. 1.9.3以降であればGKE Metadata concealment機能を利用することができます。公式ページはこちら
6. Network Policyを利用する
Network Policyを利用することで、Pod間のネットワークアクセスを制御できます。Network Policyを利用するには、それをサポートするネットワークプロバイダを使用する必要があります。
※Network Policyをサポートするものとして、公式では以下の5つを挙げています (アルファベット順)。
- Calico
- Cilium
- Kube-router
- Romana
- Weave Net
7. Pod Security Policyをクラスター全体で利用する
Pod Security Policyは、workloadがクラスター上で動くための前提条件を設定することができます。個々のpolicyをどのように設定し、それをどうやって適用するかは、cloud providerの種類などの条件によって変わります。
※Pod Security Policyに関してはこちらの記事がわかりやすいと思います。公式ページはこちら
8. Nodeのセキュリティを強化する
ここではNodeのセキュリティを強化する3stepを紹介します。
ホストはセキュアであり正しく設定されていることを確認する: これを確認する方法の一つとして、CIS Benchmarkと比較する方法があります。またその際は、Kube-Benchなどの自動チェックツールを利用することができます。
重要なポートへのアクセスを制御する: kubeletの利用するポートへのアクセスがブロックされるようにします。またKubernetes API serverへのアクセスは信頼できるネットワークからのみに制限します。
管理者権限でのノードへのアクセスを最小限にする: Nodeへのアクセスは一般的に少ない方が推奨されています。デバッグやその他のタスクを実行する際には、Nodeへ直接アクセスせずに実行するようにします。
9. Auditログを利用可能にする
Auditログを利用可能にし、監視することで、特に認証周りに関する異常なAPIコールを検知できます。Forbidden
など認証失敗のログがあることが、攻撃のあったことを教えてくれます。GKEなどのマネージドサービスでは、認証失敗のログが発生した時にアラートが鳴るよう設定することができます。
まとめ
記事であげられた9つのポイントの多くはKubernetesの機能で実現できるため、参考になる部分が多いと感じました。またそれ以外のポイントはGKEでしか実現できないものが多く、新規でKubernetesを利用する場合、セキュリティのことを考えるなら、現状ではGKEを使うのが良さそうです。