Oracle Cloud Hangout Cafe Season5 #3「Kubernetes のセキュリティ」(2022年3月9日開催)

2023年4月18日(火)
市川 豊
連載第4回の今回は、2022年3月9日に開催された「Oracle Cloud Hangout Cafe Season5 #3『Kubernetes のセキュリティ』」の発表内容に基づいて紹介していきます。

Supply Chain Security

ここでは、コンテナイメージとセキュリティに焦点を当てます。

Trivy

コンテナの仕組み上、ホストカーネルを共有するため、脆弱性のあるイメージを利用してコンテナを起動するとホストカーネルおよび他のコンテナに影響が及ぶ可能性が高くなります。不特定多数の利用者が公開しているコンテナイメージレジストリ(パブリック)にあるコンテナイメージを利用する場合は注意が必要です。

利用するコンテナイメージに脆弱性がないことを事前に確認する必要があります。コンテナイメージの脆弱性診断を実行できるTrivyというOSSを利用して、コンテナを起動する前にコンテナイメージの脆弱性を事前に診断する過程を見ていきます。

1. Trivyとは?
Trivyは、コンテナイメージの脆弱性を静的に診断できるツールです。脆弱性データベースを軸にOSのパッケージ情報、アプリケーションの依存関係などから脆弱性を検出します。Aqua Security社がOSSとして公開しています。

ワンバイナリでインストールしやすく、操作性もシンプルで利便性があります。HarborというOSSのコンテナイメージレジストリにも脆弱性スキャン機能として実装されたり、アプリケーション開発では継続的インテグレーション(CI:Contiuous Integration)の工程で利用されるケースもあります。

2. Trivyによる脆弱性診断
Kubernetesクラスタ上で稼働しているPodから使用されているコンテナイメージを調べて、Trivyで脆弱性診断を実行してみます。

  1. Trivyのダウンロード
  2. 稼働しているPodのコンテナイメージを確認
  3. TrivyでスキャンをかけてHIGHとCRITICALが表示されるコンテナイメージを検出する

3. Trivyのダウンロード
Trivyのインストールスクリプトをダウンロードして、実行環境を構築します。

$ curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin v0.24.0

aquasecurity/trivy info checking GitHub for tag 'v0.24.0'
aquasecurity/trivy info found version: 0.24.0 for v0.24.0/Linux/ARM64
aquasecurity/trivy info installed /usr/local/bin/trivy

trivyコマンドを実行してバージョンを確認します。バージョンを表示できればTrivyが利用可能な状態です。

trivy -v

Version: 0.24.0

4. 稼働しているPodのコンテナイメージを確認
以下のマニフェストを適用して、3個のサンプルPodを稼働させます。

【マニフェスト:oraclelinux.yaml】
apiVersion: v1
kind: Pod
metadata:
  name: oraclelinux
spec:
  containers:
    - name: oraclelinux
      image: oraclelinux:8.5
      command:
        - sleep
        - infinity
$ kubectl apply -f oraclelinux.yaml

pod/oraclelinux created
【マニフェスト:ubuntu.yaml】
apiVersion: v1
kind: Pod
metadata:
  name: ubuntu
spec:
  containers:
    - name: ubuntu
      image: ubuntu:21.10
      command:
        - sleep
        - infinity
$ kubectl apply -f ubuntu.yaml

pod/ubuntu created
【マニフェスト:sample-go-app.yaml】
apiVersion: apps/v1
kind: Deployment
metadata:
  name: sample-go-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: sample-go-app
  template:
    metadata:
      labels:
        app: sample-go-app
    spec:
      containers:
      - name: sample-go-app
        image: <your-container-registry>/sample-go-app:arm
---
apiVersion: v1
kind: Service
metadata:
  name: sample-go-app-service
spec:
  type: ClusterIP
  ports:
  - name: sample-go-app-service
    protocol: TCP
    port: 80
    targetPort: 8080
  selector:
    app: sample-go-app
$ kubectl apply -f sample-go-app.yaml

deployment.apps/sample-go-app created
service/sample-go-app-service created

稼働状況を確認します。

$ kubectl get pods

NAME                             READY   STATUS    RESTARTS   AGE
oraclelinux                      1/1     Running   0          4m13s
sample-go-app-548b756854-7m4xr   1/1     Running   0          4m13s
ubuntu                           1/1     Running   0          4m13s

各Podが利用しているコンテナイメージを確認します。

$ kubectl get pods -o yaml | grep image:

      image: oraclelinux:8.5
      image: docker.io/library/oraclelinux:8.5
    - image: <your-container-registry>/sample-go-app:arm
      image: <your-container-registry>/sample-go-app:arm
    - image: nginx:1.21.5
      image: docker.io/library/nginx:1.21.5
    - image: nginx:1.21.5
      image: docker.io/library/nginx:1.21.5
      image: ubuntu:21.10
      image: docker.io/library/ubuntu:21.10

5. TrivyでスキャンをかけてHIGHとCRITICALが表示されるコンテナイメージを検出する

$ trivy image --severity HIGH,CRITICAL docker.io/library/oraclelinux:8.5

2022-03-03T07:16:28.996Z        INFO    Need to update DB
2022-03-03T07:16:28.998Z        INFO    Downloading DB...
29.73 MiB / 29.73 MiB [-----------------------------------------------] 100.00% 25.27 MiB p/s 1.4s
2022-03-03T07:16:36.774Z        INFO    Detected OS: oracle
2022-03-03T07:16:36.775Z        INFO    Detecting Oracle Linux vulnerabilities...
2022-03-03T07:16:36.781Z        INFO    Number of language-specific files: 0

docker.io/library/oraclelinux:8.5 (oracle 8.5)
==============================================
Total: 0 (HIGH: 0, CRITICAL: 0)

HIGHとCRITICALが0とあるので脆弱性はありません。

$ trivy image --severity HIGH,CRITICAL docker.io/library/ubuntu:21.10

2022-03-03T07:18:51.413Z        INFO    Detected OS: ubuntu
2022-03-03T07:18:51.414Z        INFO    Detecting Ubuntu vulnerabilities...
2022-03-03T07:18:51.417Z        INFO    Number of language-specific files: 0

docker.io/library/ubuntu:21.10 (ubuntu 21.10)
=============================================
Total: 0 (HIGH: 0, CRITICAL: 0)

これも、HIGHとCRITICALが0とあるので脆弱性はありません。

$ trivy image --severity HIGH,CRITICAL <your-container-registry>/sample-go-app:arm

2022-03-03T07:19:27.161Z        INFO    Detected OS: debian
2022-03-03T07:19:27.162Z        INFO    Detecting Debian vulnerabilities...
2022-03-03T07:19:27.167Z        INFO    Number of language-specific files: 1

<your-container-registry>/sample-go-app:arm (debian 11.2)
====================================================
Total: 4 (HIGH: 1, CRITICAL: 3)

+---------+------------------+----------+-------------------+---------------+------------------------------------------+
| LIBRARY | VULNERABILITY ID | SEVERITY | INSTALLED VERSION | FIXED VERSION |                 TITLE                    |
+---------+------------------+----------+-------------------+---------------+------------------------------------------+
| libc6   | CVE-2021-33574   | CRITICAL | 2.31-13+deb11u2   |               | glibc: mq_notify does                    |
|         |                  |          |                   |               | not handle separately                    |
|         |                  |          |                   |               | allocated thread attributes              |
|         |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2021-33574 |
+         +------------------+          +                   +---------------+------------------------------------------+
|         | CVE-2022-23218   |          |                   |               | glibc: Stack-based buffer overflow       |
|         |                  |          |                   |               | in svcunix_create via long pathnames     |
|         |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2022-23218 |
+         +------------------+          +                   +---------------+------------------------------------------+
|         | CVE-2022-23219   |          |                   |               | glibc: Stack-based buffer                |
|         |                  |          |                   |               | overflow in sunrpc clnt_create           |
|         |                  |          |                   |               | via a long pathname                      |
|         |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2022-23219 |
+         +------------------+----------+                   +---------------+------------------------------------------+
|         | CVE-2021-3999    | HIGH     |                   |               | glibc: Off-by-one buffer                 |
|         |                  |          |                   |               | overflow/underflow in getcwd()           |
|         |                  |          |                   |               | -->avd.aquasec.com/nvd/cve-2021-3999  |
+---------+------------------+----------+-------------------+---------------+------------------------------------------+

HIGH 1とCRITICAL 3とあるので脆弱性が見つかりました。それぞれの内容を確認して対処法を検討できます。この流れは手動による実行例ですが、継続的インテグレーション(CI:Contiuous Integration)の自動化に組み込むと、コンテナイメージのセキュリティを効率的に実現できます。

Monitoring / Logging and Runtime Security

これまで、Network Policy、RBAC、Pod Security Standardsなど、「誰が何をするか」を事前に定義することで制御する仕組みを紹介しました。ここでは、Kubernetesクラスタ上で「何が起きているのか」「何が起きたのか」を検知および追跡して原因を特定、制御する仕組みをFalcoというOSSをベースに解説します。

Falcoとは?

Falcoは、予期せぬアプリケーションの挙動を検知して、ランタイムレベルで脅威をアラートします。Sysdig社がOSSとして公開しています。主な特徴は以下です。

  • カーネルからのシステムコールを解析して、定義したルールに違反した意図しない振る舞いを検知
  • 設定された出力対象(Syslog、標準出力など)にアラートする
  • 何を実行したかなどを追跡して原因究明を支援

Falco Architecture

Falcoは、FALCO RULESに従って、フィルタリングされて違反がある場合はALERTINGからSyslogやStdoutなどに出力されます。

Falco Architecture

【出典】「Falco:Kubernetes runtime security with Falco and Sysdig

主なデフォルトルールセット

公式ドキュメントでは、主なルールセットとして以下が公開されています。

  • 特権コンテナを使用した特権のエスカレーション
  • setnsのようなツールを使ったネームスペースの変更
  • /etc, /usr/bin, /usr/sbinなどのよく知られたディレクトリへの読み込み/書き込み
  • シンボリックリンクの作成
  • 所有権とモードの変更
  • 予期しないネットワーク接続またはソケットの変異
  • execveを使ってプロセスをSpawnした
  • sh, bash, csh, zshなどのシェルバイナリの実行
  • SSHバイナリssh, scp, sftpなどを実行
  • Linuxのcoreutils実行ファイルを変異させる
  • ログインバイナリの変異
  • shadowutilやpasswdの実行ファイルを変異させる
    • shadowconfig
    • pwck
    • chpasswd
    • getpasswd
    • change
    • useradd

 など

【出典】「The Falco Project

Falcoによる違反検知

Kubernetesクラスタ上で稼働しているPod(コンテナ)でルール違反を発生させて検知できることを確認します。デモ環境において実施した概要としては、ノード(ホスト)の仮想マシンにFalcoをインストールし、httpdのPod(コンテナ)内で操作してSyslogの結果を確認します。

  1. ノード(ホスト)の仮想マシンでFalcoをインストール
  2. テスト用のPodを起動後、Pod(コンテナ)内およびノード(ホスト)で「/etc/」ディレクトリ内にファイル作成を試みる
  3. 「/var/log/syslog」のFalcoからの出力を確認する

1. ノード(ホスト)の仮想マシンでFalcoをインストール
Ubuntu LinuxにFalcoをインストールします。

$ curl -s https://falco.org/repo/falcosecurity-3672BA8F.asc | apt-key add -

OK

$ echo "deb https://download.falco.org/packages/deb stable main" | tee -a /etc/apt/sources.list.d/falcosecurity.list

deb https://download.falco.org/packages/deb stable main

$ apt-get update -y

$ apt-get -y install linux-headers-$(uname -r)

$ apt-get install -y falco

2. テスト用のPodを起動後、Pod(コンテナ)内およびノード(ホスト)で「/etc/」ディレクトリ内にファイル作成を試みる
マニフェストを適用します。

【マニフェスト:httpd.yaml】
apiVersion: v1
kind: Pod
metadata:
  labels:
    run: apache
  name: apache
spec:
  containers:
  - image: httpd:2.4.52
    name: apache
$ kubectl apply -f httpd.yaml

pod/apache created

Pod内のコンテナに接続して「/etc/」に「test.conf」というファイルを作成します。

$ kubectl exec -it apache  -- touch /etc/test.conf

ノード(ホスト)側で「/var/log/syslog」に出力されるFalcoのログを確認します。

$ cat /var/log/syslog | grep falco

エラーとして検出されています。

・
・(省略)
・
Mar  3 11:01:31 k8s-node-k-945573 falco: 11:01:31.183863989: Error File below /etc opened for writing (user=root user_loginuid=-1 command=touch /etc/test.conf parent=<NA> pcmdline=<NA> file=/etc/test.conf program=touch gparent=<NA> ggparent=<NA> gggparent=<NA> container_id=a723e15034a5 image=docker.io/library/httpd)
・
・(省略)
・

ノード(ホスト)側から「/etc/」に「test2.conf」作った場合も検出されます。コンテナの場合は「container_id」と「image」が記載されていましたが、ノード(ホスト)側で実施した場合は「container_id」は「host」、「image」は「NA」と表示されます。

・
・(省略)
・
Mar  3 11:11:57 k8s-node-k-945573 falco: 11:11:57.885578617: Error File below /etc opened for writing (user=root user_loginuid=1001 command=touch /etc/test2.conf parent=bash pcmdline=bash file=/etc/test2.conf program=touch gparent=sudo ggparent=bash gggparent=node container_id=host image=<NA>)
・
・(省略)
・

これは、Falcoの以下のルールに違反したことによる検出結果です。

$ vim /etc/falco/falco_rules.yaml
・
・(省略)
・
- rule: Write below etc
  desc: an attempt to write to any file below /etc
  condition: write_etc_common
  output: "File below /etc opened for writing (user=%user.name user_loginuid=%user.loginuid command=%proc.cmdline parent=%proc.pname pcmdline=%proc.pcmdline file=%fd.name program=%proc.name gparent=%proc.aname[2] ggparent=%proc.aname[3] gggparent=%proc.aname[4] container_id=%container.id image=%container.image.repository)"
  priority: ERROR
  tags: [filesystem, mitre_persistence]
・
・(省略)
・

運用では、モニタリングツールで対象のエラーメッセージを監視し、アラートを上げることで検知できます。

最後に補足ですが、Falcoは、ホストシステムまたはKubernetesにインストールする2通りの方法があります。侵害された場合、Kubernetesから分離するホストシステムへのインストールを最も安全な方法として公表しています。

【参考】「Falco Install

おわりに

今回は、2022年3月時点のCKSの範囲からピックアップして、Kubernetesセキュリティについて整理しました。もちろん、紹介したこと以外にもたくさんあります。発表時以降の傾向としては、Isovalent社が提供するeBPF(Extended Berkeley Packet Filter)をベースとしたセキュリティおよびオブザバビリティのプロダクトやオープンソースも注目されています。

  • Cilium CNI: eBPFをベースにコンテナ間通信を制御するCNIプラグイン
  • Cilium Service Mesh: envoyプロキシをノードに配置することによるSidecar-freeやIstioとの統合など
  • Hubble Timescope: CiliumとHubbleエージェントからの情報を基にサービス間通信の依存関係を可視化および分析
  • Tetragon: eBPFをベースとしたオブザバビリティとランタイムセキュリティの強化

Kubernetesに限らず、セキュリティは日々進化するので、情報をキャッチアップしながら対応を検討する姿勢が大切です。

日本オラクル株式会社

Oracle Groundbreaker Advocate
Principal Cloud Solution Engineer

これまで、インフラエンジニア、フロントエンドエンジニアとして官公庁のシステム基盤を中心としたサーバの設計構築、運用保守、Webシステム開発を担当。技術教育者として専門学校でクラウド技術やOSS(Linux、Docker、Kubernetes)の授業を担当し、企業様向けプライベートトレーニング講師も担当。 アドボケート/エバンジェリストとしてミートアップ、カンファレンスで登壇。現在は、クラウドネイティブ技術を中心とするソリューションエンジニアとして活動。クラウドネイティブ技術に関連するコミュニティの運営にも積極的に参加。

Community:
Oracle Cloud Hangout Cafe メンバー (#ochacafe)
CloudNative Days Tokyo 実行委員会メンバー (#CNDT)

Book:
著書「Dockerコンテナ開発・環境構築の基本」(インプレス)
共著「RancherによるKubernetes活用完全ガイド」(インプレス)、「コンテナ・ベース・オーケストレーション Docker/Kubernetesで作るクラウド時代のシステム基盤」(翔泳社)

連載バックナンバー

仮想化/コンテナ技術解説
第6回

Oracle Cloud Hangout Cafe Season6 #1「Service Mesh がっつり入門!」(2022年9月7日開催)

2023/6/22
連載第6回の今回は、2022年9月7日に開催された「Oracle Cloud Hangout Cafe Season6 #1『Service Mesh がっつり入門!』」の発表内容に基づいて紹介していきます。
仮想化/コンテナ技術解説
第5回

Oracle Cloud Hangout Cafe Season5 #5「実験! カオスエンジニアリング」(2022年5月11日開催)

2023/5/18
連載第5回の今回は、2022年5月11日に開催された「Oracle Cloud Hangout Cafe Season5 #5『実験! カオスエンジニアリング』」の発表内容に基づいて紹介していきます。
仮想化/コンテナ技術解説
第4回

Oracle Cloud Hangout Cafe Season5 #3「Kubernetes のセキュリティ」(2022年3月9日開催)

2023/4/18
連載第4回の今回は、2022年3月9日に開催された「Oracle Cloud Hangout Cafe Season5 #3『Kubernetes のセキュリティ』」の発表内容に基づいて紹介していきます。

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています