Oracle Cloud Hangout Cafe Season5 #3「Kubernetes のセキュリティ」(2022年3月9日開催)
Supply Chain Security
ここでは、コンテナイメージとセキュリティに焦点を当てます。
Trivy
コンテナの仕組み上、ホストカーネルを共有するため、脆弱性のあるイメージを利用してコンテナを起動するとホストカーネルおよび他のコンテナに影響が及ぶ可能性が高くなります。不特定多数の利用者が公開しているコンテナイメージレジストリ(パブリック)にあるコンテナイメージを利用する場合は注意が必要です。
利用するコンテナイメージに脆弱性がないことを事前に確認する必要があります。コンテナイメージの脆弱性診断を実行できるTrivyというOSSを利用して、コンテナを起動する前にコンテナイメージの脆弱性を事前に診断する過程を見ていきます。
1. Trivyとは?
Trivyは、コンテナイメージの脆弱性を静的に診断できるツールです。脆弱性データベースを軸にOSのパッケージ情報、アプリケーションの依存関係などから脆弱性を検出します。Aqua Security社がOSSとして公開しています。
ワンバイナリでインストールしやすく、操作性もシンプルで利便性があります。HarborというOSSのコンテナイメージレジストリにも脆弱性スキャン機能として実装されたり、アプリケーション開発では継続的インテグレーション(CI:Contiuous Integration)の工程で利用されるケースもあります。
2. Trivyによる脆弱性診断
Kubernetesクラスタ上で稼働しているPodから使用されているコンテナイメージを調べて、Trivyで脆弱性診断を実行してみます。
- Trivyのダウンロード
- 稼働しているPodのコンテナイメージを確認
- 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を稼働させます。
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: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の結果を確認します。
- ノード(ホスト)の仮想マシンでFalcoをインストール
- テスト用のPodを起動後、Pod(コンテナ)内およびノード(ホスト)で「/etc/」ディレクトリ内にファイル作成を試みる
- 「/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/」ディレクトリ内にファイル作成を試みる
マニフェストを適用します。
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に限らず、セキュリティは日々進化するので、情報をキャッチアップしながら対応を検討する姿勢が大切です。
連載バックナンバー
Think ITメルマガ会員登録受付中
全文検索エンジンによるおすすめ記事
- 「Inspektor Gadget」でKubernetesクラスタをデバッグする
- Kubernetesの基礎
- 認定Kubernetesアプリケーション開発者を目指そう!
- Oracle Cloud Hangout Cafe Season7 #1「Kubnernetes 超入門」(2023年6月7日開催)
- NGINX Ingress Controllerの柔軟なアプリケーション制御、具体的なユースケースと設定方法を理解する
- Kubernetes環境を構築して、実際にコンテナを動かしてみよう
- KubernetesのマニフェストをMagnumで実行する
- Oracle Cloud Hangout Cafe Season 4 #2「Kubernetesのネットワーク」(2021年5月12日開催)
- Kubernetes上のアプリケーション開発を加速させるツール(2) Telepresence
- kustomizeで復数環境のマニフェストファイルを簡単整理