TLS/SSL 连接
Mongoose 支持连接到 需要 TLS/SSL 连接的 MongoDB 集群。在 mongoose.connect()
或您的连接字符串中将 tls
选项设置为 true
就足以使用 TLS/SSL 连接到 MongoDB 集群。
mongoose.connect('mongodb://127.0.0.1:27017/test', { tls: true });
// Equivalent:
mongoose.connect('mongodb://127.0.0.1:27017/test?tls=true');
对于以 mongodb://
开头的连接字符串,tls
选项默认值为 false
。但是,对于以 mongodb+srv://
开头的连接字符串,tls
选项默认值为 true
。因此,如果您使用 srv 连接字符串连接到 MongoDB Atlas,则默认情况下会启用 TLS/SSL。
如果您尝试连接到需要 TLS/SSL 但未启用 tls
/ssl
选项的 MongoDB 集群,mongoose.connect()
将出现以下错误
TLS/SSL 验证
默认情况下,Mongoose 会将 TLS/SSL 证书与 证书颁发机构 进行验证,以确保 TLS/SSL 证书有效。要禁用此验证,请将 tlsAllowInvalidCertificates
(或 tlsInsecure
)选项设置为 true
。
mongoose.connect('mongodb://127.0.0.1:27017/test', {
tls: true,
tlsAllowInvalidCertificates: true,
});
在大多数情况下,您不应在生产环境中禁用 TLS/SSL 验证。但是,tlsAllowInvalidCertificates: true
通常有助于调试 SSL 连接问题。如果您可以在 tlsAllowInvalidCertificates: true
的情况下连接到 MongoDB,但在 tlsAllowInvalidCertificates: false
的情况下无法连接,那么您可以确认 Mongoose 可以连接到服务器,并且服务器已正确配置为使用 TLS/SSL,但证书存在一些问题。
例如,常见的错误消息如下
MongooseServerSelectionError: unable to verify the first certificate此错误通常是由 自签名 MongoDB 证书 或其他情况导致的,在这种情况下,MongoDB 服务器发送的证书未在已建立的证书颁发机构中注册。解决办法是设置 tlsCAFile
选项,它实际上设置了允许的 SSL 证书列表。
await mongoose.connect('mongodb://127.0.0.1:27017/test', {
tls: true,
// For example, see https://medium.com/@rajanmaharjan/secure-your-mongodb-connections-ssl-tls-92e2addb3c89
// for where the `rootCA.pem` file comes from.
tlsCAFile: `${__dirname}/rootCA.pem`,
});
另一个常见的问题是以下错误消息
MongooseServerSelectionError: Hostname/IP does not match certificate's altnames: Host: hostname1. is not cert's CN: hostname2SSL 证书的 通用名称 **必须** 与您的连接字符串中的主机名一致。如果 SSL 证书用于 hostname2.mydomain.com
,则您的连接字符串必须连接到 hostname2.mydomain.com
,而不是任何其他主机名或 IP 地址,这些主机名或 IP 地址可能等效于 hostname2.mydomain.com
。对于副本集,这也意味着 SSL 证书的通用名称必须与 机器的 hostname
一致。要禁用此验证,请将 tlsAllowInvalidHostnames
选项设置为 true
。
X.509 身份验证
如果您使用的是 X.509 身份验证,则应在连接字符串中设置用户名,**而不是** connect()
选项。
// Do this:
const username = 'myusername';
await mongoose.connect(`mongodb://${encodeURIComponent(username)}@127.0.0.1:27017/test`, {
tls: true,
tlsCAFile: `${__dirname}/rootCA.pem`,
authMechanism: 'MONGODB-X509',
});
// Not this:
await mongoose.connect('mongodb://127.0.0.1:27017/test', {
tls: true,
tlsCAFile: `${__dirname}/rootCA.pem`,
authMechanism: 'MONGODB-X509',
auth: { username },
});
使用 MongoDB Atlas 的 X.509 身份验证
对于 MongoDB Atlas,X.509 证书不是根 CA 证书,并且与自签名证书一样,不会与 tlsCAFile
参数一起使用。如果使用 tlsCAFile
参数,则会引发类似于以下内容的错误
要使用 X.509 身份验证连接到 MongoDB Atlas 集群,要设置的正确选项是 tlsCertificateKeyFile
。连接字符串已经指定了 authSource
和 authMechanism
,但是为了完整性,它们包含在下面的 connect()
选项中。
const url = 'mongodb+srv://xyz.mongodb.net/test?authSource=%24external&authMechanism=MONGODB-X509';
await mongoose.connect(url, {
tls: true,
// location of a local .pem file that contains both the client's certificate and key
tlsCertificateKeyFile: '/path/to/certificate.pem',
authMechanism: 'MONGODB-X509',
authSource: '$external',
});
注意 连接字符串选项必须正确 URL 编码。