无法通过 AWS.RDS.Signer 连接到 RDS

Posted

技术标签:

【中文标题】无法通过 AWS.RDS.Signer 连接到 RDS【英文标题】:Can't connect to RDS via AWS.RDS.Signer 【发布时间】:2021-06-15 18:16:05 【问题描述】:

我正在尝试通过 AWS.RDS.Signer 使用以下代码和 fake 凭据从 Lambda 连接到我的 mysql RDS:

1  const DB_REGION = 'ap-southeast-2a'
2  const DB_HOST = 'dbinstance.ddtev8utygt.ap-southeast-2.rds.amazonaws.com'
3  const DB_PORT = 3306
4  const DB_USER = 'anyuser'
5  const DB_NAME = 'anydb'
6
7  const signerOptions = 
8    region: DB_REGION,
9    hostname: DB_HOST,
10   port: DB_PORT,
11   username: DB_USER
12 
13
14 const signer = new AWS.RDS.Signer(signerOptions)
15 const token = await signer.getAuthToken()
16 
17 const config = 
18   host: DB_HOST,
19   user: DB_USER,
20   password: token, // "Password123"
21   database: DB_NAME,
22   ssl: 'Amazon RDS',
23   authPlugins: 
24     mysql_clear_password: () => () => token
25   
26 

但我总是收到此错误

"Access denied for user 'anyuser'@'172.14.1.12' (using password: NO)"

我不完全确定 AWS.RDS.Signer 是否需要这样做,但我选择了我的数据库的这个选项:

Password and IAM database authentication
Authenticates using the database password and user credentials through AWS IAM users and roles. 

注意:如果我在line 20 上将密码从令牌换成"Password123",我可以成功连接到我的RDS。

我在这里遗漏了什么还是AWS.RDS.Signer 仅适用于RDS Proxy

顺便说一句:getAuthToken 函数给了我类似的东西(令牌被截断)

"dbinstance.ddtev8utygt.apsoutheast2.rds.amazonaws.com:3306/Action=connect&DBUser=anyuser&&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=ASIAU7VGXF6UCWYZCFEG%2F20210318%2Fap-southeast-2a%2Frds-db%2Faws4_request&X-Amz-Date=20210318T105145Z&X-Amz-Expires=900&X-Amz-Security-Token=IQoJb3JpZ2luX2VjEAsaDmFwLXNvdXRoZWFzdC0yIkgwRgIhAKg8ibwNJ4E3hSOuq7HtDFvqHxmTlpOUk3I6EH2%2B9VdOV3RQ%2F03xiVdvjhEBkHqEXHQ%3D&X-Amz-Signature=749d931f74873e6c2c0d4fec94f0743f42efd5aa95ca0ac0f05c4bef30e3bd4d&X-Amz-SignedHeaders=host"

【问题讨论】:

【参考方案1】:

我终于可以使用 IAM(又名 AWS.RDS.Signer)通过 Lamdba 连接到我的 RDS

那么问题出在哪里?

短篇小说:

我在 PolicyAWS.RDS.Signer 的 props 中使用了错误的区域。

我假设 可用区 (ap-southeast-2a) 等于区域,但事实并非如此。当创建 AWS 命令行凭据时,实际上描述了正确的区域。要找出该区域,请从终端调用 cat ~/.aws/config。我的默认区域实际上是region=ap-southeast-2

说来话长:

当我开始使用 AWS.RDS.Signer 时,我按照说明进行操作 here 在提取策略的数据库信息时,我使用了这个命令

aws rds describe-db-instances --db-instance-identifier <MY INSTANCE NAME> --query "DBInstances[*].DbiResourceId" --region ap-southeast-2a

但我收到此错误Could not connect to the endpoint URL: "https://rds.ap-southeast-2a.amazonaws.com/"

经过一番谷歌搜索后,我意识到该地区不正确。这给了我在策略和我的 Lambda 函数代码中更改区域的提示。


   "Version": "2012-10-17",
   "Statement": [
       
           "Effect": "Allow",
           "Action": [
               "rds-db:connect"
           ],
           "Resource": [
               "arn:aws:rds-db:<my-region>:<my-account-id>:dbuser:<my-db-resource-id>/<my-db-username>"
           ]
       
   ]

然后我在数据库中创建了一个额外的用户 (ssluser) 来连接 AWS.RDS.Signer 令牌

CREATE USER 'ssluser' IDENTIFIED WITH AWSAuthenticationPlugin as 'RDS';
GRANT ALL PRIVILEGES ON <MY DB NAME>.* TO 'ssluser'@'%';
GRANT USAGE ON <MY DB NAME>.* TO 'ssluser'@'%' REQUIRE SSL;

下一步是将上述策略添加到 EC2 实例,ssh 到实例中,安装 MySQL 客户端 yum install mysql 并尝试使用令牌连接到实例

mysql --host=dbinstance.chteb5kjtggo.ap-southeast-2.rds.amazonaws.com --port=3306 --ssl-ca=rds-combined-ca-bundle.pem --enable-cleartext-plugin --user=ssluser --password=`aws rds generate-db-auth-token --hostname dbinstance.chteb5kjtggo.ap-southeast-2.rds.amazonaws.com --port 3306 --region ap-southeast-2 --username ssluser`

在不提供密码的情况下成功连接到 RDS 后,我只需将策略附加到我的 Lambda 并将我的 Lambda 代码中的用户名和区域更改为

1  const DB_REGION = 'ap-southeast-2'
2  const DB_HOST = 'dbinstance.ddtev8utygt.ap-southeast-2.rds.amazonaws.com'
3  const DB_PORT = 3306
4  const DB_USER = 'ssluser'
5  const DB_NAME = 'anydb'

我希望这对将来的人有所帮助。

【讨论】:

以上是关于无法通过 AWS.RDS.Signer 连接到 RDS的主要内容,如果未能解决你的问题,请参考以下文章

无法通过Excel VBA连接到SQL数据库。

CloudCompare 无法启动并出现错误:“QXcbConnection:无法连接到显示器:0”

无法连接到 docker 托管的 MSSQL

vm无法连接到虚拟机

带docker的Mysql:无法通过socket连接到本地MySQL服务器

R中的H2O错误-无法连接到本地主机