一、说明

go连接MongoDB驱动库mongo-drivermgo.v2库中都不支持ssh认证连接的。但是我们可以使用net库先与MongoDB数据库服务器建立ssh连接,然后再将MongoDB数据库所在服务器端口映射到本地连接中转发就可以了。

二、使用

下面以mongo-driver数据库驱动为例。

安装

go get -u github.com/zngw/sshtunnel

实现代码

// @Title 
// @Description $
// @Author  55
// @Date  2021/11/7
package main

import (
	"context"
	"github.com/zngw/log"
	"github.com/zngw/sshtunnel/ssht"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
	"go.mongodb.org/mongo-driver/mongo/readpref"
	"net/url"
	"strings"
	"time"
)

func main() {
	sshUri := "ssh://root:123456@192.168.1.55:22"
	mdbUri := "mongodb://root:123456@127.0.0.1:27017/admin"

	u, err := url.Parse(mdbUri)
	if err != nil {
		log.Error("test", "解析数据库连接信息失败 %v", err)
		return
	}

	listen, err := ssht.TunnelUri(sshUri, u.Host, ":3717")
	if err != nil {
		log.Error("test", "启用ssh端口映射失败 %v", err)
	} else {
		log.Info("test", "启用ssh端口映射成功 %s", listen)
	}

	// 替换数据库地址端口
	mdbUri = strings.Replace(mdbUri, u.Host, listen, -1)

	// 下面按正常逻辑连接mongodb
	name := "Test"
	maxTime := time.Duration(2)     // 链接超时时间
	table := "test"                 // 表名

	// 连接数据库
	db, err := ConnectToDB(mdbUri, name, maxTime)
	if err != nil {
		log.Error("test","链接数据库有误!")
	}

	// 获取test表数据数量
	collection := db.Collection(table)
	count, err := collection.CountDocuments(context.Background(), bson.D{})
	if err != nil {
		log.Error("test", err.Error())
		return
	}

	log.Info("test","collection.CountDocuments: %v", count)
}

func ConnectToDB(uri, name string, timeout time.Duration) (*mongo.Database, error)  {
	// 设置连接超时时间
	ctx, cancel := context.WithTimeout(context.Background(), timeout)
	defer cancel()
	// 通过传进来的uri连接相关的配置
	o := options.Client().ApplyURI(uri)
	// 发起链接
	client, err := mongo.Connect(ctx, o)
	if err != nil {
		log.Error("test",err.Error())
		return nil, err
	}
	// 判断服务是不是可用
	if err = client.Ping(context.Background(), readpref.Primary()); err != nil {
		log.Error("test",err.Error())
		return nil, err
	}
	// 返回 client
	return client.Database(name), nil
}