使用rdsutils.BuildAuthToken连接AWS RDS失败,硬编码密码可正常连接
我之前踩过完全一样的坑!你现在遇到的Error 1045: Access denied问题,核心原因是你的IAM用户没有被授予生成有效RDS认证令牌的权限——虽然你开了编程访问,但没附加对应的IAM策略,导致生成的令牌无法被RDS实例认可。下面一步步给你解决:
1. 给IAM用户附加正确的RDS IAM认证策略
你需要给这个IAM用户添加一个自定义策略,允许它对目标RDS实例执行rds-db:connect动作。打开IAM控制台,找到你的用户,点击「添加权限」→「创建内联策略」,选择JSON模式,粘贴下面的内容(记得替换占位符):
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "rds-db:connect", "Resource": "arn:aws:rds-db:<aws-region>:<your-account-id>:dbuser:<db-resource-id>/<db-user>" } ] }
<aws-region>:你的RDS实例所在区域(比如us-east-1)<your-account-id>:你的AWS账号ID(不带连字符)<db-resource-id>:RDS实例的资源ID,可在RDS控制台实例详情页找到<db-user>:你用来连接的数据库用户名(比如你代码里的master)
如果想快速测试,也可以用更宽松的策略(不推荐生产环境):
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "rds-db:connect", "Resource": "*" } ] }
2. 确认RDS实例已开启IAM数据库认证
这一步很容易被忽略!你需要确保目标RDS实例已经启用了IAM数据库认证:
- 登录RDS控制台,找到你的实例,进入「配置」标签页,查看「IAM数据库认证」状态是否为「已启用」
- 或者用AWS CLI验证:
aws rds describe-db-instances --db-instance-identifier <your-instance-name> --query 'DBInstances[0].IAMDatabaseAuthenticationEnabled'
如果返回false,赶紧修改实例配置开启它(需要重启实例生效)。
3. 检查代码中BuildAuthToken的参数是否正确
我之前栽过这个跟头:BuildAuthToken的dbEndpoint参数必须是不带端口的域名(比如mydb.xxxxxxx.us-east-1.rds.amazonaws.com),不能加:3306这类端口号!你代码里的dnsStr是把endpoint和port分开的,那要确认传给BuildAuthToken的dbEndpoint没有带端口,否则生成的令牌会无效。
另外,验证生成的令牌是否正确:用AWS CLI手动生成一个令牌,和代码生成的对比:
aws rds generate-db-auth-token --hostname <db-endpoint-no-port> --port <db-port> --username <db-user> --region <aws-region>
如果两个令牌不一样,说明代码里的参数(比如region、用户名)有错误,或者凭证不是你预期的IAM用户的。
4. TLS配置的优化(非当前问题,但建议调整)
你代码里用了InsecureSkipVerify: true,虽然能暂时绕开证书验证,但生产环境不推荐。建议下载AWS官方的RDS CA证书,然后配置TLS:
// 加载AWS RDS CA证书 caCert, err := ioutil.ReadFile("rds-ca-2019-root.pem") if err != nil { log.Fatal(err) } certPool := x509.NewCertPool() certPool.AppendCertsFromPEM(caCert) mysql.RegisterTLSConfig("custom", &tls.Config{ RootCAs: certPool, })
做完上面几步,再重新测试连接,应该就能成功了!
内容的提问来源于stack exchange,提问作者thelearner

