このドキュメントでは、Google Distributed Cloud(ソフトウェアのみ)on bare metal で作成されたクラスタのセキュリティを強化する方法について説明します。
SELinux を使用してコンテナを保護する
Red Hat Enterprise Linux(RHEL)でサポートされている SELinux を有効にすることで、コンテナを保護できます。ホストマシンが RHEL を実行している場合で、クラスタで SELinux を有効にするには、すべてのホストマシンで SELinux を有効にする必要があります。詳細については、SELinux を使用してコンテナを保護するをご覧ください。
seccomp
を使用してコンテナを制限する
セキュア コンピューティング モード(seccomp
)は、Google Distributed Cloud のバージョン 1.11 以降で利用できます。seccomp
プロファイルを使用してコンテナを実行すると、コンテナがカーネルに対して実行できるシステム呼び出しが制限されるため、クラスタのセキュリティが向上します。これにより、カーネルの脆弱性が悪用される可能性が低くなります。
デフォルトの seccomp
プロファイルには、コンテナが実行できるシステムコールのリストが含まれています。このリストにないシステムコールは許可されません。seccomp
は、バージョン 1.11 以降のクラスタでデフォルトで有効になっています。これは、すべてのシステム コンテナとお客様のワークロードが、コンテナ ランタイムのデフォルトの seccomp
プロファイルで実行されることを意味します。構成ファイルで seccomp
プロファイルを指定していないコンテナとワークロードも、seccomp
の制限が適用されます。
クラスタ全体または特定のワークロードで seccomp
を無効にする方法
seccomp
は、クラスタの作成時またはクラスタのアップグレード時にのみ無効にできます。bmctl update
を使用してこの機能を無効にすることはできません。クラスタ内で seccomp
を無効にするには、クラスタ構成ファイルに次の clusterSecurity
セクションを追加します。
apiVersion: baremetal.cluster.gke.io/v1
kind: Cluster
metadata:
name: example
namespace: cluster-example
spec:
...
clusterSecurity:
enableSeccomp: false
...
万が一、seccomp
がデフォルトでブロックするシステムコールを一部のワークロードで実行する必要がある場合、クラスタ全体で seccomp
を無効にする必要はありません。代わりに、特定のワークロードを選んで unconfined mode
で実行できます。unconfined mode
でワークロードを実行すると、seccomp
プロファイルがクラスタの他の部分に適用する制限からそのワークロードが除外されます。
unconfined mode
でコンテナを実行するには、Pod マニフェストに次の securityContext
セクションを追加します。
apiVersion: v1
kind: Pod
....
spec:
securityContext:
seccompProfile:
type: Unconfined
....
root
ユーザーとしてコンテナを実行しない
デフォルトでは、コンテナ内のプロセスは root
として実行されます。プロセスがコンテナから抜け出した場合、そのプロセスはホストマシン上で root
として実行されるため、セキュリティ上の問題になる可能性があります。したがって、すべてのワークロードを非 root ユーザーとして実行することをおすすめします。
以降のセクションでは、コンテナを非 root ユーザーとして実行する 2 つの方法について説明します。
メソッド #1: Dockerfile
に USER
命令を追加する
このメソッドは Dockerfile
を使用して、コンテナが root
ユーザーとして実行されないようにします。Dockerfile
では、コンテナ内のプロセスを実行するユーザーを指定できます。以下の Dockerfile
のスニペットは、これを行う方法を示しています。
....
#Add a user with userid 8877 and name nonroot
RUN useradd −u 8877 nonroot
#Run Container as nonroot
USER nonroot
....
この例では、Linux コマンド useradd -u
によって、コンテナ内に nonroot
というユーザーが作成されます。このユーザーには、8877
というユーザー ID(UID)が割り当てられます。
Dockerfile
の次の行によって、コマンド USER nonroot
が実行されます。このコマンドでは、イメージのこの時点以降に対してそのように実行するように指定され、ユーザー nonroot
としてコマンドが実行されます。
コンテナ プロセスを nonroot
に対して正しく実行できるように、UID 8877
に権限を付与します。
メソッド #2: Kubernetes マニフェスト ファイルに securityContext フィールドを追加する
この方法では、コンテナが root
ユーザーとして実行されないように Kubernetes マニフェスト ファイルを使用します。Pod にはセキュリティ設定が指定されており、それらのセキュリティ設定は Pod 内のすべてのコンテナに適用されます。
次の例は、特定の Pod のマニフェスト ファイルから抜粋した内容を示しています。
apiVersion: v1
kind: Pod
metadata:
name: name-of-pod
spec:
securityContext:
runAsUser: 8877
runAsGroup: 8877
....
runAsUser
フィールドは、Pod 内のコンテナに対して、すべてのプロセスがユーザー ID 8877
で実行されることを指定します。runAsGroup
フィールドは、これらのプロセスのプライマリ グループ ID(GID)が 8877
であることを指定します。コンテナ プロセスを適切に実行できるように、UID 8877
に必要かつ十分な権限を付与してください。
これにより、コンテナ内のプロセスが root よりも権限が少ない UID 8877
として実行されるようになります。
Google Distributed Cloud ソフトウェア専用のシステム コンテナは、クラスタのインストールと管理に役立ちます。これらのコンテナで使用される UID と GID は、クラスタ仕様の startUIDRangeRootlessContainers
フィールドで制御できます。startUIDRangeRootlessContainers
は省略可能なフィールドです。指定しない場合は、2000
の値が設定されます。startUIDRangeRootlessContainers
に指定できる値は 1000
~57000
です。startUIDRangeRootlessContainers
値はアップグレード時にのみ変更できます。システム コンテナは、startUIDRangeRootlessContainers
~startUIDRangeRootlessContainers
+ 2999 の範囲の UID と GID を使用します。
次の例では、Cluster リソースのマニフェスト ファイルの一部を示します。
apiVersion: baremetal.cluster.gke.io/v1
kind: Cluster
metadata:
name: name-of-cluster
spec:
clusterSecurity:
startUIDRangeRootlessContainers: 5000
...
システム コンテナで使用される UID スペースと GID スペースが、ユーザー ワークロードに割り当てられた UID スペースおよび GID スペースと重複しないように、startUIDRangeRootlessContainers
の値を選択します。
ルートレス モードを無効にする方法
Google Distributed Cloud のリリース 1.10 以降では、Kubernetes コントロール プレーン コンテナとシステム コンテナがデフォルトで非 root ユーザーとして実行されます。Google Distributed Cloud は、これらのユーザーに 2000
~4999
の範囲の UID と GID を割り当てます。ただし、この UID と GID が環境内で実行されるプロセスにすでに割り当てられている場合は、この割り当てによって問題が発生する可能性があります。
リリース 1.11 以降では、クラスタをアップグレードするときにルートレス モードを無効にできます。rootless モードを無効にすると、Kubernetes コントロール プレーン コンテナとシステム コンテナは root ユーザーとして実行されます。
rootless モードを無効にするには、次の手順を行います。
クラスタの構成ファイルに次の
clusterSecurity
セクションを追加します。apiVersion: baremetal.cluster.gke.io/v1 kind: Cluster metadata: name: example namespace: cluster-example spec: ... clusterSecurity: enableRootlessContainers: false ...
クラスタをアップグレードします。詳細については、クラスタをアップグレードするをご覧ください。
ワークロードの自己変更機能を制限する
特定の Kubernetes ワークロード(特にシステム ワークロード)には、自己変更の権限があります。たとえば、一部のワークロードは垂直方向に自動スケーリングされます。これは便利ですが、すでにノードを不正使用した攻撃者がクラスタ内でさらにエスカレーションする可能性があります。たとえば、攻撃者がノード上のワークロード自体を変更して、同じ Namespace 内に存在する、より権限の高いサービス アカウントとして実行するおそれがあります。
理想的には、ワークロードにはそもそも自己変更機能を付与するべきではありません。自己変更が必要な場合は、オープンソースの Gatekeeper ライブラリから NoUpdateServiceAccount などの Gatekeeper またはポリシー コントローラの制約を適用して権限を制限できます。これにより、いくつかの有用なセキュリティ ポリシーが提供されます。
ポリシーをデプロイする場合、通常はクラスタのライフサイクルを管理するコントローラがポリシーをバイパスできるようにする必要があります。これは、コントローラがクラスタに変更を加える(クラスタのアップグレードを適用するなど)ことができるようにするために必要です。たとえば、クラスタに NoUpdateServiceAccount
ポリシーをデプロイする場合は、Constraint
で次のパラメータを設定する必要があります。
parameters:
allowedGroups:
- system:masters
allowedUsers: []
kubelet 読み取り専用ポートを無効にする
リリース 1.15.0 以降、Google Distributed Cloud では、デフォルトで 10255
の kubelet 読み取り専用ポートが無効になります。お客様のワークロードが、この安全でない kubelet ポート 10255
からデータを読み取るように構成されている場合は、安全な kubelet ポート 10250 を使用するように移行する必要があります。
このポートは、バージョン 1.15.0 以降で作成されたクラスタしかデフォルトで無効になっていません。クラスタがバージョン 1.15.0 以降にアップグレードされても、1.15.0 より前のバージョンで作成されたクラスタでは、kubelet 読み取り専用ポート 10255
がアクセス可能なまま残ります。
この変更は、機密性の低い情報が kubelet が未認証のポート 10255
を介して漏洩したことから加えられたものです。この情報には、ノード上で実行されているすべての Pod の完全な構成情報が含まれており、攻撃者にとって貴重な情報となる可能性があります。また、指標やステータス情報も公開され、ビジネス上重要な分析情報を含んでいる可能性があります。
CIS Kubernetes Benchmark では、kubelet 読み取り専用ポートを無効にすることが推奨されています。
メンテナンス
セキュリティ情報のモニタリングとクラスタのアップグレードは、クラスタが稼働した後に実施する必要がある重要なセキュリティ対策です。
セキュリティ情報を監視する
GKE のセキュリティ チームは、重大度が「高」や「重大」の脆弱性のセキュリティに関する情報を公開しています。
これらの情報は、共通の Google Cloud 脆弱性番号スキームに従っており、メインの Google Cloud 情報ページとリリースノートからリンクされています。
この XML フィードを使用して、Google Kubernetes Engine(GKE)と関連プロダクトのセキュリティに関する公開情報を定期的に受け取ります。
このような重大度が「高」や「重大」の脆弱性に対処するためにお客様の対応が必要な場合は、Google からメールでご連絡いたします。また、Google はサポート チャネルを通じてサポート契約を結んでいるお客様にご連絡する場合もあります。
Google が GKE と GKE Enterprise のセキュリティ脆弱性を管理してパッチを適用する方法については、セキュリティ パッチをご覧ください。
クラスタをアップグレードする
Kubernetes では新しいセキュリティ機能が定期的に導入されており、セキュリティ パッチが提供されています。Google Distributed Cloud のリリースには、クラスタに影響を与える可能性があるセキュリティの脆弱性に対処する Kubernetes セキュリティ強化が組み込まれています。
クラスタを最新の状態に保つことは、お客様の責任で行っていただく必要があります。各リリースについて、リリースノートをご確認ください。クラスタのセキュリティ リスクを最小限に抑えるには、新しいパッチリリースへの更新を毎月、マイナー バージョンへの更新を 4 か月ごとに実施するようにしてください。
クラスタをアップグレードすることの多くのメリットの一つは、クラスタの kubeconfig ファイルが自動的に更新されることです。kubeconfig ファイルは、クラスタに対してユーザーを認証します。bmctl
でクラスタを作成すると、kubeconfig ファイルはクラスタ ディレクトリに追加されます。デフォルトの名前とパスは bmctl-workspace/CLUSTER_NAME/CLUSTER_NAME-kubeconfig
です。クラスタをアップグレードすると、そのクラスタの kubeconfig ファイルが自動的に更新されます。それ以外の場合、kubeconfig ファイルは作成日から 1 年後に期限切れになります。
クラスタのアップグレード方法については、クラスタをアップグレードするをご覧ください。
Cloud Interconnect や Cloud VPN で VPC Service Controls を使用する
Cloud Interconnect は、低レイテンシで高可用性の接続を提供し、オンプレミスのベアメタル マシンと Google Cloud Virtual Private Cloud(VPC)ネットワークとの間でデータを確実に転送できるようにします。Cloud Interconnect の詳細については、Dedicated Interconnect のプロビジョニングの概要をご覧ください。
Cloud VPN は、IPsec VPN 接続を使用してピア ネットワークを Virtual Private Cloud(VPC)ネットワークへ安全に接続します。Cloud VPN については、Cloud VPN の概要をご覧ください。
VPC Service Controls は、Cloud Interconnect または Cloud VPN と連携し、クラスタのセキュリティを強化します。VPC Service Controls を使用すると、データが引き出されるリスクを軽減できます。VPC Service Controls の活用により、境界の外部から発生するリクエストからリソースとサービスを保護するサービス境界にプロジェクトを追加できます。サービス境界の詳細については、サービス境界の詳細と構成をご覧ください。
Google Distributed Cloud で作成されたクラスタを完全に保護するには、制限付き VIP を使用して、次の API をサービス境界に追加する必要があります。
- Artifact Registry API(
artifactregistry.googleapis.com
) - Resource Manager API(
cloudresourcemanager.googleapis.com
) - Compute Engine API(
compute.googleapis.com
) - Connect gateway API(
connectgateway.googleapis.com
) - Google Container Registry API(
containerregistry.googleapis.com
) - GKE Connect API(
gkeconnect.googleapis.com
) - GKE Hub API(
gkehub.googleapis.com
) - GKE On-Prem API(
gkeonprem.googleapis.com
) - Identity and Access Management(IAM)API(
iam.googleapis.com
) - Cloud Logging API(
logging.googleapis.com
) - Cloud Monitoring API(
monitoring.googleapis.com
) - Ops API の構成モニタリング(
opsconfigmonitoring.googleapis.com
) - Service Control API(
servicecontrol.googleapis.com
) - Cloud Storage API(
storage.googleapis.com
)
bmctl
を使用してクラスタを作成またはアップグレードする場合は、--skip-api-check
フラグを使用して、Service Usage API(serviceusage.googleapis.com
)の呼び出しを回避します。Service Usage API は、VPC Service Controls ではサポートされていません。