You need to enable JavaScript to run this app.
导航

客户端使用 SSL 加密连接 MongoDB

最近更新时间2023.03.31 14:55:37

首次发布时间2023.03.31 14:07:25

文档数据库 MongoDB 版提供了 SSL(Secure Sockets Layer)加密服务,您可以提前开启 SSL 加密功能,在连接数据库时,通过设置 SSL 加密提高数据链路的安全性。本文介绍多语言客户端通过 SSL 加密连接来访问 MongoDB 数据库的具体方法。

前提条件

  • MongoDB 实例已开启 SSL 加密功能,详情请参见设置 SSL 加密
  • 已将安装了客户端的本地服务器或 ECS 实例的 IP 地址加入到 MongoDB 实例的白名单中。详细操作步骤,请参见设置白名单

注意事项

通过私网访问 MongoDB 实例相对较安全,一般无需对数据链路加密。使用 SSL 加密连接会增加 MongoDB 实例的 CPU 使用率,建议仅在有加密需求(例如通过公网连接数据库)时启用 SSL 加密。

客户端 SSL 连接示例

说明

  • 文档数据库 MongoDB 版支持副本集和分片集群两种实例类型,不同类型的实例提供的连接地址不同。您可以登录 MongoDB 控制台,在 连接管理 页签下查看并复制所需的连接地址。关于 MongoDB 连接地址的更多说明,请参见连接地址类型
  • 本文档中示例中均使用了各语言最新版本的客户端。

C

  • 相关链接MongoDB C Driver

  • 代码说明
    您需要根据如下步骤,在 C 客户端代码中设置如下参数:

    1. 在客户端 URI 的末尾增加 ssl=true 参数,表示启用 SSL 加密连接。
    2. 您可以通过 mongoc_ssl_opt_t 参数配置 SSL 加密连接。其中:
      1. ssl_opts.ca_file 字段中设置 CA 证书的路径。
      2. ssl_opts.allow_invalid_hostname 字段设置为 false,表示忽略域名检测。

      说明

      关于 mongoc_ssl_opt_t 参数的更多说明,请参见 mongoc_ssl_opt_t

    代码示例如下。

    mongoc_client_t *client = NULL;
    
    client = mongoc_client_new (
          /* 下述代码中以副本集实例私网连接地址为例*/
          "mongodb://<user>:<password>@mongoreplicae9d7d321****0.mongodb.ivolces.com:3717,mongoreplicae9d7d321****1.mongodb.ivolces.com:3717/?authSource=admin&replicaSet=rs-mongo-replica-e9d7d321****&retryWrites=true&ssl=true");
    const mongoc_ssl_opt_t *ssl_default = mongoc_ssl_opt_get_default ();
    mongoc_ssl_opt_t ssl_opts = { 0 };
    
    /* optionally copy in a custom trust directory or file; otherwise the default is used. */
    memcpy (&ssl_opts, ssl_default, sizeof ssl_opts);
    ssl_opts.ca_file = "/path/to/ca.pem"
    ssl_opts.allow_invalid_hostname = false
    mongoc_client_set_ssl_opts (client, &ssl_opts);
    

C ++

  • 相关链接MongoDB C++ Driver

  • 代码说明
    您需要根据如下步骤,在 C++ 客户端代码中设置如下参数:

    1. 在客户端 URI 的末尾增加 ssl=true 参数,表示启用 SSL 加密连接。
    2. 您可以通过 mongoc_ssl_opt_t 参数配置 SSL 加密连接,您需要在 ssl_options.ca_file 字段中设置 CA 证书的路径。

      说明

      • 关于 mongoc_ssl_opt_t 参数的更多说明,请参见 mongoc_ssl_opt_t
      • mongocxx 驱动现不支持忽略域名检测。

    代码示例如下。

    #include <mongocxx/client.hpp>
    #include <mongocxx/uri.hpp>
    #include <mongocxx/options/client.hpp>
    #include <mongocxx/options/ssl.hpp>
    
    mongocxx::options::client client_options;
    mongocxx::options::ssl ssl_options;
    
    // If the server certificate is not signed by a well-known CA,
    // you can set a custom CA file with the `ca_file` option.
    ssl_options.ca_file("/path/to/ca.pem");
    
    client_options.ssl_opts(ssl_options);
    
    auto client = mongocxx::client{
        // 下述代码中以副本集实例私网连接地址为例
        uri{"mongodb://<user>:<password>@mongoreplicae9d7d321****0.mongodb.ivolces.com:3717,mongoreplicae9d7d321****1.mongodb.ivolces.com:3717/?authSource=admin&replicaSet=rs-mongo-replica-e9d7d321****&retryWrites=true&ssl=true"}, client_opts};
    

Golang

  • 相关链接MongoDB Golang DriverCrypto tls package

  • 代码说明
    Golang 驱动程序使用 crypto/tls 包提供的 SSL 底层支持与 MongoDB 服务器进行 SSL 连接。您需要根据如下步骤,在客户端代码中设置 SSL 连接参数:

    1. 在客户端 URI 的末尾增加 ssl=true 参数,表示启用 SSL 加密连接。
    2. tlsConfig 结构中,设置如下配置:
      1. 通过 RootCAs 参数来指定 CA 证书。
      2. InsecureSkipVerify 设置为 true,表示忽略域名检测。

    代码示例如下。

    package main
    
    import (
        "context"
        "crypto/tls"
        "crypto/x509"
        "fmt"
        "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"
        "go.mongodb.org/mongo-driver/mongo/writeconcern"
        "io/ioutil"
        "log"
    )
    
    func main() {
        var filename = "ca.pem"
        rootPEM, err := ioutil.ReadFile(filename)
        roots := x509.NewCertPool()
        if ok := roots.AppendCertsFromPEM([]byte(rootPEM)); !ok {
            fmt.Printf("get certs from %s fail!\n", filename)
            return
        }
        tlsConfig := &tls.Config{
            RootCAs: roots,
            InsecureSkipVerify: true,
        }
    
        // Create a Client to a MongoDB server and use Ping to verify that the
        // server is running.
        // 下述代码中以副本集实例私网连接地址为例
        clientOpts := options.Client().ApplyURI("mongodb://<user>:<password>@mongoreplicae9d7d321****0.mongodb.ivolces.com:3717,mongoreplicae9d7d321****1.mongodb.ivolces.com:3717/?authSource=admin&replicaSet=rs-mongo-replica-e9d7d321****&retryWrites=true&ssl=true")
        clientOpts.SetReadPreference(readpref.Secondary())
        clientOpts.SetWriteConcern(writeconcern.New(writeconcern.WMajority(), writeconcern.J(true), writeconcern.WTimeout(1000)))
        clientOpts.SetTLSConfig(tlsConfig)
        client, err := mongo.Connect(context.TODO(), clientOpts)
        if err != nil {
            fmt.Println("connect failed!")
            log.Fatal(err)
            return
        }
        fmt.Println("connect successful!")
    
        defer func() {
            if err = client.Disconnect(context.TODO()); err != nil {
                fmt.Println("disconnect failed!")
                log.Fatal(err)
            }
            fmt.Println("disconnect successful!")
        }()
    
        // Call Ping to verify that the deployment is up and the Client was
        // configured successfully. As mentioned in the Ping documentation, this
        // reduces application resiliency as the server may be temporarily
        // unavailable when Ping is called.
        if err = client.Ping(context.TODO(), nil); err != nil {
            fmt.Println("ping failed!")
            log.Fatal(err)
            return
        }
        fmt.Println("ping successful!")
    
        collection := client.Database("baz").Collection("qux")
        res, err := collection.InsertOne(context.Background(), bson.M{"hello": "world"})
        if err != nil {
            fmt.Println("insert result failed!")
            log.Fatal(err)
            return
        }
        id := res.InsertedID
        fmt.Println("Id: ", id)
        fmt.Printf("insert result: %v\n", res)
    
        result := bson.M{}
        filter := bson.D{{"_id", res.InsertedID}}
        if err := collection.FindOne(context.Background(), filter).Decode(&result); err != nil {
            fmt.Println("find failed!")
            log.Fatal(err)
            return
        }
    
        fmt.Printf("result: %v\n", result)
    }
    

Java

  • 相关链接MongoDB Java Driver
  • 代码说明
    您需要根据如下步骤,在 Java 客户端代码中设置 SSL 连接参数:
    1. 设置 MongoClientOptions参数组,具体配置如下:

      1. sslEnabled 设置为 true,表示启用 SSL 连接。
      2. sslInvalidHostNameAllowed 设置为 true,表示忽略域名检测。

      代码示例如下。

      import com.mongodb.MongoClientURI;
      import com.mongodb.MongoClientOptions;
      MongoClientOptions options= MongoClientOptions.builder().sslEnabled(true).sslInvalidHostNameAllowed(true).build();
      MongoClient client = new MongoClient("mongodb://<user>:<password>@mongoreplicae9d7d321****0.mongodb.ivolces.com:3717,mongoreplicae9d7d321****1.mongodb.ivolces.com:3717/?authSource=admin&replicaSet=rs-mongo-replica-e9d7d321****&retryWrites=true", options)
      
    2. 使用 keytool 工具设置 CA 证书。
      代码示例如下。

      keytool -importcert -trustcacerts -file <path to certificate authority file> 
              -keystore <path to trust store> -storepass <password>
      
    3. 在 Java 程序中设置 JVM 系统属性,确保指向正确的信任库和密钥库。
      代码示例如下。

      System.setProperty("javax.net.ssl.trustStore","/trust/mongoStore.ts");
      System.setProperty("javax.net.ssl.trustStorePassword","StorePass");
      

Node.js

  • 相关链接MongoDB Node.js Driver

  • 代码说明
    您需要根据如下步骤,在 Node.js 客户端代码中设置相关参数:

    1. 在客户端 URI 的末尾增加 ssl=true 参数,表示启用 SSL 加密连接。
    2. 通过 sslCA 参数指向 CA 证书路径。
    3. checkServerIndentity 设置为 false,表示忽略域名检测。

    代码示例如下。

    var MongoClient = require('mongodb').MongoClient
    // Read the certificate authority
    var ca = "/path/to/ca.pem"
    // Connect validating the returned certificates from the server
    // 下述代码中以副本集实例私网连接地址为例
    MongoClient.connect("mongodb://<user>:<password>=@mongoreplicae9d7d321****0.mongodb.ivolces.com:3717,ongoreplicae9d7d321****1.mongodb.ivolces.com:3717/?authSource=admin", {
        sslValidate:true,
        checkServerIdentity:false,
        sslCA: ca
    }, async function(err, db) {
      db.close();
    });
    

.NET Core

您可以参考如下步骤,通过 .NET Core 驱动程序使用 SSL 加密连接来访问 MongoDB 数据库:

  1. 安装 .NET。安装方法,请参见 Download .NET

  2. 执行如下命令创建一个项目(本文示例中项目名录名称为 MongoDB)。

    dotnet new console -o MongoDB
    
  3. 执行如下命令进入新创建的目录。

    cd MongoDB
    
  4. 使用如下命令安装 MongoDB 的 .NET Core 驱动包。

    dotnet add package mongocsharpdriver --version 2.11.5
    
  5. 在客户端代码中设置 SSL 连接参数。
    代码示例如下。

    using System;
    using System.Collections.Generic;
    using System.Security.Cryptography.X509Certificates;
    using MongoDB.Bson;
    using MongoDB.Driver;namespace dotnetCase
    {
    class Program
    {
    static void Main(string[] args)
    {
    //MongoDB 实例信息。
    const string host1 = "mongoreplicae9d7d321****0.mongodb.ivolces.com";
    const int port1 = 3717;
    const string host2 = "mongoreplicae9d7d321****1.mongodb.ivolces.com";
    const int port2 = 3717;
    const string replicaSetName = "rs-mongo-replica-e9d7d321****"; // 分片集群实例连接地址无需设置该参数
    const string admin = "admin";
    const string userName = "root";
    const string passwd = "********";        
    try
            {
                // 设置连接 host 信息。
                MongoClientSettings settings = new MongoClientSettings();
                List<MongoServerAddress> servers = new List<MongoServerAddress>();
                servers.Add(new MongoServerAddress(host1, port1));
                servers.Add(new MongoServerAddress(host2, port2));
                settings.Servers = servers;
                // 设置副本集名称(分片集群实例无需设置该参数)。
                settings.ReplicaSetName = replicaSetName;
                // 设置超时时间为 3 秒。
                settings.ConnectTimeout = new TimeSpan(0, 0, 0, 3, 0);
                // 设置登录用户名和密码。
                MongoCredential credentials = MongoCredential.CreateCredential(admin, userName, passwd);
                settings.Credential = credentials;
                // 设置 SSL 信息。
                SslSettings sslSettings = new SslSettings{
                    ClientCertificates = new[] {new X509Certificate("ca.pem")},
                };
                settings.UseTls = true;
                settings.AllowInsecureTls = true;
                settings.SslSettings = sslSettings;
                // 初始化客户端。
                MongoClient client = new MongoClient(settings);
            }
            catch (Exception e)
            {
                Console.WriteLine("连接异常:"+e.Message);
            }
        }
    }
    }
    

PHP

  • 相关链接MongoDB PHP Driver

  • 代码说明
    您需要根据如下步骤,创建一个 PHP Client,并在客户端代码中设置 SSL 连接参数:

    1. ssl 设置为 true,表示启用 SSL 加密连接。
    2. ca_file 中设置 CA 证书路径。
    3. allow_invalid_hostname 设置为 true,表示忽略域名检测。

    代码示例如下。

    <?php  
    // 下述代码中以副本集实例私网连接地址为例
    $manager = new MongoDB\Driver\Manager('mongodb://<user>:<password>=@mongoreplicae9d7d321****0.mongodb.ivolces.com:3717,ongoreplicae9d7d321****1.mongodb.ivolces.com:3717/?authSource=admin',
    [   'ssl' => true,
    /* 分片集群实例连接地址无需设置如下参数 */
    'replicaSet' => 'rs-mongo-replica-e9d7d321****'  
        ],
        [
            "ca_file" => "/path/to/ca.pem",
            "allow_invalid_hostname" => true
        ]
    );
    

Python

  • 相关链接MongoDB Python Driver

  • 代码说明
    您需要根据如下步骤,在 Python 客户端代码中设置 SSL 连接参数:

    1. ssl 参数设置为 True,表示启用 SSL 加密连接。
    2. 通过 ssl_ca_certs 参数设置 CA 证书的路径。
    3. ssl_match_hostname 设置为 False,表示忽略域名检测。

    代码示例如下。

    import ssl
    from pymongo import MongoClient
        
    uri = "mongodb://<user>:<password>@mongoreplicae9d7d321****0.mongodb.ivolces.com:3717,mongoreplicae9d7d321****1.mongodb.ivolces.com:3717/?authSource=admin&replicaSet=rs-mongo-replica-e9d7d321****&retryWrites=true"
    client = MongoClient(uri,
                         ssl=True,
                         ssl_ca_certs='ca.pem',
                         ssl_match_hostname=False)
    

Scala

  • 相关链接MongoDB Scala Driver
  • 代码说明
    Scala 驱动程序使用 Netty 提供的 SSL 底层支持与 MongoDB 服务器进行 SSL 连接。您需要根据如下步骤,在客户端代码中设置 SSL 连接参数:
    1. MongoClientOptions 参数组中,设置 sslSettings 中的如下配置。

      1. enabled 设置为 true,表示启用 SSL 连接。
      2. invalidHostNameAllowed 设置为 true,表示忽略域名检测。

      代码示例如下。

      import org.mongodb.scala.connection.{NettyStreamFactoryFactory, SslSettings}
      
      MongoClientSettings.builder()
                         .sslSettings(SslSettings.builder()
                                                 .enabled(true)                 
                                                 .invalidHostNameAllowed(true)  
                                                 .build())                      
                         .streamFactoryFactory(NettyStreamFactoryFactory())
                         .build()
      // 下述代码中以副本集实例私网连接地址为例
      val client: MongoClient = MongoClient("mongodb://<user>:<password>@mongoreplicae9d7d321****0.mongodb.ivolces.com:3717,mongoreplicae9d7d321****1.mongodb.ivolces.com:3717/?authSource=admin&replicaSet=rs-mongo-replica-e9d7d321****&retryWrites=true")
      
    2. 使用 keytool 工具设置 CA 证书。
      代码示例如下。

      keytool -importcert -trustcacerts -file <path to certificate authority file> 
              -keystore <path to trust store> -storepass <password>
      
    3. 在程序中设置 JVM 系统属性,确保指向正确的信任库和密钥库。

      System.setProperty("javax.net.ssl.trustStore","/trust/mongoStore.ts");
      System.setProperty("javax.net.ssl.trustStorePassword","StorePass");