使用 IAM 角色从 ECS 的 S3 存储桶中提取对象被拒绝访问

Posted

技术标签:

【中文标题】使用 IAM 角色从 ECS 的 S3 存储桶中提取对象被拒绝访问【英文标题】:Getting Access Denied for pulling object from S3 bucket from ECS using IAM Role 【发布时间】:2018-08-27 05:31:03 【问题描述】:

我正在尝试从我的示例 Spring 应用程序中的 s3 存储桶获取一些加密连接参数。这是我在容器内运行的方法:

public void encryptionOnly_KmsManagedKey() throws NoSuchAlgorithmException 

     AmazonS3Encryption s3Encryption = AmazonS3EncryptionClientBuilder
            .standard()
            .withRegion(Regions.US_EAST_1)
            .withCryptoConfiguration(new CryptoConfiguration(CryptoMode.AuthenticatedEncryption))
            // Can either be Key ID or alias (prefixed with 'alias/')
            .withEncryptionMaterials(new KMSEncryptionMaterialsProvider("alias/db-connstring"))
            .build();

    //System.out.println(amazonS3.getObjectAsString(BUCKET_NAME, PROPERTIES_FILE_NON_ENC));
    System.out.println(s3Encryption.getObjectAsString(BUCKET_NAME, PROPERTIES_FILE_ENC));


我创建了一个 IAM 角色并分配给我的 ECS 任务:

 "Version": "2012-10-17", "Statement": [  "Action": [ "s3:GetObject" ], "Sid": "Stmt1", "Resource": [ "arn:aws:s3:::dev-web-s3/dev-webapp.properties" ], "Effect": "Allow"  ]  

我遇到以下错误:

15:31:25,502 WARN  [com.amazonaws.http.AmazonHttpClient] (http-/0.0.0.0:8080-1) SSL Certificate checking for endpoints has been explicitly disabled.
15:31:25,523 WARN  [com.amazonaws.http.AmazonHttpClient] (http-/0.0.0.0:8080-1) SSL Certificate checking for endpoints has been explicitly disabled.
15:31:26,000 ERROR [stderr] (http-/0.0.0.0:8080-1) com.amazonaws.services.s3.model.AmazonS3Exception: Access Denied (Service: Amazon S3; Status Code: 403; Error Code: AccessDenied; Request ID: 6859B84E52157DB7), S3 Extended Request ID: hIneAhT8TYX3P1z8zOGetqrSHhz5AqeOtRQnkCU9IuR0mBpMntFE9TXySu2iYv0Bbs4xONkxRz0=
15:31:26,001 ERROR [stderr] (http-/0.0.0.0:8080-1)  at com.amazonaws.http.AmazonHttpClient$RequestExecutor.handleErrorResponse(AmazonHttpClient.java:1588)
15:31:26,001 ERROR [stderr] (http-/0.0.0.0:8080-1)  at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeOneRequest(AmazonHttpClient.java:1258)
15:31:26,001 ERROR [stderr] (http-/0.0.0.0:8080-1)  at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeHelper(AmazonHttpClient.java:1030)
15:31:26,001 ERROR [stderr] (http-/0.0.0.0:8080-1)  at com.amazonaws.http.AmazonHttpClient$RequestExecutor.doExecute(AmazonHttpClient.java:742)
15:31:26,002 ERROR [stderr] (http-/0.0.0.0:8080-1)  at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeWithTimer(AmazonHttpClient.java:716)
15:31:26,002 ERROR [stderr] (http-/0.0.0.0:8080-1)  at com.amazonaws.http.AmazonHttpClient$RequestExecutor.execute(AmazonHttpClient.java:699)
15:31:26,002 ERROR [stderr] (http-/0.0.0.0:8080-1)  at com.amazonaws.http.AmazonHttpClient$RequestExecutor.access$500(AmazonHttpClient.java:667)
15:31:26,002 ERROR [stderr] (http-/0.0.0.0:8080-1)  at com.amazonaws.http.AmazonHttpClient$RequestExecutionBuilderImpl.execute(AmazonHttpClient.java:649)
15:31:26,002 ERROR [stderr] (http-/0.0.0.0:8080-1)  at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:513)

我正在使用 Fargate 部署我的容器,因此无法进入容器内部,但运行以下命令并得到如下结果: 卷曲 169.254.170.2$AWS_CONTAINER_CREDENTIALS_RELATIVE_URI


"RoleArn": "arn:aws:iam::281177187806:role/CC_GetPropertiesFile_S3_Role",
"AccessKeyId": "REDACTED",
"SecretAccessKey": "REDACTED",
"Token": "some random token",
"Expiration": "2018-03-16T00:21:55Z"

CC_GetPropertiesFile_S3_Role 是之前创建的角色,其可信实体是 AWS 服务:ecs-tasks。

我尝试使用 BasicAWSCredentials 选项使用 CURL 命令中的凭据,但出现以下错误:

com.amazonaws.services.s3.model.AmazonS3Exception: The AWS Access Key Id you provided does not exist in our records. (Service: Amazon S3; Status Code: 403; Error Code: InvalidAccessKeyId; Request ID: 81CC7254BCA83D53), S3 Extended Request ID: of46B2ujyTG 

我正在尝试获取调试级别的日志记录信息,但同时非常感谢任何其他可以指出的问题或提供的替代解决方案。

谢谢。

【问题讨论】:

与您的 S3 访问问题无关,您应该考虑使用 Parameter Store 存储数据库凭据等机密信息。 @jarmod 是的,参数存储似乎是替代解决方案,但在编写用于从存储中获取加密凭据的 java 代码方面找不到太多帮助。 【参考方案1】:

我能够通过在我在 java 方法中使用的加密密钥中添加我的自定义角色 CC_GetPropertiesFile_S3_Role 来解决此问题。

【讨论】:

【参考方案2】:

您必须使用两个不同的 Amazon 资源名称 (ARN) 来指定存储桶级 (ListBucket) 和对象级 (GetObject) 权限。

来自 IAM 的凭据会有过期时间,因此会出现 does not exist 错误。

https://aws.amazon.com/blogs/security/writing-iam-policies-how-to-grant-access-to-an-amazon-s3-bucket/


  "Version": "2012-10-17",
  "Statement": [
    
      "Effect": "Allow",
      "Action": ["s3:ListBucket"],
      "Resource": ["arn:aws:s3:::dev-web-s3"]
    ,
    
      "Effect": "Allow",
      "Action": [
        "s3:GetObject"
      ],
      "Resource": ["arn:aws:s3:::dev-web-s3/dev-webapp.properties"]
    
  ]

【讨论】:

@sudharsaan,感谢您的回复。我尝试了上述策略,但仍然遇到同样的错误。

以上是关于使用 IAM 角色从 ECS 的 S3 存储桶中提取对象被拒绝访问的主要内容,如果未能解决你的问题,请参考以下文章

Spark + S3 + IAM 角色

将 IAM 角色应用于 ECS 实例

AWS IAM 策略:按用户/角色限制存储桶/文件夹访问?

将 ECS 与 Fargate 一起使用时找不到 s3 的访问凭证

通过 terraform 创建 IAM 用户并在 S3 存储桶中上传密钥和访问密钥

AWS:将 IAM 用户限制在 S3 存储桶中的特定文件夹