如何通过CURL经VPC网关终端访问KMS加密的S3对象?
解决方案
核心问题分析
无法访问KMS加密S3对象的原因有两个:
- 仅配置S3网关终端不足以处理KMS请求,KMS需要单独的VPC接口终端;
- 使用
curl访问加密S3对象时,必须携带AWS SigV4签名(AWS CLI/SDK会自动处理,但curl需要手动构造)。
步骤1:创建KMS VPC接口终端
- 登录AWS VPC控制台,进入「终端节点」页面;
- 点击「创建终端节点」,服务类别选择「AWS服务」,搜索并选中
com.amazonaws.<你的区域>.kms; - 选择目标VPC、子网(需和EC2实例同子网或路由可达),配置安全组(允许EC2实例的IP访问终端节点的443端口);
- 完成创建,等待终端节点状态变为「可用」。
步骤2:调整KMS托管密钥的权限
- 登录AWS KMS控制台,找到你使用的AWS托管密钥;
- 进入「密钥策略」标签,点击「编辑」;
- 添加一条权限语句,允许EC2实例关联的IAM角色执行
kms:Decrypt操作:{ "Sid": "AllowEC2RoleDecrypt", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::<账号ID>:role/<EC2实例的IAM角色名>" }, "Action": "kms:Decrypt", "Resource": "*" } - 保存密钥策略。
步骤3:用curl构造带SigV4签名的请求
因为curl不自动处理AWS签名,需要手动生成SigV4签名并携带临时凭证:
3.1 获取EC2实例的临时IAM凭证
首先从实例元数据获取临时密钥:
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/<你的EC2IAM角色名>
返回结果包含AccessKeyId、SecretAccessKey和Token,记录这三个值。
3.2 构造SigV4签名请求头
按照AWS SigV4规范生成签名(可通过简单的Shell脚本计算),然后构造请求头:
Authorization:包含凭证、签名算法、签名值;x-amz-security-token:填入获取到的Token;
3.3 发起curl请求示例
假设目标S3对象地址为https://my-bucket.s3.<你的区域>.amazonaws.com/encrypted-file,请求命令如下:
curl -H "Authorization: AWS4-HMAC-SHA256 Credential=<AccessKeyId>/<YYYYMMDD>/<区域>/s3/aws4_request, SignedHeaders=host;x-amz-security-token, Signature=<生成的签名>" \ -H "x-amz-security-token: <Token>" \ https://my-bucket.s3.<你的区域>.amazonaws.com/encrypted-file
验证要点
- 确认KMS接口终端的路由已正确关联到VPC路由表;
- 检查EC2实例的安全组是否允许出站访问KMS终端节点的443端口;
- 确保KMS密钥策略中的IAM角色ARN正确无误。
内容的提问来源于stack exchange,提问作者shukla
相关产品推荐
相关产品推荐

