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

本地Mac通过SSH连接MongoDB Atlas失败,求可行解决方案

本地Mac通过SSH连接MongoDB Atlas数据库的可行方案

问题背景

  • MongoDB Atlas连接URI:mongodb+srv://user:pass@cluster0.something.mongodb.net/
  • 已将Ubuntu服务器IP(111.111.111.111)加入Atlas白名单,该服务器上用mongosh可正常连接Atlas
  • 尝试两种方法均失败:

方法1:SSH隧道失败

执行命令:

ssh -L 27030:cluster0.something.mongodb.net:27017 -p 22 user@111.111.111.111

Compass连接URI:

mongodb://mongo_user:mongo_pass@localhost:27030/?authSource=admin

报错:channel 3: open failed: connect failed: No address associated with hostname

方法2:Golang+Nginx反向代理失败

Golang代码:

func main() {
    mongoURI := "mongodb+srv://user:pass@cluster0.something.mongodb.net/"
    sshHost := "111.111.111.111"
    sshPort := "22"
    sshUser := "user"
    sshPass := "pass"

    sshConfig := &ssh.ClientConfig{
        User: sshUser,
        Auth: []ssh.AuthMethod{
            ssh.Password(sshPass),
        },
        HostKeyCallback: ssh.InsecureIgnoreHostKey(),
    }

    sshClient, err := ssh.Dial("tcp", fmt.Sprintf("%v:%v", sshHost, sshPort), sshConfig)
    if err != nil {
        log.Fatalf("Failed to dial SSH: %v", err)
    }
    defer sshClient.Close()

    mongoOptions := options.Client().ApplyURI(mongoURI)

    listener, err := sshClient.Listen("tcp", "localhost:27030")
    if err != nil {
        log.Fatalf("Failed to create SSH tunnel: %v", err)
    }
    defer listener.Close()

    mongoClient, err := mongo.Connect(nil, mongoOptions)
    if err != nil {
        log.Fatalf("Failed to connect to MongoDB: %v", err)
    }
    defer mongoClient.Disconnect(nil)

    fmt.Println("Connected to MongoDB over SSH")
}

Nginx配置:

# 在nginx.conf的http块上方添加
stream {
    server {
        listen  27030;
        proxy_connect_timeout 1s;
        proxy_timeout 3s;
        proxy_pass    stream_mongo_backend;
    }

    upstream stream_mongo_backend {
        server cluster0.something.mongodb.net:27017;
    }
}

失败原因分析

  1. SSH隧道问题:cluster0.something.mongodb.net是SRV记录,SSH隧道无法解析SRV域名背后的多节点集群,直接映射单个域名端口会导致地址解析失败。
  2. Golang+Nginx问题:Golang代码仅建立SSH连接和本地监听,未处理流量转发逻辑;Nginx的stream代理无法解析SRV记录,仅能代理单个固定地址,适配不了Atlas的多节点架构。

可行方案

方案1:SOCKS5代理转发(快速生效)

利用SSH的SOCKS5代理功能,让本地MongoDB请求通过Ubuntu服务器转发,自动解析SRV记录:

  1. 建立SOCKS5代理:
ssh -D 8080 -C -q -N user@111.111.111.111

参数说明:

  • -D 8080:在本地8080端口创建SOCKS5代理
  • -C:压缩传输数据
  • -q:静默模式
  • -N:仅转发端口,不执行远程命令
  1. 配置本地客户端:
  • Compass:进入Advanced Options,勾选Use SOCKS5 Proxy,填写localhost:8080
  • mongosh:
mongosh "mongodb+srv://user:pass@cluster0.something.mongodb.net/" --proxy socks5://localhost:8080

方案2:修改Golang代码实现隧道转发

通过自定义Dialer,让MongoDB客户端的所有连接请求都通过SSH隧道发送,自动适配SRV解析:

package main

import (
    "context"
    "fmt"
    "log"
    "net"
    "golang.org/x/crypto/ssh"
    "go.mongodb.org/mongo-driver/mongo"
    "go.mongodb.org/mongo-driver/mongo/options"
)

func main() {
    mongoURI := "mongodb+srv://user:pass@cluster0.something.mongodb.net/"
    sshHost := "111.111.111.111"
    sshPort := "22"
    sshUser := "user"
    sshPass := "pass"

    // 配置SSH客户端
    sshConfig := &ssh.ClientConfig{
        User: sshUser,
        Auth: []ssh.AuthMethod{
            ssh.Password(sshPass),
        },
        HostKeyCallback: ssh.InsecureIgnoreHostKey(),
    }

    sshClient, err := ssh.Dial("tcp", fmt.Sprintf("%s:%s", sshHost, sshPort), sshConfig)
    if err != nil {
        log.Fatalf("SSH连接失败: %v", err)
    }
    defer sshClient.Close()

    // 自定义Dialer,通过SSH隧道建立MongoDB连接
    mongoOptions := options.Client().ApplyURI(mongoURI).SetDialer(func(ctx context.Context, network, addr string) (net.Conn, error) {
        return sshClient.Dial(network, addr)
    })

    // 连接并验证MongoDB
    ctx := context.Background()
    mongoClient, err := mongo.Connect(ctx, mongoOptions)
    if err != nil {
        log.Fatalf("MongoDB连接失败: %v", err)
    }
    defer mongoClient.Disconnect(ctx)

    if err := mongoClient.Ping(ctx, nil); err != nil {
        log.Fatalf("连接验证失败: %v", err)
    }

    fmt.Println("已通过SSH隧道连接MongoDB Atlas")
}

方案3:部署MongoDB Atlas代理(推荐长期使用)

使用MongoDB官方提供的Atlas代理部署在Ubuntu服务器上,本地直接连接代理即可:

  1. 在Ubuntu服务器安装代理:
curl -fsSL https://atlas.mongodb.com/atlas-proxy/install.sh | bash
  1. 从MongoDB Atlas控制台获取代理配置文件(需开启集群代理功能)
  2. 启动代理:
atlas-proxy start --config /path/to/proxy-config.json
  1. 本地连接代理地址:
mongodb+srv://user:pass@localhost:27017/

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 15:30:22