Azure Kubernetes Service で作る Intel SGX 環境
こんにちは、Acompany プロダクト部門 DCR チームのテックリード イナミです。
この記事は、Acompanyのバレンタインアドカレ 24日目の記事です。
今回は全くの未知だった Intel SGX や TEE について私からの視点で語っていこうかと思います。
Azure Kubernetes Service を使って Intel SGX による Remote Attestation を実演しようかと思ってました。
ただし難易度設定を間違えすぎた挙げ句には環境を用意するだけで手一杯だったので導入と Hello World ができるという着地点で簡単なドッグフーディングしてみます。
Intel SGX とは?
Acompany には Intel SGX の第一人者である aos さんがいらっしゃるので、彼の著作物を見てもらえると非常にわかりやすいです。
独立行政法人情報処理推進機構(IPA)のセキュリティキャンプ講師でもあるので、スライド等も公開してくださってます。
一部セキュリティキャンプ資料から引用させていただくと、Intel SGX は下記を実現することが出来ます。
TEE(Trusted Execution Environment; 信頼可能な実⾏環境)
ハードウェアの⼒を借りる事で、秘密情報を保護したまま計算に使⽤できる保護領域を実現できる技術
Intel SGX の難しさ
Acompany は日々秘密計算を含むプライバシーテックを研究開発し、さらに個人情報保護法など法律面もカバーしつつ顧客へ提供し続けています。
その中で Intel SGX に触れる機会もあるのですが、Intel SGX は一長一短に扱える代物ではない上に固有の非常に難しい課題がいくつもあります。
このままでは私では何もできません。。。
Remote Attestation 救世主現る
救世主が現れました。その名前は aos さんです。もう皆さんご存知でしたね!
私では語れないほどの数え切れない涙涙の日々を乗り越え、救世主は OSS を公開されました。
Intel SGX を用いた Web サービスを運用する難しさ
課題
大変な課題はいくつもあるのですがこの OSS を運用するとしても、そもそも Intel SGX 自体が CPU の特別な機能であり運用には下記手順が必ず必要になります。
- Intel SGX 対応の CPU が利用可能なマシンを準備する
- 大変時間がかかる SGX SDK のインストールを行う
(1時間くらいかかったりする😱😱😱) - OSS のサーバアプリケーション(ISV) を Intel SGX 実行環境上でビルドする
(ビルドに実行環境固有の値が用いるため、別のマシンでビルドしたものをデプロイに転用は不可😨) - ISV を通常の Web アプリケーションと同様に HTTPS でインターネットへ公開する
(ビルド専用環境と同じ環境上にデプロイするため、どうしてもアーキテクチャが複雑になりがちで愚直に作れない😫😫) - クライアントアプリケーションを適当にビルドしサーバと疎通確認する
(ビルドした際に生成された環境固有の設定値 MRENCLAVE をクライアント側に共有する必要があり、DNS名前解決等をするだけではダメ😭😭😭)
。。。簡単に書きましたが、まず手順が多すぎてやばいです。
どれくらいやばいかって?
5まで終わらないと本当に動作するかどうかがわかりません😭😭😭
つまりこのままで実運用するのは DevOps が全く出来ていないといってよい状態です。
課題の愚直な解消方法
もうこの時点でお腹いっぱいだと思いますが、私が理解している 運用上の課題の愚直な解消方法を書いてみます。
マシン用意
1 は有志(?)が公開している Intel SGX の対応ハードウェアとクラウドベンダサポートを見て選定を行います。
Humane-RAFW-MAA の場合は 導入 セクションをよく読んで対応すれば動くはずです。
SGX SDK インストール済みイメージの用意
2 はかなり困る問題ですが、Azure VM であれば VM をイメージとして保存したりすればショートカット可能です。
Acompany では現状この方法で対処しています。
サーバアプリケーションのビルド
3 は独特な仕様にはなりますが、デプロイするマシン上でビルドが可能であれば問題なさそうに見えます。
だたしデプロイするマシン上でビルドすることになるのであれば、手動で作業すると稼働中のアプリケーションの障害を人為的に引き起こしてしまう可能性があります。
しかし、この課題を解決するために CI/CD などで当たり前に使われるはずのビルド専用環境が愚直に作ることが出来ません😫😫😫
つまり同じマシンで稼働中のアプリケーションを壊さないように、横でビルドしデプロイし直す必要があります。
リリース作業はどんな場合でも大変コストがかかるものだと思っているので、切迫した状況でこのような作業は推奨されません。
いっそのことマシンから作り直したほうが早い、という話になります。
ここは DevOps でぜひ改善していきたい部分になります。
サーバアプリケーションのデプロイと疎通
4 までくれば少しは楽になりそう!と思いますね。
私も理解を深めるまではそう思っていました。
4,5 の問題点は、MRENCLAVE が変わってしまうことによる Blue/Green デプロイメントの難しさにあります。
Client-Server 型の Web アプリケーションは、後方互換性を保ちながらバージョンアップデートを行うことで、クライアント側の変更を最小限にすることが可能です。
スマホアプリで例えるならスマホアプリ自体のバージョンは更新せずとも、アプリの先にあるサーバアプリケーションのインターフェースが以前と変わらない場合は更新が可能になります。
参考までに、私が社内勉強会を行った資料等を貼っておきます。
しかしながら 3,4,5 をいい加減にしてしまうと MRENCLAVE という実行環境固有の値が変更されてしまうため、クライアントとタイミングを合わせて同期的にアップデートする必要があります。
これは私や Intel SGX をよく理解している方からすると信頼性を担保する上で必要な手順なのですが、一般の Web アプリケーションに慣れてしまった人からすると水平スケールができないので素直に受け入れにくい部分になってしまいます。
どうしても個人的に欲しい要素
個人的にどうしても欲しい要素は DevOps であり CI/CD です。
どのようなアプリケーションであっても E2E テストは個人的に必ず欲しいと思っています。
とはいえ サーバアプリケーションのデプロイと疎通 でも触れたように簡単に立ち上げることができないため、必然的に E2E テストも難しいことになります。
また「だったらビルドするたびに VM を立ち上げたりすればよいではないか」と言われてしまいそうですが、それはチームがスーパーマンばかりの場合に限定されてしまいますし DevOps としては推奨されないと思っています。
DevOps は下記を実現するためのアプローチであり、チームで効率的に開発と運用を進めていく上で絶対に無視できません。
- アプリケーションの開発者は機能開発と十分テストできる環境に集中したい
- 障害やトラブルが発生した場合に、開発者が稼働中のアプリケーションを触らず簡単に再現し修正したい
- インフラとアプリケーションを分けることによって問題の切り分け、運用を楽にしたい
どうすれば DevOps できるのか
真っ先に対応したい課題
まず全体的なイメージとして、今回運用で一番に解決したい部分は サーバアプリケーションのビルド だと思います。
サーバアプリケーションのビルド が仮想化されないうちに サーバアプリケーションのデプロイと疎通 のための CI/CD を考えることは難しいと思います。
PyCharm や IntelliJ IDEA を手掛ける JetBrains 社も CI/CD のベストプラクティスとしてコンテナ仮想化について触れています。
コンテナーを使用して環境をホストし、テストを実行すると、新しいデプロイメントのたびに環境をスピンアップしたり壊したりするのが簡単に行えます。Infrastructure-as-Codeアプローチを使えば、これらのステップをスクリプト化することができます。 毎回新しいコンテナーをインスタンス化することで、一貫性を確保し、より簡単に環境をスケーリングできるため、必要であれば複数のビルドを並行してテストすることが可能です。
Azure Kubernetes Service が使える
悩ましい問題ですが Azure Kubernetes Service を利用すれば解消できる可能性があります。
Azure Kuberentes Service では Kubernetes Node に Intel SGX が可能なマシンタイプを選択することが出来でき、公式ドキュメントにわかりやすくハンズオンが書かれています。
Azure Kubernetes Service を使ってなぜ DevOps できるのか?という話題については、Kubernetes で作る CI/CD 等の記事を読んでいただくと雰囲気がわかるかと思います。
Azure Kubernetes Service を使うとどうなるのか
課題の愚直な解消方法 と比較してどう変わるか書いてみます。
-
マシン用意
- Kubernetes を使えば Node としてスケールさせられるので、マシンの存在自体を意識せずに開発が行えるようになります。
- とはいえビルド時点と同じ CPU にデプロイしなければならないため、その場合は Node Affinity を使って解決します。
-
SGX SDK インストール済みイメージの用意
- コンテナイメージにできればベースイメージや拡張イメージを自由に作成できるようになります。
-
サーバアプリケーションのビルド
- ビルドするための Kubernetes Job 等を利用してデプロイする予定の Kubernetes Node 上でビルドできます。
- サーバアプリケーションのバイナリ等は Kubernetes PersistentDisk へ、MRENCLAVE 等の追加情報は Kubentes Secrets 等に保存し、必要な Pod にマウントすれば完了です。
-
サーバアプリケーションのデプロイと疎通
- Kubernetes 内部で疎通確認することもできますし、Kubernetes Secrets から MRENCLAVE 等を取得できれば外部公開も容易になります。
- kubectl 等の各種便利なコマンド群を使い放題になるため、port-forwarding なども可能になります。
- 本番デプロイではなくテスト用デプロイも容易になるので、E2E テストも全自動化が可能になります。
また DevOps とは少し違いますが、愚直に VM を並べ続けるよりも Kubernetes Node と Pod による水平スケールのほうが大変運用しやすいと思います。
このような点でも相性の良さが垣間見えると思います。
Azure Kubernetes Service と Intel SGX による Hello World
Terraform で Azure Kubernetes Service とその元となる VM を一撃デプロイできるようにしてみました。
解説
マシン用意
課題の愚直な解消方法 の マシン用意 については、Terraform Variables でマシンタイプが選べます。
私が動作確認済みであるマシンタイプは、
- SGX1 の場合は DCsv2 シリーズサイズ一覧 から選ぶ
- Scalable SGX の場合は DCdsv3 シリーズサイズ一覧 から選ぶ
ことができます。
DCscv2 シリーズは公式のドキュメントに対応可能と書かれています。
DCdsv3 シリーズについても公式のドキュメントに Azure CLI のみからですが対応可能と書かれていました。
また動作未確認ですが DCsv3 シリーズも同様でした。
Azure Kubernetes Service: サポートされています (CLI のプロビジョニングのみ)
デプロイ
terraform apply
していきます。
### clone
$ git clone https://github.com/ustato/SGX-Remote-Attestation-on-K8s
### terraform
$ cd SGX-Remote-Attestation-on-K8s/terraform
$ terraform init
### apply
$ terraform apply
### load kubeconfig
$ export KUBECONFIG=./azurek8s
動作確認
とりあえず Hello World するために Azure のドキュメントに従います。
実際のコードは Open Enclave プロジェクトの GitHub リポジトリにあります。
$ kubectl apply -f https://raw.githubusercontent.com/Azure-Samples/confidential-computing/main/containersamples/helloworld/helm/templates/helloworld.yaml
job.batch/oe-helloworld created
$ kubectl logs job/oe-helloworld
Hello world from the enclave
Enclave called into host to print: Hello World!
### 不要なので消しておく
$ kubectl delete -f https://raw.githubusercontent.com/Azure-Samples/confidential-computing/main/containersamples/helloworld/helm/templates/helloworld.yaml
job.batch "oe-helloworld" deleted
おわりに
Azure Kubernetes Service を使うことで Intel SGX を用いた Web サービスを運用する難しさが少し和らいだと思ってます。
急ピッチで記事化してしまったので、誤字脱字、動かないよ、などコメントあればお願いいたします。
Discussion