代码之家  ›  专栏  ›  技术社区  ›  M1ke

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

  •  4
  • M1ke  · 技术社区  · 7 年前

    mysql-client 和一个用户(名为 aws_iam awscli 角色附加到我的EC2实例。

    说明书 are here

    所以我得到的是:

    • 一个EC2实例,其角色允许我生成RDS凭据
    • 其标识为 AWSAuthenticationPlugin
    • 当通过SSH登录到EC2实例时,我可以运行 mysql -h mydb.randomstring.region.rds.amazonaws.com -u root -p
    • 此外,当通过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 回复  |  直到 7 年前
        1
  •  4
  •   Michael - sqlbot    7 年前

    这些文档似乎并不多。

    '

    我是这样得出这个结论的:

    GetDbAuthToken 行动好奇的

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

    除非

    从字里行间看,这里的有效术语是 …不是同义词 收到 (通过API请求)。

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

    我把这称为我主张的进一步证明。根据我所看到的,我想说成功的令牌生成根本证明不了什么。

    你只是 生成 AWS4-HMAC-SHA256 (“签名版本4”)签名URL…用您的凭据签名。

    RDS接管这条线路,并使用与面向外部的服务API使用的基本相同的机制将其传递给IAM进行验证。这也解释了为什么令牌只能使用15分钟……这就是大多数查询API的工作方式。签名请求仅在+/-15分钟内有效。这也解释了为什么他们建议每秒不超过20个新连接——您的RDS实例正在发出内部API请求,以在您尝试登录令牌时实际验证令牌。

    setup steps

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

        2
  •  3
  •   M1ke    6 年前

    错误的

    • AWS\u ROLE\u NAME:分配给实例的角色的名称
    • RDS_REGION:实例所在的区域,例如“us-east-1”(不需要为单个AZ指定AZ)
    • 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正确的答案,因为他们用有用的信息更快地回答了问题,但这个策略应该可以帮助一些人。