使用AWS.RDS.Signer从Lambda连接RDS MySQL报访问被拒错误
AWS RDS IAM 连接失败问题排查
代码配置层面的错误
- 区域参数值错误:AWS RDS Signer要求传入纯区域标识,不包含可用区后缀。原代码配置的
ap-southeast-2a是可用区ID,不是合法的区域值,会导致生成的认证token签名和RDS实际校验规则不匹配,正确值应为ap-southeast-2。 - 认证插件配置不匹配:原配置下mysql2驱动的
mysql_clear_password插件触发逻辑存在问题,连接握手阶段没有把生成的IAM token作为凭据传递给RDS,最终触发Access denied for user ... (using password: NO)的报错。
RDS 侧缺失的配置
- 不存在“IAM认证必须配合RDS Proxy使用”的要求,直连RDS实例原生支持IAM token认证,你当前开启的“密码和IAM数据库认证”模式完全符合使用前提。
- 数据库内部的账号未关联RDS IAM认证插件:当前
anyuser是仅支持静态密码校验的普通账号,即便生成了合法的IAM token,数据库端也无法识别处理。你当前用静态密码可以正常连接,也侧面说明这个账号尚未开启IAM认证插件,仅支持静态密码校验逻辑。需要通过静态密码连接数据库,执行以下SQL修改账号属性:-- 为账号启用RDS官方IAM认证插件 ALTER USER 'anyuser'@'%' IDENTIFIED WITH AWSAuthenticationPlugin AS 'RDS'; -- 授予账号基础连接权限 GRANT USAGE ON *.* TO 'anyuser'@'%'; GRANT ALL PRIVILEGES ON anydb.* TO 'anyuser'@'%'; FLUSH PRIVILEGES; - 确认Lambda执行角色已绑定RDS连接权限策略,策略需要对应到目标RDS实例的ARN,开放
rds-db:connect动作并关联目标数据库用户名。
修正后的可用配置
const DB_REGION = 'ap-southeast-2' // 去掉可用区后缀 const DB_HOST = 'dbinstance.ddtev8utygt.ap-southeast-2.rds.amazonaws.com' const DB_PORT = 3306 const DB_USER = 'anyuser' const DB_NAME = 'anydb' const signerOptions = { region: DB_REGION, hostname: DB_HOST, port: DB_PORT, username: DB_USER } const signer = new AWS.RDS.Signer(signerOptions) const token = await signer.getAuthToken() const config = { host: DB_HOST, user: DB_USER, password: token, database: DB_NAME, ssl: 'Amazon RDS', // IAM认证强制要求SSL,该配置正确 authPlugins: { mysql_clear_password: () => () => token } }
内容的提问来源于stack exchange,提问作者Thomas Dittmar
相关产品推荐
相关产品推荐

