LASSIC Media らしくメディア
コンテナセキュリティ対策を外注で進める
LASSIC IT事業部|元請(プライムベンダー)としてシステム保守・運用を受託
この記事のポイント
- コンテナのイメージスキャンでは、OSパッケージや言語ライブラリのCVE(共通脆弱性識別子)をビルド時点で検出できます。
- NIST SP 800-190は、イメージ・レジストリ・オーケストレータ・ランタイムという4つの構成要素ごとにリスクと対策を整理しています。
- Kubernetesの本番運用では、RBAC・NetworkPolicy・Pod Security Standardsの既定値が緩いため、明示的な設定が求められます。
目次
コンテナ環境特有のセキュリティリスク——イメージ・レジストリ・オーケストレータ・ランタイムの4層
従来のサーバー運用では、OSやミドルウェアへのパッチ適用が保守担当者の主な作業でした。一方でDockerやKubernetesを使うコンテナ環境では、イメージという単位でアプリケーションと依存関係がまとめてパッケージ化されるため、脆弱性が入り込む経路そのものが従来のサーバー運用とは異なる形になります*1。
NIST(米国立標準技術研究所)が2017年9月に公開したSP 800-190「アプリケーションコンテナセキュリティガイド」は、コンテナ環境のリスクをイメージ・レジストリ・オーケストレータ・コンテナ(ランタイム)という4つの構成要素に分けて整理しています*1。この文書はIPA(情報処理推進機構)が日本語訳を公開しており、国内でも参照されています*2。
4つの構成要素は互いに独立した話ではありません。ビルド時点のイメージに脆弱性が残っていれば、レジストリでの管理やランタイムでの権限制御をどれだけ厳密にしても、根本のリスクは解消されないのです。逆にイメージが健全でも、レジストリへのアクセス制御が緩ければ、改ざんされたイメージが配布される恐れがあります。以降の章では、この4層それぞれの対策を具体的に見ていきましょう。
イメージスキャンで検出する脆弱性——CVE・CVSSとベースイメージ選定
コンテナイメージの脆弱性スキャンとは、イメージに含まれるOSパッケージや言語ライブラリを走査し、既知の脆弱性であるCVE(Common Vulnerabilities and Exposures)が含まれていないかを確認する作業を指します。検出された脆弱性には、深刻度を数値化するCVSS(Common Vulnerability Scoring System)のスコアが付与されているものもあり、対応の優先順位づけに利用できます。
OSSのコンテナイメージスキャナーとして知られるTrivyは、Alpine LinuxやDebian、Ubuntuなど複数のOSパッケージと、Python・Node.js・Java・Goといった言語別の依存パッケージを対象にCVEを検出する仕組みです*4。あわせてSBOM(Software Bill of Materials。イメージに含まれるソフトウェア構成要素の一覧)を生成する機能も備えており、後から新しい脆弱性が公表された際、どのイメージが影響を受けるかを突き合わせる土台になります*4。
スキャンだけでは不十分な部分もあります。土台となるベースイメージ自体が肥大化していれば、不要なパッケージの分だけ攻撃対象領域が広がるからです。Docker公式のベストプラクティスでは、信頼できる提供元から取得した小さなイメージを選び、本番環境ではビルドツールやデバッグツールを含まないスリムな構成にすることが推奨されています*3。
ビルド段階のシフトレフト——CI組み込みと署名による供給網対策
シフトレフトとは、脆弱性の検出をリリース後や運用中ではなく、開発の早い段階であるビルド・CIパイプラインに前倒しする考え方です。NIST SP 800-190も、イメージ向けの脆弱性管理ツールをイメージのライフサイクル全体に組み込み、組織全体で一元的に可視化することを対策の一つに挙げています*1。
具体的には、CI(継続的インテグレーション)のパイプライン内でイメージスキャンを実行し、重大な脆弱性が見つかった場合はビルドやレジストリへのプッシュを止める運用がよく使われます。稼働中のシステムで脆弱性に対処するより、コミットやプルリクエストの段階で差し戻すほうが、修正の手戻りは小さく済みます。
ビルドしたイメージの真正性を担保する手段として、イメージ署名も検討対象になります。sigstoreプロジェクトが提供するOSSのcosignは、GitHubなどのOIDC(OpenID Connect)認証を利用し、長期の秘密鍵を管理しないkeyless署名に対応しています*5。デプロイ時に署名を検証する仕組みを組み込んでおくと、意図しない経路で作られたイメージが本番環境に混入する事態への備えになります*5。
レジストリ管理とランタイム保護——アクセス制御と最小権限の実装
レジストリ(コンテナイメージを保管・配布する場所)は、イメージという成果物の集約点であるため、アクセス制御の甘さがそのままリスクにつながりやすい領域です。認証されていないユーザーによるプッシュ・プルや、通信経路の暗号化不備は、NIST SP 800-190がレジストリの主要なリスクとして扱っている点です*1。private registryの利用や、push・pull権限を役割ごとに分ける運用が基本になります。
ランタイム側では、コンテナに与える権限を絞り込むことが軸になります。Dockerfileの中でUSER命令を使い、root以外のユーザーでプロセスを起動する設定は、Docker公式のベストプラクティスでも推奨されている項目です*3。あわせて、書き込みを想定しないファイルシステムを読み取り専用にする設定や、Linuxのケーパビリティを必要最小限まで絞り込む設定も、権限を絞るという同じ方向の対策になります。
これらはKubernetesにおいてPod Security Standardsの「Restricted」レベルとしてまとめて定義されています。runAsNonRoot(非rootでの実行)、allowPrivilegeEscalation: false(権限昇格の禁止)、readOnlyRootFilesystem(読み取り専用のルートファイルシステム)、capabilities.drop: ALL(不要なケーパビリティの削除)などが具体的な設定項目に含まれます*6。seccompプロファイルをRuntimeDefaultに指定する項目も、同じRestrictedレベルの一部です*6。
Kubernetesのセキュリティ設定——RBAC・NetworkPolicy・Pod Security
RBAC——名前空間単位とクラスタ単位で権限を分ける仕組み
Kubernetesクラスタを本番運用する場合、イメージやコンテナ単体の対策だけでなく、クラスタの設定そのものが対象になります。RBAC(Role-based access control)は、Kubernetes APIへの操作権限を、名前空間単位のRole・RoleBindingと、クラスタ全体に及ぶClusterRole・ClusterRoleBindingで管理する仕組みです*7。権限は加算的な設計になっており、明示的なdenyルールは存在しません*7。必要以上の権限を持つRoleBindingを作らないよう、定期的な棚卸しが要ります。
NetworkPolicy——既定は全通信許可という前提を踏まえる
NetworkPolicyは、Pod間通信をIPアドレスやポートの単位で制御するリソースです。見落とされがちなのが、NetworkPolicyを何も設定していないクラスタでは、Ingress(受信)もEgress(送信)もすべての通信が既定で許可されている点です*8。特定のPodを選択してIngress・Egressのルールを定義した時点で初めて、その通信が制限される仕組みになっています*8。運用が進んでからNetworkPolicyを後付けする場合は、想定外の通信遮断が起きないよう、検証環境での確認が実務上の要点になります。
Pod Security Standardsは、Privileged・Baseline・Restrictedという3段階のプロファイルを定義しており、namespaceにラベルを付与することでPod Security Admissionコントローラーが強制・警告・監査のモードで適用します*6。RBAC・NetworkPolicy・Pod Security Standardsを組み合わせることで、クラスタの設定不備を起点にした侵入経路を狭められます。
継続的な脆弱性管理の運用——内製と外注の判断軸
イメージスキャンやKubernetesの設定は、一度整えて終わりにはなりません。公開済みのソフトウェアに後から新しいCVEが公表されるケースは珍しくなく、稼働中のイメージを定期的に再スキャンし、影響の有無を確認する運用が欠かせないからです。ベースイメージの更新やパッチ適用のサイクルを、リリースのスケジュールと切り離して回す体制が求められます。
この運用を内製で担うには、複数領域の知識が要ります。Dockerfileの書き方やCIパイプラインの設定、Kubernetesのマニフェスト、レジストリの権限設計、RBACやNetworkPolicyの棚卸しなど、対象領域は一人の担当者だけでは抱えきれない広さになりがちです。
外部のパートナーに委託する場合は、依頼範囲の広さが選定の分かれ目になります。イメージスキャンのCI組み込みだけを依頼するのか、Kubernetesクラスタの設定監査や署名運用まで含めて任せるのかによって、必要な体制は変わってきます。既存の開発体制や運用担当者の工数を踏まえたうえで、内製・外注の切り分けを検討することが実務的です。
まとめ:コンテナセキュリティ対策で押さえる3つの視点
本稿ではコンテナセキュリティの論点を、NIST・Kubernetes公式情報をもとに整理しました。要点は3つに集約できます。第一に、コンテナのリスクはイメージ・レジストリ・オーケストレータ・ランタイムという4つの構成要素に分けて捉える必要があります*1。第二に、イメージスキャンと署名によるビルド段階のシフトレフトを進めることで、脆弱性や改ざんの検出をリリース前に前倒しできます*4*5。第三に、Kubernetesの本番運用ではRBAC・NetworkPolicy・Pod Security Standardsの既定値が緩い前提に立ち、明示的な設定が要ります*6*7*8。
よくある質問
コンテナイメージの脆弱性スキャンは、どのタイミングで実施すればよいですか。
CIパイプラインでのビルド時、レジストリへの登録前、そして稼働中の定期的な再スキャンという3つのタイミングで行うのが基本です。新しいCVEは稼働後に公表されることもあるため、ビルド時点の一度のスキャンだけでは、後から見つかった脆弱性を把握できません*4。
コンテナをrootユーザーで動かすと、具体的に何が問題になりますか。
コンテナ内のプロセスが乗っ取られた場合、rootでの実行はホストへの影響範囲を広げる要因になります。Dockerfileの中でUSER命令を使い、非rootユーザーで起動する設定が推奨されています*3。KubernetesのPod Security Standards(Restrictedレベル)でも、runAsNonRootの指定が定義されています*6。
KubernetesのNetworkPolicyを何も設定していない場合、通信はどうなりますか。
NetworkPolicyが1つも設定されていないnamespaceでは、Pod間のIngress・Egress双方の通信が既定で許可された状態になります*8。特定のPodを対象にポリシーを定義した時点で、そのPodの通信だけが制限される仕組みです*8。
イメージへの署名は何のために行うのですか。
レジストリに登録されたイメージが、意図したビルドパイプラインを経由して作られたものかどうかを検証するために行います。cosignのようなツールは、OIDC認証を使ったkeyless署名に対応しており、長期の秘密鍵を管理せずに署名・検証の仕組みを組み込めます*5。
コンテナセキュリティ対策を外部に委託する場合、何を確認すればよいですか。
イメージスキャンをCIのどの段階に組み込むか、Kubernetesクラスタの設定監査をどこまでの範囲で行うか、稼働後の継続的な再スキャンやパッチ適用まで対応するかを、契約前にすり合わせておくことが大切です。委託範囲があいまいなまま進めると、運用開始後に対応漏れが見つかる場合があります。
著者:テレリモ総研編集部 鈴木 亮佑
ご不明な点はお問い合わせフォームからもご連絡いただけます。
- *1 出典:NIST「SP 800-190, Application Container Security Guide」(https://csrc.nist.gov/pubs/sp/800/190/final)
- *2 出典:IPA「NIST Special Publication 800-190 アプリケーションコンテナセキュリティガイド」日本語訳(https://www.ipa.go.jp/security/reports/oversea/nist/ug65p90000019cp4-att/begoj9000000bf1r.pdf)
- *3 出典:Docker「Building best practices」(Docker Docs)(https://docs.docker.com/build/building/best-practices/)
- *4 出典:Trivy「Vulnerability Scanning」(Trivy公式ドキュメント)(https://trivy.dev/docs/latest/scanner/vulnerability/)
- *5 出典:Sigstore「Signing Containers」(cosign公式ドキュメント)(https://docs.sigstore.dev/cosign/signing/signing_with_containers/)
- *6 出典:Kubernetes「Pod Security Standards」(Kubernetes公式ドキュメント)(https://kubernetes.io/docs/concepts/security/pod-security-standards/)
- *7 出典:Kubernetes「Using RBAC Authorization」(Kubernetes公式ドキュメント)(https://kubernetes.io/docs/reference/access-authn-authz/rbac/)
- *8 出典:Kubernetes「Network Policies」(Kubernetes公式ドキュメント)(https://kubernetes.io/docs/concepts/services-networking/network-policies/)