You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AWS Lambda通过IAM连接MongoDB Atlas超时问题求助

排查AWS Lambda连接MongoDB Atlas(IAM认证)超时问题

问题现象

连接时抛出socket超时异常:

com.mongodb.MongoSocketOpenException: Exception opening socket
    at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:73) ~[mongodb-driver-core-4.8.1.jar:?]
    at com.mongodb.internal.connection.InternalStreamConnection.open(InternalStreamConnection.java:183) ~[mongodb-driver-core-4.8.1.jar:?]
    at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitorRunnable.lookupServerDescription(DefaultServerMonitor.java:198) [mongodb-driver-core-4.8.1.jar:?]
    at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitorRunnable.run(DefaultServerMonitor.java:158) [mongodb-driver-core-4.8.1.jar:?]
    at java.lang.Thread.run(Unknown Source) [?:?]
Caused by: java.net.SocketTimeoutException: connect timed out
    at java.net.PlainSocketImpl.socketConnect(Native Method) ~[?:?]
    at java.net.AbstractPlainSocketImpl.doConnect(Unknown Source) ~[?:?]
    at java.net.AbstractPlainSocketImpl.connectToAddress(Unknown Source) ~[?:?]
    at java.net.AbstractPlainSocketImpl.connect(Unknown Source) ~[?:?]
    at java.net.SocksSocketImpl.connect(Unknown Source) ~[?:?]
    at java.net.Socket.connect(Unknown Source) ~[?:?]
    at sun.security.ssl.SSLSocketImpl.connect(Unknown Source) ~[?:?]
    at com.mongodb.internal.connection.SocketStreamHelper.initialize(SocketStreamHelper.java:107) ~[mongodb-driver-core-4.8.1.jar:?]
    at com.mongodb.internal.connection.SocketStream.initializeSocket(SocketStream.java:82) ~[mongodb-driver-core-4.8.1.jar:?]
    at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:68) ~[mongodb-driver-core-4.8.1.jar:?]
    ... 4 more

核心问题排查与修复

1. 网络连通性(超时首要原因)

socket超时本质是Lambda无法到达MongoDB Atlas的网络端点,分两种场景排查:

  • Lambda未配置VPC(默认模式):需要在MongoDB Atlas控制台的网络访问配置中,将0.0.0.0/0加入IP白名单(测试用,生产环境建议限制到Lambda的公网IP段)。
  • Lambda在VPC内运行:
    • 确保VPC的安全组允许出站访问MongoDB Atlas的端口(默认27017,或MongoDB+srv解析后的端口)。
    • 配置NAT网关并确保Lambda所在子网的路由表指向NAT网关,让Lambda能访问公网。
    • 将NAT网关的公网IP加入Atlas的IP白名单;或配置VPC peering直接连接Atlas的VPC(更安全)。

2. 代码中的认证凭证错误

你的代码存在两处关键错误:

  • 错误使用了原始的accessKeyId和secretAccessKey,而非assumeRole返回的临时会话凭证。
  • 错误调用stsClient.getSessionToken()获取会话Token,正确的Token应该来自assumeRole返回的sessionCredentials。

修正后的代码片段:

final String accessKeyId = System.getenv("AWS_ACCESS_KEY_ID");
final String secretAccessKey = System.getenv("AWS_SECRET_ACCESS_KEY");
final Regions region = Regions.US_EAST_1;
final BasicAWSCredentials credentials = new BasicAWSCredentials(accessKeyId, secretAccessKey);

final AWSSecurityTokenService stsClient = AWSSecurityTokenServiceClientBuilder.standard()
  .withCredentials(new AWSStaticCredentialsProvider(credentials))
  .withRegion(region)
  .build();

final AssumeRoleRequest roleRequest = new AssumeRoleRequest()
  .withRoleArn("<Role ARN>")
  .withRoleSessionName("my-session");
final AssumeRoleResult roleResponse = stsClient.assumeRole(roleRequest);
final Credentials sessionCredentials = roleResponse.getCredentials();

// 修正:使用assumeRole返回的临时凭证
final ConnectionString connectionString
  = new ConnectionString("mongodb+srv://" + sessionCredentials.getAccessKeyId() + ":" + sessionCredentials.getSecretAccessKey()
  + "@cluster.e.mongodb.net/?authSource=%24external&authMechanism=MONGODB-AWS&retryWrites=true&w=majority&authMechanismProperties=AWS_SESSION_TOKEN:"
  + sessionCredentials.getSessionToken());

final MongoClientSettings settings = MongoClientSettings.builder()
  .applyConnectionString(connectionString)
  .serverApi(ServerApi.builder()
    .version(ServerApiVersion.V1)
    .build())
  .build();
return MongoClients.create(settings);

最佳实践:Lambda运行时会自动注入执行角色的临时凭证,无需手动从环境变量获取,建议改用DefaultAWSCredentialsProviderChain替代硬编码的环境变量取值,提升安全性。

3. IAM权限配置问题

  • Lambda执行角色权限缺失:当前IAM策略中,sts:*的Resource是自身角色ARN,而非你要assume的目标角色ARN,导致无法成功调用sts:AssumeRole。需要修改策略,将目标角色ARN加入Resource列表:
    {
        "Effect": "Allow",
        "Action": "sts:AssumeRole",
        "Resource": "<你的目标角色ARN>"
    }
    
  • Atlas侧IAM权限未配置:需要在MongoDB Atlas控制台的「数据库访问」中,添加对应的IAM用户(即你assume的角色ARN),并授予所需的数据库权限(如readWrite)。
  • 冗余权限清理:当前策略中重复了sts:GetSessionToken,建议移除重复项。

4. 信任关系冗余

KuunganaApiRole的信任关系中,第三个Statement允许自身的assumed角色再assume自己,属于冗余配置,存在安全风险,建议直接删除该条目。

修复验证步骤

  1. 先确认网络连通性:在Lambda中添加测试代码,尝试telnet测试Atlas端点的端口,确认能正常访问。
  2. 修正代码后,测试凭证是否能正常通过Atlas的IAM认证。
  3. 检查CloudWatch日志,确认没有权限报错或凭证无效的信息。

内容的提问来源于stack exchange,提问作者Jacob Jeremiah

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 12:30:44