コンテナセキュリティに関する本を書きました

Akihiro Suda
nttlabs
Published in
10 min readMar 25, 2020

--

NTTの須田です。この度、「Docker/Kubernetes開発・運用のためのセキュリティ実践ガイド」という書籍を執筆しました。Z Labの五十嵐 綾 (@Ladicle)さん、宇佐美 友也 (@hiyosi)さんとの共著です。

Docker/Kubernetes開発・運用のためのセキュリティ実践ガイド

Amazon: https://www.amazon.co.jp/dp/4839970505

Manatee (PDF版): https://book.mynavi.jp/manatee/books/detail/id=114724

Docker や Kubernetes を安全に使うための設定方法やツールについて、 本書ほど網羅的かつ詳細に記した書籍はおそらく他にはありません。Dockerに代わるコンテナエンジンとして話題のPodmanなど、最新のソフトウェアに関する情報もふんだんに盛り込んであります。

以下、各章の内容を紹介します。

第1章: Docker・Kubernetesの復習

本章ではDockerやKubernetesの仕組みや使い方をおさらいします。ただし、DockerやKubernetesに初めて触れる方は、入門者向けの書籍にも目を通されるとよいでしょう。

1.1: Dockerの復習

Docker (およびPodman) のインストール方法や使い方を簡単におさらいします。また、コンテナランタイムの実装に用いられる、Namespaces、Capabilities、Cgroups、AppArmor、SELinux などの仕組みについてもおさらいします。

1.2: Kubernetesの復習

KubernetesのMasterおよびNodeを構成するコンポーネント群や、その使い方について簡単におさらいします。

1.3: TLSの復習

TLS (Transport Layer Security)の仕組みや、証明書の管理方法についておさらいします。Docker や Kubernetes のコンポーネントを正しく設定するには欠かせない知識です。

第2章: コンテナ運用における脅威の事例

本章ではコンテナ運用における脅威の事例を紹介します。また、これらの脅威はどうすれば被害を免れるこ とができたかについても解説します

2.1: APIエンドポイントの設定ミス

Docker デーモンのREST API エンドポイントをTCPポートにバインドする場合、TLSクライアント認証の設定が必須です。TLSクライアント認証の設定を怠ったためにホストのroot権限を奪取された事例などを紹介します。

また、ホストとして使う IaaS インスタンスのメタデータサービス (典型的には 169.254.169.254) を通じた権限昇格などについても解説します。

2.2: ランタイムやカーネルの脆弱性

CVE-2019–5736 (runc) などのランタイムの脆弱性がもたらしうる脅威について解説します。ランタイムの脆弱性に由来する脅威の多くは、第3章で紹介する通り、コンテナを非rootユーザで実行したり、SELinuxを有効化したりすることで被害を軽減できます。

また、CVE-2017–5123 などのカーネルの脆弱性も紹介します。カーネルの脆弱性を軽減するには、Kata ContainersやgVisorを使って、コンテナのカーネルをホストから分離することが有効です。

2.3: イメージの脆弱性

CVE-2019–5021 (Alpine)などのコンテナイメージの脆弱性を紹介します。第4章で紹介するTrivyやDockleを使うと、イメージの脆弱性を検出することができます。

また、 CVE-2019–16097 (Harbor)などレジストリの脆弱性も紹介します。同じく第4章で紹介するDocker Content Trust (Notary)を使うと、レジストリの脆弱性を突いて改竄されたイメージのデプロイを防止できます。

2.4: Kubernetesコンポーネントの脆弱性

kube-apiserverなどのKubernetesコンポーネントの脆弱性を紹介します。第5章で紹介する通り、KubernetesのRBACを細かく設定しておくと被害を軽減できることがあります。

第3章: ランタイムのセキュリティTips

container breakoutを防ぐのに役立つdocker run コマンドのフラグや、Kubernetesの securityContext について解説しています。kubeletよりも上のレイヤの話は、基本的には第5章で扱っています。

3.1: Docker APIエンドポイントを保護する

TLSクライアント認証を設定することで、Docker デーモンのREST API エンドポイントを保護する方法を紹介します。TLSの代わりにSSHを使う方法も紹介します。

3.2: コンテナ実行ユーザを変更する

コンテナを非rootユーザで実行することで、ランタイムなどの脆弱性を突いたcontainer breakoutを困難にする方法を紹介します。コンテナだけではなくランタイムも非rootユーザで実行する、Rootlessモードも紹介します。

3.3: ケーパビリティやシステムコールを制限する

CAP_NET_RAW ケーパビリティをドロップすることでARPスプーフィングを防止する方法や、seccompを使って不要なシステムコールの呼び出しを禁止する方法を紹介します。

3.4: ファイルアクセスを制限する

AppArmorやSELinuxを使って、ホストからbind-mountしたファイルへのアクセスを制限する方法を紹介します。カスタムプロファイルの作成方法についても解説します。

3.5: リソースを制限する

コンテナが使用できるCPUやメモリの容量を制限する方法を紹介します。強い負荷を受けているコンテナが、他のコンテナの動作を阻害することを防ぎます。

3.6: 代替ランタイムを利用する

デフォルトで用いられるruncよりもセキュアなランタイムである、Kata ContainersおよびgVisorを紹介します。

3.7: コンテナを監視する

Fluentdを使ってコンテナのログを収集する方法や、Falcoを使って不審なコンテナを発見する方法を紹介します。

3.8: 設定を検証する

Docker Bench for Security を使って、Dockerの設定を点検する方法を紹介します。

第4章: イメージのセキュリティTips

コンテナイメージに秘密情報が紛れ込むことを防ぐ方法や、脆弱なイメージのデプロイを防ぐ方法などを紹介します。

4.1: DockerfileからプライベートなGitやS3にアクセスする

プライベートなアセットを用いてイメージをビルドする安全な方法として、 docker build --secret などを紹介します。

4.2: コンテナ内で安全にイメージをビルドする

特権無しに安全にイメージをビルドできる新しいツールとして、BuildKitおよびKanikoを紹介します。

4.3: イメージの脆弱性を検査する

イメージ内のパッケージの脆弱性を検査するツールとして、ClairおよびTrivyを紹介します。パッケージ以外の脆弱性を検査するツールであるDockleも紹介します。

4.4: 改竄されたイメージのデプロイを防ぐ

Docker Content Trust (Notary)を使ってイメージに署名し、改竄されたイメージのデプロイを防ぐ方法を紹介します。

4.5: プライベートレジストリを構築する (Harbor)

Harborを使って、セキュアなプライベートレジストリを簡単に構築する方法を紹介します。

第5章: KubernetesクラスタのセキュリティTips

RBACなど、主にkube-apiserverに関するTipsを紹介します。

5.1: クラスタを最新の状態に保つために

Kubernetesのリリースライフサイクルや、脆弱性情報の収集方法について解説します。

5.2: ミスや攻撃から守るAPIのアクセス制御

kube-apiserverの認証(AuthN)・認可(AuthZ)について解説します。

5.3: 認証モジュールの選び方と使い方

X.509クライアント証明書やOpenID Connectなど、Kubernetes APIユーザの認証方法の選び方・使い方について解説します。

5.4: Service Accountによるサービス認証とアカウント

KubernetesのService Accountを使ったPodの権限管理方法について解説します。

5.5: 認可モジュールの種類と利用方法

RBACやWebhookなどの認可モジュールの種類と利用方法について解説します。

5.6: Admissionコントローラによる柔軟なアクセス制御

PodSecurityPolicy などのAdmisssionコントローラプラグインを紹介します。

5.7: Webhookで独自のAdmission Controlを追加する

Webhookで独自のAdmissionコントローラを実装し、リソースの検証や書き換えを行う方法について解説します。

5.8: システムコンポーネント間通信の保護

kube-apiserverとkubeletの間などの通信の保護に用いられる、mTLSの証明書の管理方法について解説します。

5.9: スケジューラによる割り当てノードの制御

TaintやTolerationなどを用いて、ノードレベルでワークロードを隔離する方法について解説します。

5.10: 秘密情報を管理する

Secretリソースの使い方や、その暗号化方法について解説します。

5.11: GitOpsのためのSecret管理

SecretリソースをGitに安全に格納できるようにするツールである、Sealed Secretsを紹介します。

第6章: アプリケーション間通信を守る

Istioなどを使って、アプリケーションが意図しない相手と通信することを防ぐ方法を紹介します。

6.1: Network Policyを使ってPodの通信を制御する

Network Policyを使って、PodがアクセスできるIPアドレスやポートを制限する方法を紹介します。

6.2: Istioを使ってPod間の通信を守る

代表的なサービスメッシュ基盤であるIstioを使って、Pod間の通信をmTLSで保護する方法などを紹介します。

6.3: SPIFFEによるアプリケーションの認証

SPIFFEの実装であるSPIREを使って、アプリケーションを認証・保護する方法を紹介します。

6.4: クラスタ外部との通信を守る

Nginx Ingress ControllerなどのIngressコントローラで、TLS通信を終端する方法を紹介します。

コラム

Open Policy Agent (OPA)など、本文で紹介しきれなった項目をコラムとして収録しています。

おわりに

私たちNTTは、コンテナやセキュリティなどに関するオープンソースコミュニティで共に活動する仲間を募集しています。ぜひ弊社 ソフトウェアイノベーションセンタ紹介ページや、採用情報ページをご覧ください。

--

--