上游授权

概述

上游授权(UpstreamAuthority)允许 SPIRE Server 使用外部 CA 作为根或中间 CA,而不是自签名。

Disk

使用磁盘上的 CA 证书和密钥。

配置

plugins {
    UpstreamAuthority "disk" {
        plugin_data {
            # CA 密钥路径
            key_file_path = "/opt/spire/conf/server/ca-key.pem"
            
            # CA 证书路径
            cert_file_path = "/opt/spire/conf/server/ca-cert.pem"
            
            # 可选:证书包(用于中间 CA)
            # bundle_file_path = "/opt/spire/conf/server/bundle.pem"
        }
    }
}

创建 CA 证书

# 创建 CA 私钥
openssl ecparam -name prime256v1 -genkey -noout -out ca-key.pem

# 创建自签名 CA 证书
openssl req -new -x509 -days 365 -key ca-key.pem -out ca-cert.pem \
    -subj "/C=US/O=Example/CN=SPIRE Root CA"

AWS PCA

使用 AWS Private Certificate Authority。

配置

plugins {
    UpstreamAuthority "aws_pca" {
        plugin_data {
            # 区域
            region = "us-west-2"
            
            # PCA ARN
            certificate_authority_arn = "arn:aws:acm-pca:us-west-2:123456789012:certificate-authority/abc123"
            
            # 签名算法
            signing_algorithm = "SHA256WITHECDSA"
            
            # CA 签名模板 ARN(可选)
            # ca_signing_template_arn = "arn:aws:acm-pca:::template/SubordinateCACertificate_PathLen0_APIPassthrough/V1"
            
            # 补充包路径(可选)
            # supplemental_bundle_path = "/path/to/bundle.pem"
            
            # 访问凭证(可选,推荐使用 IAM 角色)
            # access_key_id = "..."
            # secret_access_key = "..."
        }
    }
}

IAM 策略

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "acm-pca:IssueCertificate",
                "acm-pca:GetCertificate",
                "acm-pca:GetCertificateAuthorityCertificate",
                "acm-pca:DescribeCertificateAuthority"
            ],
            "Resource": "arn:aws:acm-pca:us-west-2:123456789012:certificate-authority/abc123"
        }
    ]
}

创建 PCA

# 创建 PCA
aws acm-pca create-certificate-authority \
    --certificate-authority-type SUBORDINATE \
    --certificate-authority-configuration file://ca-config.json \
    --revocation-configuration file://revocation-config.json

# ca-config.json
{
    "KeyAlgorithm": "EC_prime256v1",
    "SigningAlgorithm": "SHA256WITHECDSA",
    "Subject": {
        "CommonName": "SPIRE Intermediate CA"
    }
}

HashiCorp Vault

使用 Vault PKI secrets engine。

配置

plugins {
    UpstreamAuthority "vault" {
        plugin_data {
            # Vault 地址
            vault_addr = "https://vault.example.org:8200"
            
            # PKI 挂载点
            pki_mount_point = "pki"
            
            # CA 证书路径(用于验证 Vault TLS)
            ca_cert_path = "/opt/spire/conf/server/vault-ca.pem"
            
            # 认证方式:token, approle, cert, k8s
            
            # Token 认证
            # token = "hvs.xxx"
            
            # AppRole 认证
            # approle_auth_mount_point = "approle"
            # approle_role_id = "xxx"
            # approle_secret_id = "xxx"
            
            # Kubernetes 认证
            k8s_auth_mount_point = "kubernetes"
            k8s_auth_role_name = "spire-server"
            
            # 命名空间(企业版)
            # namespace = "my-namespace"
        }
    }
}

Vault PKI 配置

# 启用 PKI
vault secrets enable pki

# 配置 TTL
vault secrets tune -max-lease-ttl=87600h pki

# 生成根 CA
vault write pki/root/generate/internal \
    common_name="Example Root CA" \
    ttl=87600h

# 配置 URL
vault write pki/config/urls \
    issuing_certificates="https://vault.example.org:8200/v1/pki/ca" \
    crl_distribution_points="https://vault.example.org:8200/v1/pki/crl"

# 创建角色
vault write pki/roles/spire-server \
    allowed_domains="example.org" \
    allow_subdomains=true \
    max_ttl=720h

嵌套 SPIRE

使用另一个 SPIRE Server 作为上游 CA。

配置

plugins {
    UpstreamAuthority "spire" {
        plugin_data {
            # 上游 Server 地址
            server_address = "upstream-spire-server.example.org"
            server_port = 8081
            
            # Workload API socket(获取 SVID 用于认证)
            workload_api_socket = "/tmp/spire-agent/public/api.sock"
        }
    }
}

架构示例

        graph TB
    subgraph "根信任域"
        RS[根 SPIRE Server]
    end
    
    subgraph "区域信任域 A"
        SA[区域 Server A]
        AA1[Agent A1]
        AA2[Agent A2]
    end
    
    subgraph "区域信任域 B"
        SB[区域 Server B]
        AB1[Agent B1]
    end
    
    RS --> SA
    RS --> SB
    SA --> AA1
    SA --> AA2
    SB --> AB1
    

cert-manager

使用 Kubernetes cert-manager。

配置

plugins {
    UpstreamAuthority "cert-manager" {
        plugin_data {
            # cert-manager 命名空间
            namespace = "cert-manager"
            
            # Issuer 名称
            issuer_name = "spire-ca"
            
            # Issuer 类型:Issuer, ClusterIssuer
            issuer_kind = "ClusterIssuer"
            
            # Issuer 组(可选)
            # issuer_group = "cert-manager.io"
            
            # Kubernetes 配置(可选)
            # kube_config_file_path = "/path/to/kubeconfig"
        }
    }
}

ClusterIssuer 配置

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: spire-ca
spec:
  ca:
    secretName: spire-ca-key-pair
---
apiVersion: v1
kind: Secret
metadata:
  name: spire-ca-key-pair
  namespace: cert-manager
type: kubernetes.io/tls
data:
  tls.crt: <base64-encoded-cert>
  tls.key: <base64-encoded-key>

EJBCA

使用 EJBCA(Enterprise Java Beans Certificate Authority)。

配置

plugins {
    UpstreamAuthority "ejbca" {
        plugin_data {
            # EJBCA 服务器 URL
            hostname = "ejbca.example.org"
            
            # 证书配置文件
            certificate_profile_name = "SpireIntermediateCA"
            
            # 终端实体配置文件
            end_entity_profile_name = "SpireServer"
            
            # CA 名称
            certificate_authority_name = "RootCA"
            
            # 终端实体名称
            end_entity_name = "spire-server"
            
            # 认证
            account_binding_id = "xxx"
            
            # TLS 证书
            ca_cert = "/path/to/ejbca-ca.pem"
            client_cert = "/path/to/client.pem"
            client_key = "/path/to/client-key.pem"
        }
    }
}

选择建议

场景

推荐上游授权

独立部署

无需上游授权(自签名)

企业 PKI 集成

vaultejbca

AWS 环境

aws_pca

Kubernetes 原生

cert-manager

多级 SPIRE

spire

简单中间 CA

disk

最佳实践

  1. 层级设计: 根据组织结构设计 CA 层级

  2. 密钥保护: 上游 CA 私钥应使用 HSM

  3. 证书生命周期: 规划证书轮换策略

  4. 审计日志: 启用上游 CA 的审计功能

  5. 灾难恢复: 准备 CA 恢复计划