5分でわかる!Kubernetes/CloudNative Topics

Cilium Projectから公開! eBPFを用いてセキュリティの可観測性をもたらすTetragon

こんにちは。サイバーエージェントの青山真也@amsy810です。

弊社のインフラ組織 CIU(CyberAgent group Infrastructure Unit)では、Kubernetesを用いて、⁠Kubernetes as a Service基盤」「ML Platform」を実装・運用しています。そんなチームのメンバーで今月から、KubernetesやCloudNative関連の注目している技術や実際に利用しているプロダクトについて紹介していきます。

第1回目は、2022年初の新春企画で取り上げたeBPF関連のプロダクトでもあるTetragonについて紹介します。

eBPFとは?

eBPFは、カーネルのソースコードの変更なしに任意のプログラムをカーネルに組み込み、カーネル空間で任意の処理を実行するための仕組みです。CNCFのプロジェクトでは、Cilium・Calico・Falco・Pixieなどで利用されています。

また、eBPFプログラムをKubernetesノードに組み込む形をとることで、そのノード上のすべてのコンテナに対して様々な制御を行えるほか、アプリケーションやマニフェストの変更・Sidecarの利用をせずに様々なことが実現できるようになります。

Tetragonとは?

TetragonはCilium Projectで作られているOSSで、⁠セキュリティの可観測性」「リアルタイムの実行時制御(Enforcement⁠⁠」を実現します。Tetragonは内部でeBPFを利用しており、低オーバーヘッドかつ、カーネルの安定性を損なわずにカーネルレイヤの情報を収集できます。

参考情報eBPF自体の詳細についてはゆううきさんのブログが参考になります。

Tetragonでは、プロセス実行・システムコールの呼び出し・ネットワークやファイルI/Oなどのイベント情報を検出し、ログ・メトリクスの出力やリアルタイムの実行時制御(Enforcement)などが可能です。さらに、KubernetesのPod情報・ラベル・Namespace・コンテナイメージ名などの様々なメタデータとイベントが紐付けられるため、マイクロサービスアーキテクチャなどで複雑化した環境下でも柔軟なポリシー定義や情報収集が可能になっています。そのため、Tetragonが検知したセキュリティイベントをSecurity Information and Event Management(SIEM)にエクスポートすることで、セキュリティ担当者はKubernetesクラスタで起きている様々なイベントを追跡でき、セキュリティに関する意思決定を行うことができます。

図1 Tetragonのアーキテクチャ(TetragonのGitHubページより)
図1

また、Tetragonは2022年5月に公開されたOSSですが、数年前からIsovalent Cilium Enterpriseの機能として提供されており、すでに一定の実績があります。Tetragonの開発を主導しているIsovalent社は、Tetragon以外にもCNI(Container Network Interface)Ciliumやリアルタイムネットワーク可視化のHubbleなど、eBPFを用いた様々なOSSの開発を主導している企業であり、ソフトウェアの安定性についても信頼できます。

The Four Golden Signals of Security Observbability

少しセキュリティに関する可観測性自体について振り返ってみましょう。

Isovalent社が発行している「Security Observability with eBPF」によると、コンテナのセキュリティ可観測性のための4つのゴールデンシグナルは次の4つであると定義しています。

  • プロセス実行
  • ネットワークソケット(TCP・UDP・Unix)
  • ファイルアクセス
  • L7ネットワークアイデンティティ

これらのシグナルを適切に記録しておくことで、侵害の検出・影響範囲の特定が可能です。TetragonではこれらのシグナルをKubernetesのメタデータと紐付けて記録できます。

Tetragonのポリシー設定とeBPF

Tetragonのデフォルト動作ではプロセス実行のシグナルを記録するようになっています。それ以外のシグナルに関しては、TracingPolicy CustomResorceで挙動を設定します。TracingPolicy CustomResourceには大きく分けて「kprobes」「tracepoints」の2つのフィールドがあり、以下のそれぞれのポイントでeBPFプログラムをロードします。

kprobe
任意の関数・システムコールに対してフックポイントを設定し検知するための設定
tracepoints
Linux カーネルに予め定義されたフックポイントで検知するための設定

参考情報kprobes/tracepoints自体の詳細についてはこちらのブログが参考になります。

例えば、TCP接続を検知するためのTracingPolicyはkprobeを用いて以下のように記述します。これにより、tcp_connecttcp_closetcp_sendmsgなどのカーネル関数が実行されたタイミングでTetragonがイベントを検知します。なお、カーネル関数の引数の情報を記録する場合にはargsフィールドで指定します。例えば、tcp_sendmsg関数のシグネチャはint tcp_sendmsg(struct sock *sk, struct msghdr *msg, size_t size)のようになっており、下記の例ではsk(index: 0)size(index: 2)の情報を記録するようにしています。

# https://raw.githubusercontent.com/cilium/tetragon/main/crds/examples/tcp-connect.yaml
apiVersion: cilium.io/v1alpha1
kind: TracingPolicy
metadata:
 name: "connect"
spec:
 kprobes:
 - call: "tcp_connect"
   syscall: false
   args:
   - index: 0
     type: "sock"
 - call: "tcp_close"
   syscall: false
   args:
   - index: 0
     type: "sock"
 - call: "tcp_sendmsg"
   syscall: false
   args:
   - index: 0
     type: "sock"
   - index: 2
     type: int

こうしたポリシーが定義されたKubernetesクラスタ上で、コンテナからcurlコマンドなどを実行すると、tcp_sendmsg関数が実行されたタイミングでイベントをログから確認することができます。イベント情報には、Kubernetes関連のメタデータや、事前に定義したargsのsocket情報とsizeも記録されています。

図2 Tetragonが出力するイベントログ
図2

同様にファイルアクセスなどに対しても、特定の関数に対するポリシーを設定することで記録できます。ファイルI/Oを行う関数に渡るコンテンツ自体の引数(文字列バッファなど)を記録するようにしておくことで、Read/Writeされたデータ全体を記録することも可能です。

なお、公式ブログによると、これらのポリシーは「TracingPolicy CustomResource」以外にも「Open Policy Agent」⁠JSON」など様々なソースからインポート可能になる想定のようです。

Tetragonのイベント情報と外部連携

上記の例のように、Tetragonにおいては検知したイベントは構造化されたデータとして出力されます。大きく分けて4種類に分類されています。現時点ではドキュメントなどを見る限りはログとして集約するという形を想定しているようです。

  • process_exec / process_exit: プロセスが実行 / 終了された際のイベント情報
  • process_kprobe: プロセスがカーネル関数を呼び出した際のイベント情報
  • process_tracepoint: プロセスがカーネルのtracepointに到達した際のイベント情報

Tetragonはノードごとに起動しているAgent単位にイベントを生成・実行時制御するため、比較的スケーラブルな作りになっています。負荷が集中する部分といえば、収集されたイベント情報を集約する部分になってくるでしょう。

図3 Agent単位にイベントを生成・実行時制御する
図3

現在Tetragonでエクスポートされているメトリクスは、Tetragon内部で使われているリングバッファの状況・エラーカウントといったTetragon自体のシステムメトリクスのみで、ポリシーごとのメトリクスはエクスポートされていないようです。

また、これらのログを人が読みやすいように整形するツールとしてtetragon CLIが提供されています。tetragon CLIを使うと特定のNamespaceやPodのみにするフィルタリングも可能です。

$ cat output.log | tetragon observe -
🚀 process default/xwing /usr/bin/curl http://cilium.io
📬 open    default/xwing /usr/bin/curl /etc/ssl/openssl.cnf
📪 close   default/xwing /usr/bin/curl
📬 open    default/xwing /usr/bin/curl /etc/hosts
📪 close   default/xwing /usr/bin/curl
📬 open    default/xwing /usr/bin/curl /etc/resolv.conf
📪 close   default/xwing /usr/bin/curl
🔧 tcp_connect default/xwing /usr/bin/curl 10.4.2.8:20117 -> 104.198.14.52:80
⁉️ syscall default/xwing /usr/bin/curl tcp_sendmsg
⁉️ syscall default/xwing /usr/bin/curl tcp_close
💥 exit    default/xwing /usr/bin/curl http://cilium.io 0

リアルタイムの実行時制御(Enforcement)

TetragonではTracingPolicyのactionにSigkillが指定されている場合、定義されたポリシーに合致した場合にそのプロセスを停止する実行時制御(Enforcement)を行うことができます。この実行時制御はカーネル内で同期的に実施されるため、ポリシーに合致した時点でそのプロセスを停止して処理の実行を防ぎます。

プロセスを停止させる際はロードされたeBPFプログラムからsend_signal eBPF helper functionを使ってプロセスにSIGKILLを送信します。eBPFを使って、イベント検知だけでなくカーネル空間からSIGKILLを送る点もTetragonの特徴のひとつです。

こうした挙動を実現するために、TetragonではTracingPolicyをもとにルールごとにeBPFプログラムを生成し、cilium/epbfを使って動的にロードする形をとっています。

apiVersion: cilium.io/v1alpha1
kind: TracingPolicy
metadata:
 name: sigkill-test
spec:
 kprobes:
 - call: "fd_install"
   syscall: false
   selectors:
    matchActions:
    - action: Sigkill
    

類似プロダクト - Falco / Tracee

最後に同等のことを実現する手法と、類似プロダクトについて紹介します。

eBPFを利用した手法以外には、アプリケーション側に特定のライブラリを組み込んだり、ptraceを利用したり、seccomp/SELinuxを利用したり、カーネルモジュールを利用したりする手法があります。これらの手法はアプリケーションから見て透過的に導入できなかったり、オーバーヘッドが大きかったり、Kubernetesのメタデータを元にした柔軟なポリシーが適用できなかったり、カーネルの安定性が低下したり、様々な問題がありました(それぞれの比較はWhy Tetragon?を参照⁠⁠。

Tetragonと類似したeBPFを利用してセキュリティの可観測性を実現するプロダクトは、他にも「Falco」「Tracee」などがあります。それぞれのプロダクトで、取得できる範囲の差・外部連携の豊富さ・リアルタイムでの実行時制御の有無など、できることが若干異なります。

FalcoはもともとはSysdigが開発したプロダクトでしたが、現在はeBPF ProbeやライブラリなどのコアコンポーネントがCNCFに寄贈されています。Falcoはカーネルモジュールを利用してイベントを収集していましたが、カーネルへの安定性などの理由からeBPF Probe版が作られました。Falcoはプリセットのルールセットが提供されている点が良い点で、商用版のSysdig Secureだとより多くのポリシーが提供されていそうです。

TraceeはAqua Securityが開発しているプロダクトで、同様にeBPF Probeを利用してイベント情報を収集しています。

まとめ

Tetragonの強みは、リアルタイムの実行時制御(Enforcement)をeBPFを用いてカーネルレイヤーで行う点です。一方で、出力されたメトリクスやイベントなどの外部連携やドキュメント、プリセットのルールなどはまだ整備しきれていないので、このあたりは将来が楽しみですね。

他にも、Cilium v1.12.1時点では実装はまだされていませんが、CiliumNetworkPolicyで実行されるプロセスの情報を元にしたアクセス制御などの実装も検討されているようです。これにより、特定のバイナリから特定の権限での接続のみを許容するといった、よりきめ細やかなネットワーク制御なども可能になりそうです。

Cilium Projectでは、それぞれCilium・Hubble・Tetragonなど、Networking・Observability・Securityといった多方面に対してeBPFを使ったプロダクトを提供しています。今後もTetragonをはじめとする、Cilium ProjectのeBPF on Kubernetesには期待しています。

参考文献

おすすめ記事

記事・ニュース一覧