Amazon DocumentDB认证失败(code:18)排查求助
Amazon DocumentDB 认证失败(MongoDB code:18)求助
问题描述
连接Amazon DocumentDB时遇到MongoDB code:18认证失败错误,错误信息如下:
{ "errorResponse": { "ok": 0, "errmsg": "Authentication failed.", "code": 18, "operationTime": { "$timestamp": "7415236078489042945" } }, "ok": 0, "code": 18, "operationTime": { "$timestamp": "7415236078489042945" }, "connectionGeneration": 0 }
连接URL:
mongodb://user:pass@databaseservicedatabasexxxxx.cluster-xxxxx.us-east-1.docdb.amazonaws.com:27017/?replicaSet=rs0&readPreference=secondaryPreferred&retryWrites=false
已尝试的操作:
- 更新Amazon DocumentDB证书为
rds-ca-rsa2048-g1 - 将Mongoose升级至^8.6.2
- Lambda函数使用Node.js 18
连接代码示例:
const connection = await mongoose .createConnection(CONNECTION_URL, { dbName: DB_NAME, }) .asPromise();
该连接一个月前可正常使用,基础设施CDK代码如下:
export class DatabaseService extends Construct { public readonly instance: DatabaseCluster; public readonly connectionUrl: string; constructor(scope: Construct, id: string, vpc: Vpc) { super(scope, id); const databasePasswordSecret = new Secret(this, "Database Password", { secretName: getStandarizedName(["database", "secret"]), generateSecretString: { excludePunctuation: true, excludeCharacters: "/¥'%:;{}", }, }); const parameterGroup = new ClusterParameterGroup( this, getStandarizedName(["parameter", "group"]), { family: DOCDB_FAMILY, parameters: { tls: "disabled", }, } ); const securityGroup = new SecurityGroup(this, "SecurityGroup", { vpc, allowAllOutbound: true, }); securityGroup.addIngressRule( Peer.anyIpv4(), Port.tcp(27017), "Allow connections from deployed services" ); this.instance = new DatabaseCluster(this, "Database", { masterUser: { username: env.DATABSE_MASTER_USERNAME, password: SecretValue.secretsManager(databasePasswordSecret.secretArn), }, instanceType: isProduction ? PRODUCTION_INSTANCE_TYPE : DEVELOPMENT_INSTANCE_TYPE, vpc, vpcSubnets: { subnetType: SubnetType.PRIVATE_ISOLATED, }, instances: env.DATABASE_NODES_COUNT, parameterGroup, deletionProtection: isProduction, storageEncrypted: true, securityGroup, }); new StringParameter(this, getStandarizedName(["db", "url"]), { stringValue: this.instance.clusterEndpoint.socketAddress, parameterName: getStandarizedName(["db", "url"]), }); this.connectionUrl = `${MONGODB_PREFIX}${ env.DATABSE_MASTER_USERNAME }:${databasePasswordSecret.secretValue.unsafeUnwrap()}@${ this.instance.clusterEndpoint.socketAddress }${MONGODB_SUFFIX}`; } }
解决方案与排查步骤
1. 修正用户名拼写错误
注意到CDK代码中使用了env.DATABSE_MASTER_USERNAME,变量名存在拼写错误(应为DATABASE_MASTER_USERNAME,少了字母A)。如果环境变量的实际键名是正确的DATABASE_MASTER_USERNAME,会导致加载错误的用户名,直接引发认证失败。
2. 验证密码有效性
databasePasswordSecret.secretValue.unsafeUnwrap()会在CDK部署时获取密码快照,如果之后Secret Manager中的密码被轮换,Lambda环境中的连接URL不会自动更新。解决方法:- 重新部署CDK栈,更新连接URL中的密码
- 改为在Lambda运行时动态从Secret Manager拉取最新密码,避免依赖部署时的快照
3. 解决TLS配置冲突
你的DocumentDB参数组设置了tls: "disabled",但Mongoose默认会启用SSL连接,协议不匹配会导致认证失败:
- 在Mongoose连接选项中显式禁用SSL:
const connection = await mongoose .createConnection(CONNECTION_URL, { dbName: DB_NAME, ssl: false // 添加此配置 }) .asPromise();
- 或者在连接URL中添加
ssl=false参数:
mongodb://user:pass@xxxxxx.docdb.amazonaws.com:27017/?replicaSet=rs0&readPreference=secondaryPreferred&retryWrites=false&ssl=false
- 确认参数组的TLS设置已生效:修改参数组后需要重启DocumentDB实例,配置才会生效
4. 确认数据库权限
- 验证
DB_NAME对应的数据库是否存在,且当前用户拥有该数据库的访问权限 - 使用Mongo Shell手动测试连接,确认用户权限:
use admin db.auth("your_username", "your_password") show dbs // 检查是否能看到目标数据库
5. 排除网络干扰
虽然code:18是认证错误,但仍需确认:
- Lambda函数所在VPC与DocumentDB的私有子网连通
- 安全组入站规则允许Lambda的IP/安全组访问27017端口
内容的提问来源于stack exchange,提问作者Hulubina
相关产品推荐
相关产品推荐

