MongoDB 中的安全性如何工作(使用 x.509 证书)

San*_*eep 5 security authentication ssl mongodb x509

我阅读了 mongoDB 文档中的许多文档,仍然不清楚身份验证如何为副本集成员的客户端(使用 x.509)工作。

找到了一个资源“ http://pe-kay.blogspot.in/2016/02/securing-mongodb-using-x509-certificate.html ”,该资源有详细记录,但仍不清楚身份验证是如何发生的。

考虑以下 mongoConfig 以及启动服务器和 mongo 客户端的命令:-

mongoConfig.cfg

storage:
    dbPath: "../DB"
  security:
    clusterAuthMode: x509
  net:
    port: 27001
  ssl:
    mode: "requireSSL"
    PEMKeyFile: "../server/security/one.pem"
    clusterFile: "../server/security/one.pem"
    CAFile: "../server/security/rootCA.crt"
Run Code Online (Sandbox Code Playgroud)

提示中的命令:-

cPrompt> mongod -v --config "../custom/mongoConf.cfg" --replSet "one"

cPrompt> mongo -ssl --sslPEMKeyFile "../client/security/oneHost.pem" --sslCAFile "../client/security/rootCA.crt" --host mylocalhost --port 27001
Run Code Online (Sandbox Code Playgroud)

1) 是单向还是双向 SSL/TLS ?

2)replicaSet成员之间(mongod - 进行复制时的mongod)以及服务器-客户端(mongod-mongo说mongoShell或应用程序)之间如何进行身份验证?

3) 使用哪个版本的 TLS?

有人可以详细解释一下吗?

Wer*_*eit 4

这是一个老问题,但是我面临着同样的问题,并且花了我很多时间才让它发挥作用。有些项目相当重要,但却隐藏在文档中。

我尝试给出一个概述,而不是从 MongoDB 文档进行简单的复制/粘贴。

一般来说,MongoDB 中的 x.509 证书提供以下功能:

  • 生成密钥以加密连接
  • 确保从正确的主机建立连接(即声明的主机名与实际主机名匹配)
  • 验证客户端(而不是使用用户名+密码或密钥文件)

作为起点,人们应该看看这些教程:

TLS/SSL 设置在此配置文件部分中定义:

net:
   tls:
      certificateKeyFile: server.pem
      CAFile: server-ca.crt
      clusterFile: member.pem
      clusterCAFile: cluster-ca.crt
Run Code Online (Sandbox Code Playgroud)

它们对应于命令行选项

  • --tlsCertificateKeyFile server.pem
  • --tlsCAFile server-ca.crt
  • --tlsClusterFile member.pem
  • --tlsClusterCAFile cluster-ca.crt

所有其他 TLS/SSL 相关参数都有详细记录,通常它们不应引起任何混淆或误解。

步骤1

当客户端尝试建立启用 TLS/SSL 的连接时,mongod/mongos服务器会提供服务器证书。客户端向 CA 验证此证书。

  • 客户可以是普通客户端(例如 Mongo shell mongosh)或内部副本集/分片集群成员

  • 服务器证书始终相同,mongod/mongos不区分客户端类型

  • 服务器证书由参数定义

    net.tls.certificateKeyFile或者--tlsCertificateKeyFile

  • 普通客户端可以通过以下方式验证服务器证书:

    • 选项--tls --tlsCAFile server-ca.cer

    • 选项--tls --tlsUseSystemCA

    • 连接字符串参数tls=true&tlsCAFile=server-ca.cer

    • --tlsUseSystemCA仅作为选项存在,不能在连接字符串中定义它。会是这样的:

      mongosh --tlsUseSystemCA "mongodb://localhost/?tls=true"

  • 内部副本集/分片集群成员通过参数验证服务器证书

    net.tls.CAFile或者--tlsCAFile

  • 如果未指定net.tls.CAFile--tlsCAFile且您未使用 x.509 身份验证,则将使用系统范围的 CA 证书存储。如果您使用 x.509 身份验证,则需要net.tls.CAFile或。--tlsCAFile

第2步

客户端向服务器提供客户端证书mongod/mongos。客户端证书可用于对用户进行身份验证。在这种情况下,您不必提供密码/密钥文件。

  • 对于普通客户端,x.509 身份验证是通过用户创建启用的,例如 db.getSiblingDB("$external").runCommand({createUser: "CN=myName,OU=myOrgUnit,O=myOrg,..."})
  • 对于副本集/分片集群成员,通过参数启用x.509身份验证 security.clusterAuthMode: x509

普通客户端(例如)通过以下参数mongosh提供客户端证书:

  • mongosh --tls --tlsCertificateKeyFile client.pem(无 x.509 身份验证)
  • mongosh --tls --authenticationDatabase $external --authenticationMechanism MONGODB-X509 --tlsCertificateKeyFile client.pem(使用 x.509 身份验证)
  • mongosh "mongodb://username:secret@localhost/?tls=true&authSource=admin&tlsCertificateKeyFile=client.pem"(无 x.509 身份验证)
  • mongosh "mongodb://localhost/?tls=true&authSource=$exernal&tlsCertificateKeyFile=client.pem&authMechanism=MONGODB-X509"(使用 x.509 身份验证)

内部副本集/分片集群成员通过参数或方式提供成员证书net.tls.clusterFile--tlsClusterFile

  • 服务器monogd/mongos使用参数net.tls.clusterCAFile或定义的Root-CA验证客户端/成员证书--tlsClusterCAFile
  • 客户可以是普通客户端(例如 Mongo shell mongosh)或内部副本集/分片集群成员
  • 根CA始终相同,mongos/mongod客户端证书和成员证书之间没有区别
  • 如果net.tls.clusterCAFileor--tlsClusterCAFile未定义,则net.tls.CAFile/--tlsCAFile用于验证。

陷阱:

  • 一些 MongoDB 文档仅使用术语“证书”,而没有明确说明它是否适用于客户端证书服务器证书或两者。通常,MongoDB 文档仅使用术语“客户端证书”,而没有明确说明它是否适用于副本集/分片集群部署中的普通用户客户端证书或内部成员身份客户端证书。

    在这个答案中,我使用术语“服务器证书”、“客户端证书”和“成员证书”以便更好地理解。

  • 服务器证书和成员证书的使用者名称中必须具有相同的 OOU、 和。DC

    从 MongoDB 7.0 版本开始,您可以通过设置来更改此行为net.tls.clusterAuthX509.attributes,但到目前为止我还没有测试它。

  • 客户端证书和成员证书的主题名称中必须有不同的 O, OU, 和DC

  • 参数对certificateKeyFile/CAFileclusterFile/clusterCAFile用于分隔来自普通客户端的连接和来自副本集/分片集群成员的连接。它们用于分隔客户端和服务器证书,即传入传出连接。在我看来,这些名字完全是误导。

  • 您可以使用通用的根 CA,其定义为net.tls.CAFile

  • 您还可以对客户端、成员和服务器使用相同的证书。该通用证书甚至可以用于副本集/分片集群成员的 x.509 身份验证。该证书仅提供加密连接和x.509成员身份验证。当然,您不能将其用于普通客户端的 x.509 身份验证。

  • 选项tlsAllowInvalidCertificates对 x509 身份验证没有影响。对于 x509 身份验证,证书必须有效。无效证书仅用于加密连接。

测试用例:

openssl verify -CAfile server-ca.crt server.pem
openssl verify -CAfile cluster-ca.crt member.pem
openssl verify -CAfile cluster-ca.crt client.pem

# Verify server certificate:
openssl s_server -cert server.pem
# open another terminal
openssl s_client -CAfile server-ca.crt -quiet -no_ign_eof -status <<< Q

# Verify server and client certificate:
openssl s_server -cert server.pem -CAfile cluster-ca.crt -Verify 0
# open another terminal
openssl s_client -cert member.pem -CAfile server-ca.crt -quiet -no_ign_eof -status <<< Q
openssl s_client -cert client.pem -CAfile server-ca.crt -quiet -no_ign_eof -status <<< Q
Run Code Online (Sandbox Code Playgroud)

可视化

在此输入图像描述

或者,如果您仅使用一个 CA 证书common-ca.crt

在此输入图像描述