从 Lambda (NodeJS) 对 RDS 进行 IAM 身份验证

问题描述 投票:0回答:1

我有点不知道这里可能出了什么问题。我一直遵循这组说明,让我的 Lambda 根据以下说明使用 IAM 身份验证连接到 RDS: https://cloudonaut.io/passwordless-database-authentication-for-aws-lambda/

现在,我已经检查我的 RDS 集群确实启用了 IAM 身份验证 - 我已经创建了用户并授予了所有必要的权限(执行了几次),并且我已经验证了此处的“签名者”步骤确实生成了一个据称有效的令牌。

此外,lambda 具有

rds-db:connect
的权限,我什至为 lambda 角色添加了 RDS 完全访问权限(尽管我认为这不是必需的)。

不过,当我尝试连接时,我只是得到了这个:

    "errorType": "Error",
    "errorMessage": "Access denied for user 'mydbuser'@'19.196.193.217' (using password: YES)",
    "code": "ER_ACCESS_DENIED_ERROR",
    "errno": 1045,
    "sqlState": "28000",
    "sqlMessage": "Access denied for user 'mydbuser'@'19.196.193.217' (using password: YES)",

我还注意到我得到的令牌有一些 URL 编码位,所以我尝试对其进行 URL 解码,但这并没有导致任何结果。

我不知道这可能会在哪里失败,而且错误消息完全没有帮助。相关用户的补助金是:

GRANT USAGE ON *.* TO 'mydbuser'@'%'
GRANT ALL PRIVILEGES ON `mydbuser`.* TO 'mydbuser'@'%'

所以这暗示它不接受令牌作为密码。我的连接代码如下所示:

    const mysql = require('mysql2');
    ...
    signer.getAuthToken({
        region: 'my+region',
        hostname: process.env.ENDPOINT,
        port: 3306,
        username: 'mydbuser'
    }, function(err, token) {
            var connection = mysql.createConnection({
                host: process.env.ENDPOINT,
                port: 3306,
                user: 'mydbuser',
                password: token,
                database: 'mydb',
                ssl: { ca: fs.readFileSync(__dirname + '/rds-combined-ca-bundle.pem') },
                authSwitchHandler: function (data, cb) {
                    if (data.pluginName === 'mysql_clear_password') {
                        cb(null, Buffer.from(token + '\0'));
                    }
                }
            });

            connection.connect((res, err) => {
                console.log(res, err);
            });
        
            connection.query(
                    `SELECT 1;`, ...

此外,完整生成的令牌确实包含

X-Amz-Security-Token
,因此它暗示根据我迄今为止的研究,它是有效的。

此时还有什么可能失败?

authentication aws-lambda amazon-rds amazon-iam unauthorized
1个回答
0
投票

我用

Python
遇到了这个确切的问题,我花了很长时间才弄清楚。

我的问题不是数据库配置或 IAM 权限问题,而是与连接参数有关。我正在使用

AWS Aurora MySQL
连接到
sqlalchemy
+ 使用
pymysql
IAM Authentication
:

DBHostname = DBCLUSTER_HOSTNAME
DBPort = DBCLUSTER_PORT
DBUsername = DBCLUSTER_USER
DBName = DBCLUSTER_NAME

engine = sqlalchemy.create_engine(
    "mysql+pymysql:///"
)  # connection params will be set by the event callback

@sqlalchemy.event.listens_for(engine, "do_connect")
def provide_token(dialect, conn_rec, cargs, cparams):
    client = boto3.client("rds")
    token = client.generate_db_auth_token(
        DBHostname=DBHostname,
        Port=int(DBPort),
        DBUsername=DBUsername,
        Region=REGION,
    )

    # set up db connection parameters, alternatively we can get these from boto3 describe_db_instances
    cparams["host"] = DBHostname
    cparams["port"] = int(DBPort)
    cparams["user"] = DBUsername
    cparams["password"] = token
    cparams["database"] = DBName
    cparams["ssl"] = {
        "ca": "ssl-ca-bundle.pem",
        "verify_identity": False,
    }
    cparams["auth_plugin_map"] = {
        "mysql_clear_password": None,
    }
© www.soinside.com 2019 - 2024. All rights reserved.