コンテナとKubernetes(K8s)が普及するにつれてITの状況は大きく変化しています。わずか7年で、トレンドは仮想マシンからコンテナへ、そしてコンテナオーケストレーションプラットフォームに移行しました(最初のDockerリリースは2013年)。経験の浅い企業ではこれらをどう活用するかまだ模索してますが、成熟した企業ではレガシーシステムを効率的なインフラストラクチャへ移行すべく検討をしています。
急速に採用が進むコンテナやKubernetesといった技術はディスラプティブなものであると同時に、これまでになかったセキュリティの問題も引き起こしています。コンテナとKubernetesは急速に広まったため、企業ではセキュリティ対策が不十分で、攻撃の標的になっています。
K8sクラスタは、マスターノードとそのレプリカが管理するマシンのセットです。マシンやサービスの数は数千になることもあり、攻撃ベクトルとして使われることも多々あります。そのため厳しいセキュリティプラクティスが不可欠になります。
クラスタの保護
Kubernetesクラスタは複雑で、適切な保護が必要です。クラスタは1つのプロセスで守れるようなものではありません。クラスタ全体を守るには複数のベストプラクティスと優れたセキュリティチームが必要です。
以下では、Kubernetesの様々な攻撃ベクトルについて、またK8sクラスタ保護のベストプラクティスについてご説明します。
Kubernetesとノードを常に最新化する
K8sはオープンソースシステムで継続的にアップデートされます。GitHubレポジトリはこのプラットフォームの中でも最もアクティブなリポジトリで、機能、改良、セキュリティアップデートが常時追加されています。
Kubernetesでは4か月ごとに新しいメジャーバージョンがリリースされます。新しいバージョンでは新機能が追加されますが、そのために新しいセキュリティ問題やバグが発生することもあります。頻繁に更新される場合は特にです。
ただし古いバージョンでも同じような危険はあります。そのためKubernetesの古いバージョンのセキュリティアップデートについて知っておくことも必要です。Linuxや他のプラットフォームとは違い、KubernetesにはLTSバージョンがなく、代わりにセキュリティの問題を直近の3つのメジャーバージョンにバックポートしようとします。
そのためクラスタは直近の3バージョンのいずれかになっているようにし、常にセキュリティパッチを適用し、少なくとも年に1回は最新のメジャーバージョンにアップデートするようにしてください。
Kubernetesは主要コンポーネントに加えて、クラスタに割り当てられたワークロードを実行するノードも処理します。これらのノードは物理マシンだったり仮想マシンだったりします。どのノードも攻撃ベクトルになりえるため、セキュリティアップデートは不可欠です。攻撃対象を減らすには、ノードはできる限りクリーンにしておく必要があります。
ユーザーアクセスの制限
クラスタのユーザーアクセス権限とアクセス方法の管理には、役割ベースのアクセス制御(RBAC)が役立ちます。これを用いれば、各ユーザーの権限を細かく定義できます。ルールは付加的なものなので、権限は明示的に設定しなければなりません。RBACでは、ポッド(K8sの最小コンピューティングユニティ)からネームスペースまで、各Kubernetesオブジェクトへのアクセス許可(閲覧、読み取り、書き込み)を制限できます。
RBACはOpenID接続トークンを使って別のディレクトリサービスに適用することもできます。これによりユーザーやグループの管理を一括で定義して、組織全体で使えるようにも設定できます。
アクセス許可を制限する対象はKubernetesだけではありません。例えば、問題を特定するためにユーザーがクラスタノードにアクセスしたいという場合があります。このような場合はテンポラリのユーザーを作成して問題解決後にユーザーを削除するということができます。
コンテナのベストプラクティス
一番有名なコンテナ技術であるDockerはレイヤー構成になっています。一番内側のレイヤーは基盤構造で、外側のレイヤーは個別の機能です。そのためDockerイメージでは最初のほうのレイヤーはディストリビューションや言語サポートなどとなり、新しいレイヤーは機能の追加や変更になります。そのように積み重ねていって、最終的にアプリケーションの起動に必要なすべてがコンテナ内に揃うことになります。
これらのレイヤー(イメージとも呼ばれる)はDocker Hubで公開したり、別のイメージレジストリでプライベートに利用できます。イメージは2つの形式で表示します。1つは名前とラベル(例:node:latest)、もう1つは不変のSHA識別子 (例:執筆時点では同じイメージは (e.g., sha256:d64072a554283e64e1bfeb1bb457b7b293b6cd5bb61504afaa3bdd5da2a7bc4b
です。).
リポジトリの所有者はラベルに紐づけられたイメージをいつでも変更できます。そのためlatest(最新)のタグはそれが最新のバージョンだということを示しています。これはまた、新しいイメージを作成したり、タグ付きのイメージを実行したりすると、内側のレイヤーが前触れなく突然変更される可能性があるということを意味しています。
これはいくつかの問題を引き起こします。(1)上位レイヤーが更新されて競合が起こるとKubernetesインスタンスで実行しているものを制御できなくなる。(2)セキュリティを侵害するためにイメージが意図的に変更され得る。
1つ目の問題を防ぐには、最新のタグは使わずに、よりバージョン固有のタグ(例:node:14.5.0)を使うようにします。2つ目の問題を回避するには、オフィシャルイメージを使うか、イメージをプライベートリポジトリに複製するか、またはSHA値を使用します。
または、使用されているイメージを脆弱性検知ツールで常時スキャンします。これらのツールは、継続的インテグレーションパイプラインと一緒に実行でき、イメージリポジトリを監視することで、以前は検知されなかった問題も特定できます。
新しいイメージを作成する場合、1つのイメージには1つのサービスのみ、またそのアプリケーションに必要な依存関係のみが含まれるようにします。これで必要なコンポーネントだけになるので、攻撃対象を減らすことができます。1つのイメージに1つのアプリケーションのみになるため、バージョンの更新やオーケストレーターでのリソースの割り当ても簡単になります。
ネットワークセキュリティ
上記セクションでは攻撃対象の削減について説明しましたが、ネットワークにも同じことが言えます。Kubernetesではクラスタ内に仮想ネットワークがあります。これによりポッド間のアクセスを制限し、外部からのアクセスを許可して、許可されたサービスだけにアクセスできるようにします。これは、小規模クラスタであれば機能する、基本的ソリューションです。
複数のチームで複数のサービスを開発するような大規模クラスタは複雑であり、一元化した管理はほぼ不可能です。このようなケースでは今のところサービスメッシュが最も適した方法です。サービスメッシュは、サービス同士が安全に通信できるネットワーク暗号化レイヤーを作成します。これらは各ポッドに付属するサイドカーエージェントとして動き、サービス間の通信を可能にします。サービスメッシュの利点はセキュリティだけではありません。サービスディスカバリ、監視/トレース/ロギングも実行でき、また例えば回路遮断パターンを適用することでサービスの中断を回避することもできます。
リソースクォータの確立
アプリケーションは常時更新されるので、上記のようなクラスタ保護だけでは十分なセキュリティ対策とはいえません。
リソースクォータの利用も重要です。これを用いると、Kubernetesは停止の影響を規定の範囲内にとどめることができます。制限範囲が適切に設計されていれば、リソースの過度な消費によって全クラスタサービスが停止してしまうことは防げます。
また過度なリソース利用によってクラウド使用料が巨額になることも防げます。
監視とロギング
停止を発見して原因を特定するには、クラスタからポッドまでを監視して、異常行動を検知することが必要です。ネットワークトラフィックが増大したり、ノードのCPUが異常動作した場合は詳しく調査します。監視はCPU、メモリ、ネットワークなどのメトリックスを対象とし、ロギングは、異常パターンの検知や問題の原因追及に必要な(履歴)情報の提供を目的とします。
PrometheusやGraphanaといったツールはKubernetes監視に有効です。Prometheusは高パフォーマンスの時系列データベースで、GraphanaはPrometheusのデータをわかりやすく提示するグラフィカルダッシュボードです。
もう1つの便利なツールはElasticSearchです。これはアプリケーション、ノード、Kubernetesのログをほぼリアルタイムで一元的に提供できるため非常によく利用されています。
クラウド vs オンプレミス:セキュリティの観点
Kubernetesはオンプレミスでもクラウドマネージメントサービスでも利用できます。オンプレミスでは、すべての構成(新しいマシンの立ち上げ、ネットワークのセットアップ、アプリケーションの保護)をマニュアルでデプロイしなければなりません。Google GKE、AWS EKS、Azure AKSなどのクラウドマネージドサービスではK8を最小限の構成でインストールできます。またクラウドプロバイダーの他のサービスと互換性もあります。
セキュリティの観点から言うと、オンプレミスには多くの課題があります。前述のように、更新はシステムごとにダウンロードして構成しなければならず、ノードの更新も必要です。そのため経験豊富なチームでないと、オンプレミスでのKubernetesのデプロイは難しいでしょう。
一方クラウドマネージメントサービスでは、Kubernetesがすでにインストールされており、セキュリティアップデートもクラウドベンダーが実施するため管理も簡単です。クラスタの観点から言うと、ほとんどのクラウドマネージメントサービスではユーザーがK8sバージョンを自分で選択でき、バージョンの更新も提供されます。そのため、より簡単にはなりますが、同時に柔軟性も低くなります。
まとめ
更新や新しいツールが絶え間なく提供されるため、常に最新の状態を維持し、脆弱性に対応することは困難です。セキュリティ侵害をすべて回避することはほぼ不可能でしょう。Kubernetesは単なるツールではないため、より多くの課題に直面します。Kubernetesは他のツール、マシン、ネットワークを管理するツールのセットです。そのため強固な保護が欠かせません。
しかしKubernetesは複雑でありセキュリティの確保は簡単ではないため、次のガイドラインに従うようにしてください。
- K8s上のアプリケーションをスキャンしてセキュリティの問題を確認します。
- アクセスを制限しコントロールします。
- 最新のセキュリティ更新プログラムを常に適用し、クラスタを常時監視してて停止に迅速に対処してダメージを軽減します。
オンプレミスでデプロイすると、ハードウェアの管理、自動化の設定、ソフトウェアの更新を自ら行わなければならないため、課題はさらに多くなります。しかし上記のようなベストプラクティスを実行すればセキュリティを強化でき、Kubernetes環境の安全を確保できます。
SentinelOneプラットフォームは、物理/仮想マシン、Docker、自己管理のKubernetes、そしてAWS EKSなどのクラウドサービスプロバイダーが管理するKubernetesをサポートします。より詳細をお知りになりたい場合はぜひ無償デモをお申し込みください。