使用VS Code SAM构建Lambda函数连接VPC内MySQL RDS失败求助
解决Lambda通过SSH隧道连接VPC内RDS无报错但无法连接的问题
首先,我发现你的代码里没处理mysqlssh.connect()的Promise拒绝情况——这大概率是问题的核心!如果SSH连接本身失败了,你的代码不会抛出任何错误,看起来就像“没反应”。先给代码加个catch块,把具体错误打出来:
const fs = require('fs'); const mysqlssh = require('mysql-ssh'); mysqlssh.connect( { host: 'XXX.XXX.XX.XX', user: 'ec2-user', privateKey: fs.readFileSync('./XXXX-txlarge.pem') }, { host: '-staging-instanceXXXXX.rds.amazonaws.com', user: 'user', password: 'password', database: 'db' } ) .then(client => { client.query('SELECT * FROM users', function (err, results, fields) { if (err) throw err console.log(results); mysqlssh.close() }) }) .catch(err => { console.error('连接失败详情:', err); // 这里能看到SSH或数据库连接的具体错误信息 });
接下来按你的使用场景分情况排查:
场景1:本地用SAM CLI调试Lambda
- EC2安全组检查:确保你的本地公网IP被允许访问EC2的22端口(SSH)。去AWS控制台的EC2安全组里,添加入站规则,允许
你的本地公网IP/32访问22端口。 - RDS安全组检查:确认EC2的私有IP被允许访问RDS的3306端口。RDS的安全组入站规则要加
EC2的私有IP/32或者EC2所在的安全组,端口设为3306。 - 密钥文件权限与路径:本地调试时,
./XXXX-txlarge.pem的路径要准确,确保文件在SAM项目根目录;另外Linux/macOS下要把密钥权限改成600(执行chmod 600 XXXX-txlarge.pem),否则SSH会直接拒绝连接。
场景2:Lambda已部署到AWS
- Lambda的VPC配置:如果Lambda不在目标VPC里,根本没法直接访问VPC内的EC2和RDS。要把Lambda放到和EC2、RDS同VPC的子网里,同时给Lambda分配安全组,这个安全组要允许访问EC2的22端口。
- 安全组规则调整:EC2的安全组要允许Lambda所在的安全组访问22端口;RDS的安全组要允许EC2的私有IP或EC2所在安全组访问3306端口。
- 密钥文件的正确存储:Lambda里不能直接用本地的pem文件,建议把密钥放到AWS Secrets Manager或者S3里,在Lambda代码里读取。如果非要打包到部署包,要确保文件路径正确,并且把文件放到
/tmp目录后设置权限为600。 - Lambda执行角色权限:确保Lambda的IAM角色有创建VPC网络接口(ENI)的权限,以及访问Secrets Manager/S3(如果存密钥的话)的权限。
通用排查步骤
- 先手动验证EC2到RDS的连通性:SSH到EC2实例,用命令
mysql -h <RDS端点> -u user -p尝试连接RDS,如果这一步都失败,那隧道肯定也没法工作,先解决RDS本身的访问问题。 - 检查EC2的公网/内网可达性:如果是本地调试,EC2必须有弹性公网IP;如果Lambda在VPC内,用EC2的私有IP连接即可。
- 升级依赖版本:试试把
mysql-ssh升级到最新版本,可能存在版本兼容性问题导致的隐性错误。
内容的提问来源于stack exchange,提问作者Sonali
相关产品推荐
相关产品推荐

