繁体   English   中英

带有 IAM 的 EC2 上的 S3:错误 NoCredentialProviders:链中没有有效的提供者。 已弃用

[英]S3 on EC2 with IAM: Error NoCredentialProviders: no valid providers in chain. Deprecated

我的应用程序使用 s3 并在 EC2 上运行。 IAM 是在实例上配置的,因此身份验证发生在无密钥的情况下(没有访问密钥和密钥)。

我可以使用 aws cli 上传或下载文件。 但是,当我尝试使用 aws-sdk-go 执行下载操作时,出现以下错误:

AccessDenied:拒绝访问
状态码:403,请求ID:F945BDB5410E1A00,主机ID:m74jJ8z/AEzdkaJkWKdIqPEwPIYPZfWnLLfa5UpEwHwaBcXOuXTPY1aw/u/5HGralKg+ewAWEJA=

我遵循了来自https://docs.aws.amazon.com/sdk-for-go/api/aws/credentials/ec2rolecreds/的官方指南和从这个问题https://github.com/aws/aws-sdk- go/issues/430但出现上述错误。

下面是我的代码:

s3UploadPath = config.GetString("upload assets to s3.bucket")
s3Config := aws.NewConfig()
s3Config.CredentialsChainVerboseErrors = aws.Bool(true)

session, err := session.NewSession(s3Config)
if err != nil {
    Logger.Fatal("Error initializing s3 uploader. " + err.Error())
    os.Exit(0)
}

// the upload code
uploader = s3manager.NewUploader(session)
res, err := uploader.Upload(&s3manager.UploadInput{
    Bucket: aws.String(s3UploadPath),
    Key:    aws.String(filename),
    Body:   f,
})
if err != nil {
    log.Fatal("error on upload. " + err.Error())
}

// then continue with the download code

附件截图显示通过 aws cli 下载和上传操作成功

在此处输入图像描述

我做错了吗?

在 EC2 实例上使用 IAM 角色时,您不需要指定凭证。

我看到您收到Access Denied ,这意味着您的 Go 程序能够选择 EC2 配置文件凭据,但可能由于缺少权限,它会收到此错误。

阅读您的代码,您似乎想将 object 写入 S3。 您能否确保已将s3:Get*s3:List*s3:PutObjects3:PutObjectAcl提供给您的 IAM 角色,并且 S3 存储桶策略中没有明确的拒绝?

我通过做两件事设法解决了这个错误。

第一个是在 session 创建期间使用stscreds.NewCredentials(session, roleArn)作为凭据。

s3Config := aws.NewConfig()
s3Config.CredentialsChainVerboseErrors = aws.Bool(true)
s3Config.WithLogLevel(aws.LogDebugWithHTTPBody)
s3Config.Region = aws.String(region)
s3Config.WithHTTPClient(&http.Client{
    Transport: &http.Transport{
        Proxy: http.ProxyFromEnvironment,
    },
    Timeout: 10 * time.Second,
})

sess, err := session.NewSession(s3Config)
if err != nil {
    log.Fatal("Error initializing session. " + err.Error())
}

sess.Config.Credentials = stscreds.NewCredentials(sess, arn)
_, err = sess.Config.Credentials.Get()
if err != nil {
    log.Fatal("Error getting role. " + err.Error())
}

第二件事是定义NO_PROXY环境变量,其值为169.254.169.254 特定的 IP 是 AWS 全局 IP,用于获取 EC2 元数据。

由于我的应用程序使用代理与 S3 服务器通信,因此我需要排除 IP。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM