如何證明你是你 - SPIFEE

Abstract 如何證明你是你
Authors Walter Fan
Category learning note
Status v1.0
Updated 2025-01-18
License CC-BY-NC-ND 4.0

如何證明你是你 - SPIFEE

在數(shù)字世界里,證明“你是你”這個(gè)問(wèn)題聽起來(lái)有點(diǎn)像哲學(xué)問(wèn)題,但實(shí)際上,它是現(xiàn)代軟件架構(gòu)中的一個(gè)核心挑戰(zhàn)。想象一下,你是一個(gè)微服務(wù),每天要和成千上萬(wàn)的其他微服務(wù)打交道,每個(gè)服務(wù)都需要確認(rèn)你的身份,確保你不是一個(gè)冒名頂替者。

SPIFFE 就是這樣解決“如何證明你是你”問(wèn)題的協(xié)議, 如果你只在一個(gè)云環(huán)境中, 傳統(tǒng)的 AWS IAM 可以解決身份認(rèn)證的問(wèn)題, 而在多種不同的混合云 (公有云, 私有云, 不同的云提供商) 環(huán)境中,SPIFFE 就可以解決統(tǒng)一身份認(rèn)證的問(wèn)題, 有點(diǎn)象護(hù)照, 比身份證更通用, 可以跨國(guó)認(rèn)證你就是你.

1. 你是誰(shuí)?— 身份認(rèn)證的挑戰(zhàn)

在分布式系統(tǒng)中,每個(gè)服務(wù)都需要證明自己的身份。這就像你去參加一個(gè)派對(duì),門口的保安會(huì)問(wèn)你:“你是誰(shuí)?”如果你能出示一張有效的身份證,保安就會(huì)讓你進(jìn)去。在數(shù)字世界里,這張“身份證”就是你的身份憑證。

例如 AWS IAM(Identity and Access Management)是亞馬遜云服務(wù)提供的一個(gè)強(qiáng)大的身份和訪問(wèn)管理工具。它允許你創(chuàng)建和管理用戶、組和角色,并控制他們對(duì) AWS 資源的訪問(wèn)權(quán)限。簡(jiǎn)單來(lái)說(shuō),IAM 就是 AWS 的“保安”,它負(fù)責(zé)驗(yàn)證你的身份,并決定你能做什么。

在 AWS 中,實(shí)例(Instance)和應(yīng)用程序(Application)身份認(rèn)證是通過(guò)多種機(jī)制來(lái)實(shí)現(xiàn)的,其中最重要的兩個(gè)是 IAM RolesAWS Security Token Service (STS)

它的具體實(shí)現(xiàn)方法和機(jī)制主要是通過(guò) AWS IAM Role 和 AWS Security Token Service:

AWS IAM Role

它是一種用于委托權(quán)限的 AWS 資源,允許 EC2 實(shí)例或其他 AWS 服務(wù)在不需要硬編碼憑據(jù)的情況下訪問(wèn) AWS 資源。

工作原理:

  • IAM Role 的創(chuàng)建:管理員在 AWS IAM 中創(chuàng)建一個(gè)角色,定義允許的權(quán)限(通過(guò) IAM 策略)。
  • 實(shí)例配置角色
    • 啟動(dòng) EC2 實(shí)例時(shí),關(guān)聯(lián)一個(gè) IAM Role。
    • 或在實(shí)例啟動(dòng)后,通過(guò) AWS CLI 或 SDK 將角色附加到實(shí)例。
  • 元數(shù)據(jù)服務(wù)提供臨時(shí)憑證
    • 實(shí)例訪問(wèn) http://169.254.169.254/latest/meta-data/iam/security-credentials/<role-name> 獲取臨時(shí)憑證。
    • 這些憑證包括 Access Key ID、Secret Access KeySession Token,并具有短時(shí)間有效期(默認(rèn) 6 小時(shí),可配置)。

優(yōu)勢(shì):

  • 無(wú)需將 AWS 憑證硬編碼在代碼中。
  • 臨時(shí)憑證會(huì)自動(dòng)輪換,降低憑證泄露風(fēng)險(xiǎn)。
  • 細(xì)粒度權(quán)限控制(通過(guò) IAM 策略)。

AWS Security Token Service (STS)

它提供臨時(shí)安全憑證,用于跨賬戶、跨區(qū)域或在有限時(shí)間內(nèi)訪問(wèn) AWS 服務(wù)。

使用場(chǎng)景:

  • EC2 實(shí)例或 Lambda 函數(shù)需要臨時(shí)訪問(wèn)權(quán)限。
  • 跨賬戶訪問(wèn) AWS 資源。
  • 使用聯(lián)合身份(如 SAML 或 OpenID Connect)訪問(wèn) AWS。

工作流程:

  1. 應(yīng)用程序使用 AWS SDKAWS CLI 調(diào)用 AssumeRoleAssumeRoleWithWebIdentity API。
  2. STS 返回一組臨時(shí)憑證(Access KeySecret KeySession Token)。
  3. 應(yīng)用程序使用這些憑證調(diào)用 AWS 服務(wù)。
  4. 憑證會(huì)在指定時(shí)間后過(guò)期(默認(rèn) 1 小時(shí))。

2. 你是你嗎?— SPIFFE 的登場(chǎng)

雖然 IAM 在 AWS 生態(tài)系統(tǒng)中非常強(qiáng)大,但在跨云或混合云環(huán)境中,IAM 就顯得有些力不從心了。這時(shí)候,SPIFFE(Secure Production Identity Framework for Everyone)就登場(chǎng)了。

SPIFFE(Secure Production Identity Framework for Everyone)是一個(gè)開源框架,旨在為分布式系統(tǒng)中的服務(wù)提供可驗(yàn)證的身份。它的核心組成包括:

SPIFFE ID

它定義了一種機(jī)制,使得服務(wù)能夠在不依賴傳統(tǒng)憑據(jù)(如密碼或 API 密鑰)的情況下,證明它們的身份并進(jìn)行相互認(rèn)證。
類似于身份證的唯一標(biāo)識(shí)符,例如:spiffe://example.org/service-a。
每個(gè) Workload 工作負(fù)載(比如一個(gè)微服務(wù))都可以擁有一個(gè)唯一的身份標(biāo)識(shí)符 - SPIFFE ID。

SPIFFE 提供了以下主要功能:

  • 統(tǒng)一身份表示:通過(guò) URI(如 spiffe://example.org/service-name)表示身份。
  • 身份驗(yàn)證:支持基于證書的互相驗(yàn)證,而無(wú)需共享密碼或其他敏感憑據(jù)。

SVID(SPIFFE Verifiable Identity Document)

SVID(SPIFFE Verifiable Identity Document) 可驗(yàn)證身份文檔是 SPIFFE 的身份實(shí)現(xiàn),它是服務(wù)的身份憑證。SVID 通常由 X.509 證書形式表示,包含以下內(nèi)容:

  • SPIFFE ID:存儲(chǔ)在證書的 Subject Alternative Name (SAN) 字段中,表示服務(wù)的身份。
  • 公共密鑰:用于加密和簽名,保證通信安全。
  • 有效期:定義身份的生效和失效時(shí)間。

在分布式環(huán)境中,SVID 用于在服務(wù)間進(jìn)行安全通信??梢詫?SVID 類比為情報(bào)機(jī)構(gòu)頒發(fā)的“特工證”:

  • SPIFFE ID 是特工的“身份號(hào)碼”,存儲(chǔ)在證書中。
  • 私鑰和公鑰 是特工的“密鑰對(duì)”,用于加密信息和簽名。
  • 有效期 就像特工證的“過(guò)期日期”,超過(guò)時(shí)間后必須更新。

通過(guò)這種設(shè)計(jì),所有特工(服務(wù))可以通過(guò) SVID 相互識(shí)別并安全通信,而無(wú)需依賴傳統(tǒng)的“暗號(hào)”或密碼。這種機(jī)制在現(xiàn)代分布式系統(tǒng)中尤其重要,用于構(gòu)建零信任安全模型。

信任域(Trust Domain)

一組共享信任的服務(wù),通常通過(guò)一個(gè)共同的根證書(Root Certificate)管理。

SPIFFE 的核心目標(biāo)是確保服務(wù)之間的身份認(rèn)證不依賴固定的網(wǎng)絡(luò)配置或共享密鑰。

3. 如何證明你是你?— AWS IAM 與 SPIFFE 的結(jié)合

現(xiàn)在,我們來(lái)看看如何將 AWS IAM 和 SPIFFE 結(jié)合起來(lái),解決“如何證明你是你”的問(wèn)題。

步驟 1:創(chuàng)建 IAM 角色

首先,你需要在 AWS IAM 中創(chuàng)建一個(gè)角色,并為這個(gè)角色分配適當(dāng)?shù)臋?quán)限。這個(gè)角色將代表你的微服務(wù)在 AWS 中的身份。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::my-bucket/*"
    }
  ]
}

步驟 2:生成 SPIFFE ID

接下來(lái),你需要為你的微服務(wù)生成一個(gè) SPIFFE ID。這個(gè) ID 通常是一個(gè) URI,格式如下:

spiffe://example.org/my-service

步驟 3:將 SPIFFE ID 與 IAM 角色關(guān)聯(lián)

現(xiàn)在,你需要將 SPIFFE ID 與 IAM 角色關(guān)聯(lián)起來(lái)。這可以通過(guò) AWS IAM 的 AssumeRole 操作來(lái)實(shí)現(xiàn)。具體來(lái)說(shuō),你可以創(chuàng)建一個(gè)信任策略,允許具有特定 SPIFFE ID 的實(shí)體(即你的微服務(wù))來(lái)扮演這個(gè) IAM 角色。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Federated": "spiffe://example.org/my-service"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

步驟 4:驗(yàn)證身份

當(dāng)你的微服務(wù)需要訪問(wèn) AWS 資源時(shí),它會(huì)使用 SPIFFE ID 來(lái)請(qǐng)求一個(gè)臨時(shí)的安全令牌。AWS IAM 會(huì)驗(yàn)證這個(gè) SPIFFE ID,并生成一個(gè)臨時(shí)的訪問(wèn)令牌。這個(gè)令牌可以用來(lái)訪問(wèn) AWS 資源,比如 S3 存儲(chǔ)桶。

import boto3

# 使用 SPIFFE ID 請(qǐng)求臨時(shí)安全令牌
sts_client = boto3.client('sts')
response = sts_client.assume_role_with_web_identity(
    RoleArn='arn:aws:iam::123456789012:role/my-role',
    RoleSessionName='my-service',
    WebIdentityToken='spiffe://example.org/my-service'
)

# 使用臨時(shí)令牌訪問(wèn) S3
s3_client = boto3.client(
    's3',
    aws_access_key_id=response['Credentials']['AccessKeyId'],
    aws_secret_access_key=response['Credentials']['SecretAccessKey'],
    aws_session_token=response['Credentials']['SessionToken']
)

# 獲取 S3 對(duì)象
response = s3_client.get_object(Bucket='my-bucket', Key='my-key')
print(response['Body'].read())

實(shí)際應(yīng)用中, 我們可能需要 AWS Identity and Access Management (IAM) Roles Anywhere,
這個(gè)工具允許用戶的本地服務(wù)器或外部環(huán)境(如私有云、數(shù)據(jù)中心)使用 IAM 角色 授權(quán)訪問(wèn) AWS 服務(wù),而無(wú)需在這些環(huán)境中存儲(chǔ)長(zhǎng)期憑證(如訪問(wèn)密鑰和密鑰對(duì)):

    1. 配置信任關(guān)系 Trust Relationships

用戶在 AWS 中創(chuàng)建 IAM 角色,并允許 AWS Roles Anywhere 假設(shè)該角色(AssumeRole)。

    1. 配置信任錨點(diǎn) Trust Anchors

信任錨點(diǎn)是 AWS Roles Anywhere 用來(lái)驗(yàn)證外部環(huán)境的公鑰證書(通常由認(rèn)證機(jī)構(gòu) CA 簽發(fā)的 X.509 證書)。
用戶將 CA 的根證書上傳到 AWS Roles Anywhere 作為信任錨點(diǎn)。

    1. 客戶端憑證請(qǐng)求 Client Certificates

本地服務(wù)器或外部系統(tǒng)使用其簽名的證書,向 Roles Anywhere 服務(wù)請(qǐng)求臨時(shí)憑證。

    1. 頒發(fā)臨時(shí)憑證 Generate Temporary Credentials

Roles Anywhere 驗(yàn)證證書和信任錨點(diǎn),確定請(qǐng)求者身份。
根據(jù)配置的 IAM 角色和策略,生成臨時(shí)憑證(Access Key、Secret Key 和 Session Token)。

    1. 訪問(wèn) AWS 服務(wù)

臨時(shí)憑證被返回給本地服務(wù)器, 一般包括 Access Key、Secret Key 和 Session Token。
本地服務(wù)器使用這些憑證訪問(wèn) AWS 資源。

4. SVID 的簽發(fā)和驗(yàn)證過(guò)程

我寫了一個(gè)小程序, 演示一下如何簽發(fā)和驗(yàn)證 SVID:

4.1 生成 SVID

函數(shù) generate_svid 通過(guò)以下步驟生成一個(gè) SVID:

  1. 生成私鑰

    private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
    

    創(chuàng)建 2048 位的 RSA 密鑰,用于簽署證書。

  2. 構(gòu)造證書信息

    subject = issuer = x509.Name([...])
    san = x509.SubjectAlternativeName([
        x509.UniformResourceIdentifier(spiffe_id),
    ])
    
    • subjectissuer 定義證書的主體和頒發(fā)者信息(自簽名證書中,主體和頒發(fā)者相同)。
    • san 定義 SPIFFE ID,存儲(chǔ)在證書的 Subject Alternative Name 字段中。
  3. 簽署證書

    certificate = (
        x509.CertificateBuilder()
        .subject_name(subject)
        .issuer_name(issuer)
        .public_key(private_key.public_key())
        .serial_number(x509.random_serial_number())
        .not_valid_before(datetime.now(timezone.utc))
        .not_valid_after(datetime.now(timezone.utc) + timedelta(days=365))
        .add_extension(san, critical=False)
        .sign(private_key, hashes.SHA256())
    )
    
    • 證書有效期為 1 年。
    • 使用私鑰簽名,生成完整的 X.509 證書。
  4. 保存證書和私鑰

    with open(f"{output_path}_key.pem", "wb") as key_file:
        key_file.write(private_key.private_bytes(...))
    
    with open(f"{output_path}_cert.pem", "wb") as cert_file:
        cert_file.write(certificate.public_bytes(Encoding.PEM))
    

4.2解析證書

函數(shù) parse_certificate 提取并打印證書的詳細(xì)信息,包括:

  • Subject 和 Issuer:主體和頒發(fā)者信息。
  • Serial Number:證書的唯一序列號(hào)。
  • Public Key:公鑰算法。
  • Extensions:擴(kuò)展字段(如 SAN)。

4.3 驗(yàn)證 SVID

函數(shù) verify_svid 驗(yàn)證 SVID 的有效性,主要包括:

  1. 提取 SPIFFE ID

    san = certificate.extensions.get_extension_for_class(x509.SubjectAlternativeName)
    spiffe_id = san.value.get_values_for_type(x509.UniformResourceIdentifier)
    
  2. 驗(yàn)證簽名

    public_key.verify(
        certificate.signature,
        certificate.tbs_certificate_bytes,
        padding.PKCS1v15(),
        certificate.signature_hash_algorithm
    )
    

    確保證書的簽名匹配。

  3. 檢查有效期

    now = datetime.utcnow()
    if certificate.not_valid_before <= now <= certificate.not_valid_after:
        print("certificate is valid")
    

完成代碼參見 generate_svid.py

5. 總結(jié)

通過(guò)將 AWS IAM 和 SPIFFE 結(jié)合起來(lái),你可以輕松地在分布式系統(tǒng)中證明“你是你”。IAM 提供了強(qiáng)大的身份和訪問(wèn)管理功能,而 SPIFFE 則為跨云和混合云環(huán)境提供了一個(gè)統(tǒng)一的身份框架。兩者的結(jié)合,就像是在數(shù)字世界里為你打造了一張全球通用的身份證,無(wú)論你走到哪里,都能證明自己的身份。

所以,下次有人問(wèn)你“如何證明你是你”時(shí),你可以自信地回答:“我有我的 SPIFFE ID 和 IAM 角色,我就是我,不一樣的煙火!”



本作品采用知識(shí)共享署名-非商業(yè)性使用-禁止演繹 4.0 國(guó)際許可協(xié)議進(jìn)行許可。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容