3.6K Views
May 14, 21
スライド概要
SPIFFE Meetup Tokyo #3 の登壇資料です。
https://spiffe-jp.connpass.com/event/205213/
Yahoo! JAPANではサービス間通信のアクセス制御にAthenzが使われており、アクセス制御のためのIdentityとしてX.509証明書が利用できます。マイクロサービスを始めとする大量のワークロードが存在する環境では、X.509証明書やその秘密鍵の手動管理はセキュリティ面や運用コスト面で問題があります。Yahoo! JAPANでは証明書の自動配付を進めており、一部の本番環境向けにSPIREを採用しました。本セッションでは、SPIRE導入の背景から始まり、独自の実装についての話や、導入にあたってのSPIRE Serverの構成や課題など、それぞれの担当者から共有したいと思います。
Bio: 宇佐美 友也, 2016年よりゼットラボ株式会社に入社、現在はゼロトラストなセキュリティの実現にむけて研究開発に従事。SPIFFE/SPIREプロジェクトへ積極的に参加している。
2023年10月からSpeaker Deckに移行しました。最新情報はこちらをご覧ください。 https://speakerdeck.com/lycorptech_jp
Using SPIRE as Identity Provider for Athenz at Yahoo! JAPAN Deep Dive Into Architecture SPIFFE Meetup Tokyo #3 Tomoya Usami(@hiyosi), Z Lab Corporation
Outline ● ● ● ● ● ● ● ● ● ● Overview Node Attestation OpenStack IID Agent Operation Workload Attestation RegistrationEntry UpstreamAuthority Topology Considerations Opinion
Overview VM Policy Check Workload ※ Athenzを使ったアクセス制御は ローカルのキャッシュを参照する構成も可能 Athenz Fetch SVIDs via UNIX Domain Socket Policy Check SPIRE Agent Write IID Nova Compute Request IID NodeAttestor WorkloadAttestor SPIRE Server Node Attestation Request SVIDs Fetch JWK(s) NodeAttestor UpstreamAuthority Request CA Cert HashiCorp Vault IID API
DeepDive: Node Attestation ● OpenStack IIDを使ったNode Attestationのプラグインを実装 ○ ● ● NodeAttestor ‘openstack_iid’(OSS版とは別のもの) AgentはConfigDrive経由で渡されたIIDを取得してServerに送付 ServerはIID(JWT)の署名を検証し、X.509 SVIDを発行 SPIRE Agent Athenz(ZTS) SPIRE Server AttestAgent() Policy Check Agent IID API FetchAttestaionData() Request IID Nova Compute Create VM Write IID to ConfigDrive Server Attest() Plugin Plugin Read IID Verify IID IID API Fetch JWK(s)
DeepDive: Node Attestation ● IID APIはIIDの発行時、AthenzにPolicyを確認する ○ ● 対象インスタンスに対してX.509 SVIDの発行が許可されているか ConfigDriveに書き出されたIIDはNova APIの結果には含まれない ○ 対象のインスタンスのみが参照可 SPIRE Agent Athenz(ZTS) SPIRE Server AttestAgent() Policy Check Agent IID API FetchAttestaionData() Request IID Nova Compute Create VM Write IID to ConfigDrive Server Attest() Plugin Plugin Read IID Verify IID IID API Fetch JWK(s)
DeepDive: OpenStack IID
●
IID(JWT)はNode Attestationの有効期限を持つ
○
○
●
更新されない
期限内のNode Attestationが必要
ペイロードの例
{
"uuid":
"cluster_name":
"project_id":
"project_name":
"exp":
"athenz_domain":
"athenz_service":
...
VMに紐付くWorkload情報も含まれる
○
○
○
1VMでは1つのAthenz Serviceが動作する
利用者がVM作成時にメタデータとして指定
紐付けの正しさはIID作成時にAthenzのPolicyを確認
"e28a9443-ef3e-4f70-....",
"test-os-cluster",
"2a0acd9...",
"test-project",
4120383600,
"sports",
"backend",
}
●
Project ID x Instance IDでVMを識別
●
e.g. spiffe://example.org/agent/openstack_iid/2a0acd9…./e28a9443-ef3e-4f70-....
Yet Another OpenStack IID OpenStackのVendordata(Dynamic JSON)を 使った案も検討したが、YJでの採用は見送り cf. https://docs.google.com/document/d/1HkK3 Q74yYiqckBMI-h9FrZdlWEkrY5R4uHbXRqSRl W8/edit
DeepDive: Agent Operation ● 再起動時のRe-Attestationは禁止している ○ ○ ○ ● ReliabilityとSecurityのバランスが難しい ○ ○ ● 導入環境において、マウントしたIIDに対するアクセス制御が不十分 ■ Trust on First Use モデル ただし再起動時はVM再作成 or 取得済みSVIDの再利用が必要 SVIDを再利用する場合は秘密鍵の永続化が必要(KeyManager Plugin) 鍵を永続化する場合、より短期間でローテーションしたい SVIDが失効するとAgentの再起動はできないのでVMの作り直しが必要 SVIDのTTLとは別にローテーション周期を設定したい ○ ○ ○ 現状はTTLの1/2が経過したらローテーションで固定されている ReliabilityのためにTTLを大きくすると、ローテーションの頻度が低くなる https://github.com/spiffe/spire/issues/1754
DeepDive: Workload Attestation ● IIDに含まれるAthenzサービス情報(Workload情報)を使ったAttestation ○ ● WorkloadAttestor ‘openstack_iid’ IID置き換えに攻撃によるWorkload Attestationは成立しない ○ ○ RegistrationEntryと一致しないため、Workload Attestationは失敗する NodeのRe-Attestationは禁止 ※ 紐付くRegistrationEntryの中に 一致するSelectorがあるか確認 Check Entries (Workload Attestation) SPIRE Agent FetchX509SVID() Agent Workload Attest() - Make Selectors athenz_domain:xxx athenz_service:xxx Plugin Read IID
DeepDive: RegistrationEntry ● ○ ○ ○ ● SPIRE Server Entry作成に対してAdmin権限はToo Much 任意のSVIDを発行できたり、何でもあり 安全に配布する仕組みとか監査とか考えると管理が大変 Sync Entries Store Entries SVIDs CSRs CLIやUDS経由ならAdmin権限不要 ○ ○ ● スケジューラによる作成など、任意のタイミングで実施 Workload Attestationに間に合えばよい AgentによるEntryの同期 + SVID発行の時間も考慮する TCP経由でのEntry作成にはAdmin権限が付いたX.509 SVIDが必要 ○ ○ ○ ● Create Entries 動的にRegistrationEntryを作成する仕組みを用意 とりあえずNode AttestationのタイミングでEntryを作成するようにした 今回はIIDにWorkload情報が含まれていたり、基本的に変更されないので可能 SPIRE Agent (Workload Attestation) 将来的にはRBAC機能が実装されるかも ○ ○ ○ https://github.com/spiffe/spire/issues/1975 細かく権限を分割できると、TCP経由でのEntry作成も気軽にできるようになる RBAC機能が実装されたらEntry作成の仕組みは再設計したい Check Entries Fetch SVID SVID Workload
DeepDive: Upstream Authority ● 社内のPKIに合流させたい ○ ○ ○ ● HashiCorp Vault PKI Secret Engine ○ ○ ● 社内CA Issue CA Cert HashiCorp VaultをCAとして利用 中間CAの秘密鍵はVault内で生成され、外には出ない クレデンシャルなど秘密情報の保護 ○ ○ ○ ○ ● Athenzや他のプラットフォームとの互換性 社内CAとの間にHashiCorpt Vault (Enterprise)を挟んだ構成にした 社内CAの運用上の都合 PKI Secret Engineの利用には認証が必要 漏洩すると社内で利用可能な任意のX.509証明書が発行できてしまう SPIRE Serverを入室制限や情報持ち出しが困難なネットワークに隔離 AppRole Auth Methodの利用し、SecretやTokenはマイクロセグメントにバインド HashiCorp Vault Intermediate CA Issue CA Cert SPIRE Server内部のCAの秘密鍵 ○ ○ 現在はオンメモリで管理 内部のCAがHSMを使って証明書を発行できるようになるとよさそう ■ https://github.com/spiffe/spire/issues/525 SPIRE Server Intermediate CA Issue Leaf Cert (= X.509 SVID)
DeepDive: Topology GSLB Region B Region A L4 Load Balancer L4 Load Balancer Trust Domain: production.example.org SPIRE Server SPIRE Server SPIRE Server SPIRE Server HashiCorp Vault MySQL MySQL HashiCorp Vault Replication
DeepDive: Topology ● シンプルHA構成のSPIREをマルチリージョンに配置 ○ ○ ● TrustDomainは環境ごとに分割 ○ ○ ● 同じDatastoreを共有しているためRegionが異なっても同じTrust Domain RegionでDomain分けるとFederationが必要になってくる ■ 結局は同じTrust Bundleだが... L4 Load Balancerを使った負荷分散 ○ ○ ○ ● JWT SVIDは使わないのでNested SPIRE構成は必要ない、まずはシンプルな構成から ■ 今後、負荷が問題になってきたらNested SPIRE or Trust Domain分割などが必要になるかも 広域負荷分散で各Regionに振り分け SPIREではgRPCのコネクションは3min毎に作り直される DNSラウンドロビンだと、RPC単位で分散される 今回はGSLBの仕組みに関連してL4 Load Balancerを採用 HashiCorp Vault, MySQLはRegionを跨いでReplication ○ ○ HashiCorp Vault, MySQLともに社内のプラットフォームを利用 Vault Tokenはtoken_type=batchを設定
Considerations ● OpenStack NovaにおけるVMのRebuild (openstack server rebuild …) ○ ○ ● Agentのアップグレード ○ ○ ○ ● SPIRE Serverとのバージョン差異は1マイナーバージョンまで ■ https://qiita.com/ryysud/items/9575f08cd96936896eb0 利用者に依存する形でのバージョンアップは厳しいと感じている 最新に更新していくための仕組みを検討している ■ 自動アップグレードの仕組みの提供など Agent→Serverの通信量 ○ ○ ○ ○ ● VMのRebuildはInstanceのUUIDが同じものが再生成される Node Attestationにbuild毎に変わるパラメータを入れるなどの考慮が必要 Agentは定期的(5sec毎)に自分に紐付くRegistration Entryを取得する 紐付くEntryが多い場合や、Agentの数が多い場合は通信量が多くなる 今回の場合、紐付くEntryは基本変わらないのでSync Intervalを調整 ■ Experimental & Undocumented なパラメータなので利用は自己責任 SPIREでも通信量を減らす作業が行われており改善はされている ■ https://github.com/spiffe/spire/issues/2182 モニタリング ○ ○ Prometheusを使っているが、Metricsはまだこなれていない感じがある 今後フィードバックして改善していく必要がある
Opinion ● 運用自体は難しいものではない ○ ○ ● loginやexecが制限されているとつらいかも ○ ○ ● 基本的には自動で復旧する仕組みが組み込まれている PKIの基本的な知識は必要 CLIをつかった運用が制限されてしまう ■ 安全ではある 独自でWebベースの管理コンソール作ったりが必要になる ■ Admin SVID問題が出てくる 導入する場合はSPIRE Serverを適切に管理できるか検討する ○ ○ ○ 不正アクセスの防止 ■ 不正なCLI操作やAdmin SVIDによる操作 秘密情報の適切な管理 ■ Upstream AuthorityやNode Attestationのためのクレデンシャルとか 証明書有効期限やローテーション周期のバランス, キャパシティプランニング、リリース・アップグレード戦略 ■ 障害時の影響は大きい ■ Agent数、Agentに紐付くWorkload数の見積もり(RegistrationEntryの設計) ■ カナリアリリースやBlue Greenデプロイ
Q&A
Thank you!