我无法使用IAM用户连接到我的RDS数据库。
数据库用户名:master
IAM用户:api-user
我已为用户分配了用户程序化访问权限并添加了以下政策:
自定义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"
]
}
]
}
奇怪的是,即使我已经完全按照文档中的要求定义了我的自定义权限,也无法识别:
当我尝试使用身份验证令牌(通过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)
答案 0 :(得分:3)
根据来自AWS Github存储库的Go编程语言示例,您需要创建如下凭据:
参考: 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/database-user-name
authToken, err := rdsutils.BuildAuthToken(dbEndpoint, awsRegion, dbUser, awsCreds)
我几乎可以肯定你错过了IAM ARN的那一部分。
您需要连接到数据库并使用AWS身份验证插件创建用户。
以下SQL语句创建名为lambda的数据库用户。 AWSAuthenticationPlugin不是指定密码,而是用于标识用户。替换为您要授予用户访问权限的数据库的名称。
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文档中的以下内容非常重要:
IAM数据库身份验证的限制
使用IAM数据库身份验证,每秒最多限制为20个新连接。如果您使用的是db.t2.micro实例类,则限制为每秒10个连接。
Amazon RDS for MySQL和Aurora MySQL数据库引擎不会对每秒的身份验证尝试施加任何限制。但是,使用IAM数据库身份验证时,应用程序必须生成身份验证令牌。然后,您的应用程序使用该令牌连接到数据库实例或群集。如果超过每秒最大新连接数限制,则IAM数据库身份验证的额外开销可能会导致连接限制。额外的开销甚至可能导致现有连接丢失。
我们建议如下:
使用IAM数据库身份验证作为临时,个人访问数据库的机制。
如果您的应用程序每秒需要超过20个新连接,请不要使用IAM数据库身份验证。
仅对可以轻松重试的工作负载使用IAM数据库身份验证。
注意
有关MySQL的最大总连接数的信息,请参阅最大MySQL连接数。有关Aurora MySQL的最大总连接数的信息,请参阅Aurora MySQL数据库实例的最大连接数。
答案 1 :(得分:0)
我也遇到了同样的问题。在我添加了用于构建Auth令牌的端口号之后(在网上进行了大量查找),它得到了解决。
之前是这样的:
authToken, err := rdsutils.BuildAuthToken(host, region, username, sess.Config.Credentials)
我必须更改为:
authToken, err := rdsutils.BuildAuthToken(fmt.Sprintf("%s:%d", host, 3306), region, username, sess.Config.Credentials)
这是针对Golang应用程序的。但是其他语言SDK也可能适用。 我从https://luktom.net/en/e1544-aws-lambda-and-mysql-iam-authentication-in-go
得到了这个答案AWS的某些人需要更新其 official docs on this
答案 2 :(得分:0)
Ele 提供的答案部分错误,这是正确的代码:
arn := "arn:aws:iam::00000000000:role/your-TaskRole"
awsCreds := stscreds.NewCredentials(session.New(&aws.Config{Region: aws.String(Region)}), arn)
所以 arn
不是 iam db 用户之一,而是分配给您的资源(EC2、ECS、Fargate)的角色的 arn
请记住,您也必须使用 TLS 通过 IAM 身份验证连接到数据库