简体   繁体   English

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

[英]Can't connect to RDS via AWS.RDS.Signer

I'm trying to connect to my MySQL RDS from a Lambda via AWS.RDS.Signer with the following code and fake credentials:我正在尝试通过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 }

but I always get this error但我总是收到这个错误

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

I'm not entirely sure if that is needed for the AWS.RDS.Signer but I selected this option of my database:我不完全确定AWS.RDS.Signer是否需要这样做,但我选择了我的数据库的这个选项:

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

NOTE: If I swap the password from token to "Password123" on line 20 I can successfully connect to my RDS.注意:如果我在line 20密码从令牌交换为"Password123" ,我可以成功连接到我的 RDS。

Am I missing something here or does AWS.RDS.Signer only work with RDS Proxy ?我在这里遗漏了什么还是AWS.RDS.Signer仅适用于RDS Proxy

By the way: the getAuthToken function gives me something like that (token truncated)顺便说一句: getAuthToken function 给了我类似的东西(令牌被截断)

"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"

I finally can connect to my RDS via Lamdba using IAM (aka AWS.RDS.Signer)我终于可以使用IAM (又名 AWS.RDS.Signer)通过 Lamdba 连接到我的RDS

So what was the problem?那么问题出在哪里?

  • Short story:短篇故事:

I used the wrong region in my Policy and in the props for the AWS.RDS.Signer .我在我的PolicyAWS.RDS.Signer的 props 中使用了错误的区域。

I assumed that the Availability zone ( ap-southeast-2a ) equals the region, but that's not true.我假设可用( ap-southeast-2a ) 等于区域,但事实并非如此。 The correct region is actually described when the AWS command line creds get created.在创建AWS命令行凭据时,实际上描述了正确的区域。 To find out the region invoke cat ~/.aws/config from the terminal.要找出该区域,请从终端调用cat ~/.aws/config My default region was actually region=ap-southeast-2 .我的默认区域实际上是region=ap-southeast-2

  • Long story:很长的故事:

When I started with AWS.RDS.Signer I followed the instructions here When it came to extracting the DB info for the Policy, I used this command当我开始使用AWS.RDS.Signer时,我按照此处的说明进行操作。在提取策略的数据库信息时,我使用了此命令

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

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

After a bit of Googling, I realised that the region is not right.经过一番谷歌搜索,我意识到该地区不正确。 That gave me a hint to change the region in the policy and in the code of my Lambda function.这给了我一个提示,让我在策略和我的 Lambda function 的代码中更改区域。

{
   "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>"
           ]
       }
   ]
}

Then I created an extra user ( ssluser ) in the DB to connect with the AWS.RDS.Signer token然后我在数据库中创建了一个额外的用户( 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;

The next step was to add the above policy to the EC2 instance, ssh into the instance, install the MySQL client yum install mysql and try to connect to the instance using the token下一步是将上述策略添加到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`

After successfully connect to the RDS without providing a password I only had to attach the policy to my Lambda and change the username and region in my Lambda code to在不提供密码的情况下成功连接到 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'

I hope that will help someone in the future.我希望这将有助于未来的人。

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

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