amazon-web-services - 无法通过 IAM 身份验证访问 RDS 数据库

标签 amazon-web-services go amazon-rds

我无法使用 IAM 用户连接到我的 RDS 数据库。

数据库用户名:master
IAM 用户:api-用户

我已经为用户分配了编程访问权限并为用户添加了以下策略:

enter image description here

自定义 rds-permission 定义为:https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/UsingWithRDS.IAMDBAuth.IAMPolicy.html

    {
   "Version": "2012-10-17",
   "Statement": [
      {
         "Effect": "Allow",
         "Action": [
             "rds-db:connect"
         ],
         "Resource": [
             "arn:aws:rds-db:REGION:ACCOUNT-ID:USER:dbi-resource-id/DB_ACCOUNT_NAME"
         ]
      }
   ]
}

奇怪的是,即使我已经完全按照文档中的要求定义了我的自定义权限,它仍未被识别:

enter image description here

enter image description here

当我尝试使用身份验证 token (通过 golang)进行连接时,出现以下错误:

error: ERROR: Error 1045: Access denied for user 'master'@'x.x.x.189' (using password: YES)

我的策略似乎不起作用!

尽管这无关紧要,但这是我通过 IAM 用户连接的方式:

//Yes Env vars are available
//creating new credentials from environment variables
//AWS_ACCESS_KEY_ID  and  AWS_SECRET_ACCESS_KEY
awsCreds := credentials.NewEnvCredentials()

//creating authentication token for the database connection
authToken, err := rdsutils.BuildAuthToken(dbEndpoint, awsRegion, dbUser, awsCreds)
if err != nil {
    Logger.LogFatal("Unable to build Authentication Token")
    log.Fatal("Unable to build Authentication Token")  //todo remove
}

//setting up TLS
mysql.RegisterTLSConfig("custom", &tls.Config{
    InsecureSkipVerify: true,
})

// Creating the MySQL DNS string for the DB connection
// user:password@protocol(endpoint)/dbname?<params>
dnsStr := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s allowCleartextPasswords=true&tls=custom",
    dbUser, authToken, dbEndpoint,dbPort, dbName,
)
rootCertPool := x509.NewCertPool() //NewCertPool returns a new, empty CertPool.

pem, err := ioutil.ReadFile("rds-ca-bundle.pem") //reading the provided pem
if err != nil {
    log.Fatal("! Could not read certificates")
}
fmt.Println("Loading certificate seems to work")
//AppendCertsFromPEM attempts to parse a series of PEM encoded certificates.
//pushing in the pem
if ok := rootCertPool.AppendCertsFromPEM(pem); !ok {
    log.Fatal("Failed to append PEM.")
}
fmt.Println("Appending certificate seems to work too")

//setting up TLS
//we dont need a client ca?
mysql.RegisterTLSConfig("custom", &tls.Config{
    RootCAs: rootCertPool,
    InsecureSkipVerify: true,
})
database, err = sql.Open("mysql", dnsStr)

最佳答案

根据 Go 编程语言的 AWS Github 存储库中的示例,您需要创建如下凭证:

IAM ARN

引用: IAM authentication go example

import (
    "database/sql"
    "fmt"
    "log"
    "os"

    "github.com/go-sql-driver/mysql"

    "github.com/aws/aws-sdk-go/aws"
    "github.com/aws/aws-sdk-go/aws/credentials/stscreds"
    "github.com/aws/aws-sdk-go/aws/session"
    "github.com/aws/aws-sdk-go/service/rds/rdsutils"
)

awsCreds := stscreds.NewCredentials(session.New(&aws.Config{Region: &awsRegion}), iamArn) 

// iamArn: arn:aws:rds-db:region:account-id:dbuser:dbi-resource-id/data‌​base-user-name

authToken, err := rdsutils.BuildAuthToken(dbEndpoint, awsRegion, dbUser, awsCreds)

我几乎可以肯定您遗漏了 IAM ARN 的那一部分。


准备数据库用户

引用: Preparing a Database User

You need to connect to your database and create a user using the AWS authentication plugin.

The following SQL statement creates a database user named lambda. Instead of specifying a password, the AWSAuthenticationPlugin is used for identifying the user. Replace with the name of the database you want to grant the user access to.

CREATE USER 'master' IDENTIFIED WITH AWSAuthenticationPlugin as 'RDS';
GRANT ALL PRIVILEGES ON <DB_NAME>.* TO 'master'@'%';
FLUSH PRIVILEGES;

奖金推荐

引用: Limitations for IAM Database Authentication

我不知道您的项目中 IAM 身份验证的目的是什么,但我认为 AWS 文档中的以下内容很重要:

Limitations for IAM Database Authentication

With IAM database authentication, you are limited to a maximum of 20 new connections per second. If you are using a db.t2.micro instance class, the limit is 10 connections per second.

The Amazon RDS for MySQL and Aurora MySQL database engines do not impose any limits on authentication attempts per second. However, when you use IAM database authentication, your application must generate an authentication token. Your application then uses that token to connect to the DB instance or cluster. If you exceed the maximum new-connection-per-second limit, then the extra overhead of IAM database authentication can cause connection throttling. The extra overhead can even cause existing connections to drop.

We recommend the following:

  • Use IAM database authentication as a mechanism for temporary, personal access to databases.

  • Don't use IAM database authentication if your application requires more than 20 new connections per second.

  • Use IAM database authentication only for workloads that can be easily retried.

Note

For information about the maximum total connections for MySQL, see see Maximum MySQL connections. For information about the maximum total connections for Aurora MySQL, see Maximum Connections to an Aurora MySQL DB Instance.

关于amazon-web-services - 无法通过 IAM 身份验证访问 RDS 数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48138267/

相关文章:

amazon-web-services - mysql 升级后 AWS RDS 参数组显示 "Pending-Reboot"

go - 如何从Google Cloud VM部署Hugo网站?

mysql - 在 RDS 中访问 MySQL 或 MS SQL 时,AWS Lambda node.js ETIMEDOUT

mysql - 如何从 MySQL .NET Connector 使用 SSL 访问托管在 Amazon RDS 上的 MySQL 数据库

python - RDS : Not able to fetch events it is showing blank in boto3 describe_events

amazon-web-services - AWS : How to update an existing S3 bucket-policy via CloudFormation?

amazon-web-services - CloudFormation 可选映射属性 - DeadLetterQueue

go - Angular 客户端不调用后端服务

amazon-web-services - Golang 在 AWS 中重定向到 HTTPS

go - 从包访问主结构