SPIFFE Meetup Tokyo #1 - connpass https://spiffe-jp.connpass.com/event/126507/
SPIFFE Meetup #1 2019/05/14 @naokiainoyaSPIFFE in Action
View Slide
Naoki Ainoya / @naokiainoya▶ 基盤研究開発エンジニア@ZLab▶ “Kubernetes as a Service”に必要なインフラの開発に従事+ SPIFFE/SPIREへの取り組みはその仕事のひとつ
本⽇お話したいこと▶ SPIREͷ֓ཁ▶ SPIREͷߏཁૉ▶ SPIREͰSVIDΛൃߦ͢Δ·Ͱͷϑϩʔ▶ ZLabͰͷऔΓΈ+ SPIFFE/SPIREΛ༻ͨ͠OpenStackͰͷSecure Introductionͷ࣮▶ Further Challenges
SPIREの概要
SPIREとは▶ SPIFFEの参照実装+ https://github.com/spiffe/spire+ golangで書かれている▶ SPIFFE Workload APIを実装+ workloadを検証(attest)し、 SPIFFE IDとSVIDを発⾏する機能を持つ workload: コンテナやプロセスなどのソフトウェアシステムの実⾏単位
SPIREの構成概略▶ SPIRE ServerとAgentで構成+ Agentはworkloadが動作するNode毎に動作▶ SPIRE Server+ Registration API+ workloadの情報管理+ Node API+ SVIDへの署名▶ SPIRE Agent+ Workload API+ WorkloadへSPIFFE ID/SVIDを供給https://spiffe.io/spire/overview/
▶ Nodeの検証->Workloadの検証の2段階+ Workloadは検証済みのNode上でのみ検証可能▶ Workloadの検証にあたり、事前にworkload情報をServerに登録しておく必要があるNode/Workloadの検証(Attestation)のフロー1.Node AttestationNode Node2.WorkloadRegistration3.Workload Attestation
SPIREの主要機能▶ Node Attestation+ Nodeのアイデンティティ検証▶ Workload Registration+ Node上で動作するWorkloadのデータ登録▶ Workload Attestation+ Workloadのアイデンティティ検証1.Node Attestation2.WorkloadRegistration3.Workload Attestation
Node Attestation▶ Nodeのアイデンティティ検証+ インスタンスの「⾝元」が正しいかを確かめるプロセス▶ AWS上でのNode Attestationの例https://spiffe.io/spire/overview/
Node Attestation on AWS1. Agent(インスタンス)がインスタンスのアイデンティティを取得+ インスタンスアイデンティティ: AWSが署名したインスタンスのメタデータ https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/instance-identity-documents.htmlhttps://spiffe.io/spire/overview/
Node Attestation on AWS2. 取得したインスタンスアイデンティティをSPIRE Serverに送信https://spiffe.io/spire/overview/
Node Attestation on AWS3. インスタンスアイデンティティが正当なものか署名を検証https://spiffe.io/spire/overview/
Node Attestation on AWS4. 検証が成功したら、SPIRE ServerはインスタンスのSVIDを発⾏してNode Attestationは完了https://spiffe.io/spire/overview/
SPIREの主要機能1.Node Attestation2.WorkloadRegistration3.Workload Attestation▶ Node Attestation+ Nodeのアイデンティティ検証▶ Workload Registration+ Node上で動作するWorkloadのデータ登録▶ Workload Attestation+ Workloadのアイデンティティ検証
Workload Registration▶ Workloadの識別情報をRegistration Entryとして登録▶ SPIRE Serverがworkloadのアイデンティティを検証する際に利⽤CLIでエントリを作成する例Registration Entry
Registration Entryの中⾝▶ Workloadの識別情報をRegistration Entryとして登録▶ SPIRE Serverがworkloadのアイデンティティを検証する際に利⽤Registration Entryʹؚ·ΕΔ߲エントリ名 概要 例SPIFFE ID Workload⾃⾝のSPIFFE ID spiffe://example.org/workloadSelector Workloadのメタ情報(複数可)unix:user:nginxunix:path:/usr/bin/nginxParent ID親として紐付けたいエントリのSPIFFE IDSelectorの値が継承されるspiffe://example.org/my-cluster
Registration Entryの中⾝▶ Selectorはworkloadのメタ情報▶ Agentから送られてきたworkloadのselector情報と登録済み情報を照合し、SVIDの発⾏可否を判断Registration Entryʹؚ·ΕΔ߲エントリ名 概要 例SPIFFE ID Workload⾃⾝のSPIFFE ID spiffe://example.org/workloadSelector Workloadのメタ情報(複数可)unix:user:nginxunix:path:/usr/bin/nginxParent ID親として紐付けたいエントリのSPIFFE IDSelectorの値が継承されるspiffe://example.org/my-cluster
Workload Attestation▶ Attestation済のNodeで動作するWorkloadの検証▶ unixプロセスやコンテナなどの様々なworkloadにpluginで対応+ Workload plugin例+ K8s plugin+ Unix plugin+ Docker pluginhttps://spiffe.io/spire/overview/
UnixプロセスのAttestationのフロー1. Workloadが⾃⾝のSVIDをWorkload APIに要求+ Workload APIはUnixドメインソケットとして公開されておりそこにアクセスする形( Unix systemの場合)https://spiffe.io/spire/overview/Workload Attestationのフロー
2. Workload Attestorは呼び出し元のプロセスIDをUnix kernelに問い合わせhttps://spiffe.io/spire/overview/Workload Attestationのフロー
3. プロセスIDを元にWorkloadの情報を取得+ 取得する情報の例+ プロセスの実⾏ユーザ+ 実⾏バイナリのパス https://github.com/spiffe/spire/blob/master/doc/plugin_agent_workloadattestor_unix.mdhttps://spiffe.io/spire/overview/Workload Attestationのフロー
4. 取得したプロセスの情報をWorkloadのSelector情報として格納https://spiffe.io/spire/overview/Workload Attestationのフロー
5. WorkloadのSelector情報とSPIRE ServerのRegistration Entryを照合し、合致するSVIDをWorkloadに渡してAttestation完了+ AgentにはSVIDをキャッシュする機構が備わっており都度Serverに要求しなくてもいいようになっているhttps://spiffe.io/spire/overview/Workload Attestationのフロー
K8sのWorkload Attestation1. cgroupから得られるpod idと呼び出し元のpod idを照合2. Pod idをキーにしてkubeletにpodの情報を取得3. podの情報をworkloadのselector情報として格納 https://github.com/spiffe/spire/blob/master/doc/plugin_agent_workloadattestor_k8s.mdhttps://spiffe.io/spire/overview/Workload Attestationのフロー
SPIREの構成要素
SPIRE Serverの内部構成▶ 主要な機能がプラガブルになっており 利⽤する環境・使い⽅の差異を吸収+ AWS/GCP/Azure/https://spiffe.io/spire/overview/
SPIRE Serverを構成するプラグイン▶ Datastore+ Selectorのデータなどを永続化▶ KeyManager+ SVID署名時に利⽤する鍵ペアの管理▶ Upstream CA+ SVIDのCAを外部のPKI配下にする場合に 利⽤https://spiffe.io/spire/overview/
SPIRE Serverを構成するプラグイン▶ NodeAttestor+ Nodeの⾝元を検証する+ 例)GCPインスタンス⽤のプラグイン+ インスタンスIDトークンを検証し インスタンスのアイデンティティを 確認 https://github.com/spiffe/spire/blob/master/doc/plugin_agent_nodeattestor_gcp_iit.mdhttps://spiffe.io/spire/overview/
SPIRE Serverを構成するプラグイン▶ NodeResolver+ Nodeに紐づくメタデータを取得して Selectorとして格納する+ 例)AWS⽤のプラグイン+ インスタンスの各情報を取得+ セキュリティグループ名/ID+ タグ情報etc.. https://github.com/spiffe/spire/blob/master/doc/plugin_server_noderesolver_aws_iid.md https://spiffe.io/spire/overview/
SPIRE Agentの内部構成SPIRE Serverと同様プラガブルな設計▶ NodeAttestor▶ WorkloadAttestor▶ KeyManagerhttps://spiffe.io/spire/overview/
SPIRE Agentを構成するプラグイン▶ NodeAttestor+ ServerのNodeAttestorと同等+ ただし検証はせず、証明情報を取得してServerに送るのみ+ 検証はServer側で⾏われるhttps://spiffe.io/spire/overview/
SPIRE Agentを構成するプラグイン▶ WorkloadAttestor+ ワークロードの検証を⾏い、workloadにSVIDを発⾏する▶ KeyManager+ SVID⽣成時に使⽤する鍵ペアの管理https://spiffe.io/spire/overview/
SVID発⾏までのフローをまとめておさらい▶ SPIRE Server起動からWorkloadにSVIDを発⾏するまでの⼀連の流れをおさらいしてみます+ AWSでの流れを例にしていますhttps://spiffe.io/spire/overview/
SVID発⾏までのフロー1. SPIRE Server起動https://spiffe.io/spire/overview/
SVID発⾏までのフロー2. SVIDに署名するためのCA証明書を⽣成+ Upstream CA pluginを利⽤した場合は外部PKIから取得+ Upstream CA pluginを利⽤しない場合は⾃⼰証明書が使われるhttps://spiffe.io/spire/overview/
SVID発⾏までのフロー3. DataStoreを構成https://spiffe.io/spire/overview/
SVID発⾏までのフロー4. Registration APIを通じてWorkloadのEntryが登録可能になるhttps://spiffe.io/spire/overview/
SVID発⾏までのフロー5. Workloadが動作するインスタンスが起動。SPIRE Agentもその上で起動するhttps://spiffe.io/spire/overview/
SVID発⾏までのフロー6. Agentは⾃⾝の動作するNodeの⾝元を証明する情報としてインスタンスアイデンティティをServerに送信https://spiffe.io/spire/overview/
SVID発⾏までのフロー7. Serverは受信したインスタンスアイデンティティドキュメントの正当性をAWS APIに問い合わせつつ検証https://spiffe.io/spire/overview/
SVID発⾏までのフロー8. 検証に成功したら、インスタンスに紐づく追加情報を取得し、Selectorとして登録エントリを更新する+ セキュリティグループID+ インスタンスタグhttps://spiffe.io/spire/overview/
SVID発⾏までのフロー9. Node Attestationに成功したのでServerはAgentにSVIDを発⾏https://spiffe.io/spire/overview/
SVID発⾏までのフロー10.Workload Attestation開始。WorkloadはWorkload APIを呼び出してSVIDを要求するhttps://spiffe.io/spire/overview/
SVID発⾏までのフロー11.Workload AttestorはWorkloadのプロセスIDを取得12.プロセスIDをもとにプロセス情報(ユーザID,バイナリのパスetc..)をSelectorとして取得13.得られたWorkloadのSelectorと登録済みEntryを照合14.合致するSVIDをWorkloadに返却してWorkload Attestation完了https://spiffe.io/spire/overview/
Z Labでの取り組み
我々がSPIFFE/SPIREでまず実現したかったことOpenStack環境でも他のクラウドプラットフォーム同様、以下のことを実現したかった ▶ インスタンス(VM)のアイデンティティ検証▶ インスタンスへのシークレット導⼊(SecureIntroduction)の仕組み+ 既存のCIを経由したプロセスの改善+ SVIDを利⽤したSecure Introductionの実装
従来のSecure Introductionの問題▶ インスタンス構築時、ミドルウェアの動作に必要なシークレット情報をCI経由で渡していた▶ シークレット情報がCIマシンを経由する▶ CIマシンにシークレットが残るリスクがある+ 第⼆のシークレットストア化…
従来のSecure Introductionの問題▶ CIにインスタンス管理権限やシークレットへの管理権限が集中してしまっている
望ましいSecure Introductionのプロセス▶ シークレット情報をCIマシン経由にしない▶ インスタンスが直接Vaultからシークレットを取得できるようにしたい
Secure Introduction with SPIFFE/SPIRE▶ SPIREの機構を利⽤してOpenStackインスタンスのアイデンティティ検証を⾏う
SPIFFE/SPIREを使⽤したOpenStackでのSecure Introductionの実装
Secure Introduction構成の概要▶ OpenStackとSPIREの連携+ SPIREのNode Attestation機構でインスタンスのアイデンティティを検証▶ VaultとSPIREの連携+ JWT-SVIDでVault認証を⾏いシークレット取得
OpenStackとSPIREの連携OpenStack⽤のSPIRE Pluginを開発▶ NodeAttestor plugin+ openstack-iid-attestor▶ NodeResolver plugin+ openstack-iid-resolver
Openstack-iid-attestor▶ https://github.com/zlabjp/spire-openstack-plugin+ Attestation の際、OpensStack APIを利⽤しInstance IDとProject IDを照合
Openstack-iid-resolver▶ https://github.com/zlabjp/spire-openstack-plugin+ OpenStack APIからインスタンスメタデータ、セキュリティグループ情報を取得してSelectorとして保存
VaultとSPIREの連携▶ Spire-vault-plugin+ Upstream CA Plugin▶ Svid-verification-key-sync+ SPIREとVault間で認証情報を同期する仕組み▶ Secret-agent+ workloadの代⾏でVaultからsecretを取得する仕組み
Spire-vault-plugin▶ https://github.com/zlabjp/spire-vault-plugin▶ Upstream CA Plugin+ VaultのPKI Secret Engineを利⽤+ https://www.vaultproject.io/docs/secrets/pki/index.html+ SPIRE Serverが⾃⾝のCA証明書のCSRを作成し、Vaultに署名してもらう機構
Svid-verification-key-sync▶ (ソースコード⾮公開)▶ VaultのJWT Auth MethodとSPIREのJWT SVIDの認証⽤公開鍵を同期する機構+ x.509 SVIDとVaultのTLS Auth Methodを利⽤しないのは、x.509 SVIDのCommon Nameが設定されていない仕様だったためVault側の要求と噛み合わなかった+ (注)現在はx.509 SVIDのCommon Nameに値を設定できるようになっている https://github.com/spiffe/spire/pull/798SPIRE Server①JWT SVIDの公開鍵を JWT Auth Methodに 同期Workload②JWT SVIDで Vault認証できる
Svid-verification-key-sync▶ VaultのJWT Auth Methodに新しい拡張が⼊り、JSON Web Key Set (JWKS)を外部サーバに問い合わせできるようになった https://github.com/hashicorp/vault-plugin-auth-jwt/pull/43+ 今後は、この仕組みを使うように修正予定SPIRE Server+JWKS①JWT Auth Method認証時、公開鍵リストを照合Workload②JWT SVIDで Vault認証できる
Secret-agent▶ (ソースコード⾮公開)▶ ⾃⾝はWorkloadとして振る舞う▶ ⾃⾝のSVIDでVault認証を⾏い、必要なシークレットを取得
Further Challenges
Node Attestationのプロセスをより厳格に▶ 開発したOpenStack⽤のNodeAttestorは、現段階では厳密にインスタンスの⾝元を確認できていない+ インスタンスIDやProject IDを確認しているだけ▶ OpenStackはインスタンスの⾝元を証明する⽅法を提供していないのが根本原因+ AWSのインスタンスアイデンティティドキュメントやGCPのインスタンスIDトークンに相当する機構+ もしあれば教えてください
Node Attestationのプロセスをより厳格に▶ VendordataのDynamicJSONを使うと良さそう+ インスタンスのメタデータ作成時、外部サーバに問い合わせて動的にデータを作成する機能+ インスタンス情報への署名データを埋め込み、検証するサーバを⽤意すればよい署名Server2. インスタンスIDへの 署名を要求1. metadataサーバに 情報を要求VM3. 署名された アイデンティティ が⼊ったメタデータ を返却
SPIRE Server冗⻑化のためのDataStore探し▶ DataStoreプラグイン+ SQLite.PostgreSQL サポートがある▶ PostgreSQLを選択したとして、そのDBインスタンスのアイデンティティ検証ができない+ AWS,GCP..ならマネージドを使えばよいが…▶ DataStoreプラグインの⾃作を予定+ バックエンド案)Openstack Swift, etcd,Vault..SPIRE ServerTrusted DataStore?
まとめ
まとめ▶ SPIFFEの参照実装としてSPIREというものがある▶ インスタンスのアイデンティティの活⽤範囲は広い+ Z Labでの取り組みとして、Vaultと組み合わせたSecure Introductionを紹介+ SPIFFE ID/SVIDというユニバーサルな仕様の恩恵▶ エコシステムは発展途上+ プラグイン開発などを通じて積極的にSPIFFEコミュニティへ貢献していく
Appendix
参考⽂献▶ SPIFFE ‒ Secure Production Identity Framework for Everyone https://spiffe.io/spire/overview/+ SPIREの概要が⼀通り書かれている。このスライドのほとんどは本資料から引⽤▶ spire/SPIRE101.md at master · spiffe/spire https://github.com/spiffe/spire/blob/master/doc/SPIRE101.md▶ spire/doc at master · spiffe/spire https://github.com/spiffe/spire/tree/master/doc+ SPIREのプラグイン含めた実装に関するドキュメント群
参考⽂献▶ scytale.io https://blog.scytale.io/+ SPIFFE/SPIREプロジェクトに⼒を注いでいるscytale.io社のブログ▶ SPIFFE Community Day May 2019: Recap and Videos ‒ scytale.io https://blog.scytale.io/spiffe-community-day-may-2019-recap-and-videos-61a672e0c728+ SPIFFEのイベントが定期的に開催されている。プロジェクトの動向を知りたい場合におすすめ。ネット中継あり