SSL Connections安全套接字连接

Mongoose supports connecting to MongoDB clusters that require SSL connections. Mongoose支持连接到需要SSL连接的MongoDB集群Setting the ssl option to true in mongoose.connect() or your connection string is enough to connect to a MongoDB cluster using SSL:mongoose.connect()中将ssl选项设置为true或您的连接字符串足以使用SSL连接到MongoDB集群:

mongoose.connect('mongodb://127.0.0.1:27017/test', { ssl: true });

// Equivalent:
mongoose.connect('mongodb://127.0.0.1:27017/test?ssl=true');

The ssl option defaults to false for connection strings that start with mongodb://. 对于以mongodb://开头的连接字符串,ssl选项默认为falseHowever, the ssl option defaults to true for connection strings that start with mongodb+srv://. 但是,对于以mongodb+srv://开头的连接字符串,ssl选项默认为trueSo if you are using an srv connection string to connect to MongoDB Atlas, SSL is enabled by default.因此,如果您使用srv连接字符串连接到MongoDB Atlas,则默认情况下会启用SSL。

If you try to connect to a MongoDB cluster that requires SSL without enabling the ssl option, mongoose.connect() will error out with the below error:如果您试图在不启用ssl选项的情况下连接到需要SSL的MongoDB集群,mongoose.connect()将出错,并显示以下错误:

MongooseServerSelectionError: connection <monitor> to 127.0.0.1:27017 closed
at NativeConnection.Connection.openUri (/node_modules/mongoose/lib/connection.js:800:32)
...

SSL ValidationSSL验证

By default, Mongoose validates the SSL certificate against a certificate authority to ensure the SSL certificate is valid. 默认情况下,Mongoose根据证书颁发机构验证SSL证书,以确保SSL证书有效。To disable this validation, set the sslValidate option to false.要禁用此验证,请将sslValidate选项设置为false

mongoose.connect('mongodb://127.0.0.1:27017/test', {
ssl: true,
sslValidate: false
});

In most cases, you should not disable SSL validation in production. However, sslValidate: false is often helpful for debugging SSL connection issues. 在大多数情况下,您不应该在生产中禁用SSL验证。但是,sslValidate:false通常有助于调试SSL连接问题。If you can connect to MongoDB with sslValidate: false, but not with sslValidate: true, then you can confirm Mongoose can connect to the server and the server is configured to use SSL correctly, but there's some issue with the SSL certificate.如果您可以使用sslValidate:false连接到MongoDB,但不能使用sslValidate:true连接到Mongoose,那么您可以确认Mongoose可以连接到服务器,并且服务器已配置为正确使用SSL,但SSL证书存在一些问题。

For example, a common issue is the below error message:例如,一个常见问题是以下错误消息:

MongooseServerSelectionError: unable to verify the first certificate

This error is often caused by self-signed MongoDB certificates or other situations where the certificate sent by the MongoDB server is not registered with an established certificate authority. 此错误通常是由自签名的MongoDB证书或MongoDB服务器发送的证书未在已建立的证书颁发机构注册的其他情况引起的。The solution is to set the sslCA option, which essentially sets a list of allowed SSL certificates.解决方案是设置sslCA选项,该选项本质上设置了允许的SSL证书的列表。

await mongoose.connect('mongodb://127.0.0.1:27017/test', {
ssl: true,
sslValidate: true,
// For example, see https://medium.com/@rajanmaharjan/secure-your-mongodb-connections-ssl-tls-92e2addb3c89
// for where the `rootCA.pem` file comes from.
// Please note that, in Mongoose >= 5.8.3, `sslCA` needs to be
// the **path to** the CA file, **not** the contents of the CA file
sslCA: `${__dirname}/rootCA.pem`
});

Another common issue is the below error message:另一个常见问题是以下错误消息:

MongooseServerSelectionError: Hostname/IP does not match certificate's altnames: Host: hostname1. is not cert's CN: hostname2

The SSL certificate's common name must line up with the host name in your connection string. SSL证书的通用名称必须与连接字符串中的主机名一致。If the SSL certificate is for hostname2.mydomain.com, your connection string must connect to hostname2.mydomain.com, not any other hostname or IP address that may be equivalent to hostname2.mydomain.com. 如果SSL证书是针对hostname2.mydomain.com的,则您的连接字符串必须连接到hostname2.mydomain.com,而不是任何其他可能等效于hostname2.mydomain.com的主机名或IP地址。For replica sets, this also means that the SSL certificate's common name must line up with the machine's hostname.对于副本集,这也意味着SSL证书的通用名称必须与计算机的主机名一致。

X509 Auth

If you're using X509 authentication, you should set the user name in the connection string, not the connect() options.如果使用X509身份验证,则应在连接字符串中设置用户名,而不是connect()选项。

// Do this:
const username = 'myusername';
await mongoose.connect(`mongodb://${encodeURIComponent(username)}@127.0.0.1:27017/test`, {
ssl: true,
sslValidate: true,
sslCA: `${__dirname}/rootCA.pem`,
authMechanism: 'MONGODB-X509'
});

// Not this:
await mongoose.connect('mongodb://127.0.0.1:27017/test', {
ssl: true,
sslValidate: true,
sslCA: `${__dirname}/rootCA.pem`,
authMechanism: 'MONGODB-X509',
auth: { username }
});