使用IAM设置RDS(MySQL)数据库访问以生成访问令牌

时间:2017-07-19 11:35:29

标签: amazon-web-services amazon-rds amazon-iam

我已按照说明设置AWS和MySQL,以便我能够使用mysql-client和用户(名为aws_iam)登录mysql而无需密码,但使用令牌由awscli生成且角色附加到我的EC2实例。

说明are here

所以我拥有的是:

  • 具有允许我生成RDS凭据的角色的EC2实例
  • 运行MySQL的RDS实例,用户aws_iamAWSAuthenticationPlugin
  • 标识
  • 当通过SSH登录EC2实例时,我可以运行mysql -h mydb.randomstring.region.rds.amazonaws.com -u root -p并输入RDS设置的主密码以获取mysql shell。
  • 同样通过SSH登录EC2实例时,我可以运行aws rds generate-db-auth-token --hostname mydb.randomstring.region.rds.amazonaws.com --port 3306 --username aws_iam,运行时我会得到一个如下所示的令牌:

mydb.randomstring.region.rds.amazon.aws.com:port-number/?Action=connect&DBUser=aws_iam&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Expires=900&X-Amz-Date=current_time&X-Amz-SignedHeaders=host&X-Amz-Security-Token=really-long-url-encoded-string&X-Amz-Credential=string/region/rds-db/aws4_request&X-Amz-Signature=long-hash

然后我运行连接命令:

mysql -h mydb.randomstring.region.rds.amazonaws.com --ssl-ca=rds-ca-2015-eu-west-1.pem --ssl-mode=VERIFY_IDENTITY -u aws_iam --enable-cleartext-plugin --password=TOKEN

但是我得到了

ERROR 1045 (28000): Access denied for user 'aws_iam'@IP (using password: YES)

我注意到的一些事情:

  • “令牌”最初是url编码的;然而解码它不起作用
  • 令牌包含许多url格式的参数;可能只有其中一个参数是实际令牌,但文档
  • 中没有提到
  • 如果您的EC2角色没有“rds-db”策略,您仍然可以生成令牌。这可能意味着令牌生成并不能证明您的策略有效;但除此之外没有其他方法可以调试

有没有人启用此功能,是否有我遗漏的内容?

2 个答案:

答案 0 :(得分:3)

文档似乎很少。

乍一看似乎是荒谬的,看起来整个事情,包括其网址转义,是“身份验证令牌”......你只需要将它包含在'单一中在命令行上引用。

以下是我得出这个结论的方法:

尝试解决此问题的第一步是检查RDS API参考。没有GetDbAuthToken操作。好奇。

然后,我注意到aws rds generate-db-auth-token不需要区域。怎么会这样?

除非......

在各行之间阅读,看起来这里的操作术语是生成 ...与获取(通过API请求)不是同义词。

这看起来像是一个完全本地的操作,这意味着它可以成功地“生成”一个完全无效的身份验证令牌......与生成一个语法上有效但仍然拒绝访问的预签名URL的方式完全相同,因为请求签名者缺少必要的权限。

  

如果您的EC2角色没有“rds-db”策略,您仍然可以生成令牌。这可能意味着令牌生成并不能证明您的策略有效。

我在这里称之为我的断言的进一步证明。根据我所看到的情况,我会说成功的令牌生成完全没有任何证据。

您只是生成他们称之为“令牌”的内容 - 即,在形式上,与AWS4-HMAC-SHA256(“签名版本4”)签名的URL没有区别。 ..用您的凭证签名。

RDS使用整个行,并使用与外部服务API使用的机制基本相同的机制将其传递给IAM,以验证它。这也解释了为什么令牌只有15分钟好...这就是大多数查询API的工作原理。签名请求仅适用于+/- 15分钟。它还解释了为什么他们建议每秒不超过20个新连接 - 当您尝试使用它登录时,您的RDS实例正在发出内部API请求以实际验证令牌。

我会回顾所有setup steps但在测试时使用IAM用户而不是实例角色,只是为了消除一点点复杂性。

RDS实例的错误日志可能包含更多信息。您可能需要在参数组中将log_warnings设置为2或更高,这无论如何都可能是一个好主意。

答案 1 :(得分:3)

事实证明我的角色没有正确的权限。不幸的是,那些错误的权限会在时间上丢失,但我似乎记得“资源”键是错误的。

以下是您需要替换以下变量的政策:

  • AWS_ROLE_NAME:分配给实例的角色名称
  • AWS_ACCOUNT_ID:您的整体帐户ID(请参阅帐户或结算页面)
  • RDS_REGION:您的实例所在的区域,例如“us-east-1”(不需要为单个AZ指定AZ)
  • RDS_RESOURCE_ID:您要访问的实例的RDS Web控制台中标题为“资源ID”下的代码(应采用db-([A-Z0-9]+)形式)

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "rds-db:connect" ], "Resource": [ "arn:aws:rds-db:RDS_REGION:AWS_ACCOUNT_ID:dbuser:RDS_RESOURCE_ID/AWS_ROLE_NAME" ] } ] }

我已经给了sqlbot正确的答案,因为他们用有用的信息很快就回答了很多,但是这个政策应该可以帮助一些人。