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

5

我阅读了许多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"

提示符中的命令:

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

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

2)副本集成员之间(mongod-mongod)和服务器-客户端(mongod-mongo,如mongoShell或应用程序)之间的认证是如何进行的?

3)使用哪个版本的TLS?

有人能详细解释一下吗?

1个回答

4
这是一个老问题,然而我也遇到了同样的问题,花了很多时间才解决。有些要点在文档中相当重要,但却隐藏得很深。
我试着概述一下,而不是简单地从MongoDB文档中复制粘贴。
通常情况下,MongoDB中的x.509证书提供以下功能:
- 生成用于加密连接的密钥 - 确保连接建立在正确的主机上(即声明的主机名与实际主机名匹配) - 对客户端进行身份验证(而不是使用用户名+密码或密钥文件)
作为起点,应该参考这些教程。

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

net:
   tls:
      certificateKeyFile: server.pem
      CAFile: server-ca.crt
      clusterFile: member.pem
      clusterCAFile: cluster-ca.crt

它们对应于命令行选项

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

所有其他与TLS/SSL相关的参数都有很好的文档记录,通常不会引起任何混淆或误解。

第一步

当客户端尝试建立一个启用了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

第二步

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

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

普通客户端(例如 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--tlsClusterCAFile定义的Root-CA来验证客户端/成员证书。
  • 客户端可以是普通客户端(例如Mongo shell mongosh)或内部副本集/分片集群成员。
  • Root-CA始终相同,mongos/mongod不区分客户端证书和成员证书。
  • 如果未定义net.tls.clusterCAFile--tlsClusterCAFile,则使用net.tls.CAFile/--tlsCAFile进行验证。

注意事项:

一些Mongo文档只是提到“客户端”证书/连接。请注意,这意味着普通客户端(例如`mongosh`)以及内部副本集/分片集群成员客户端。在本答案中,我使用术语“客户端证书”和“成员证书”以便更好地理解。
服务器证书和成员证书的主题名称中必须具有相同的`O`、`OU`和`DC`。
客户端证书和成员证书的主题名称中必须具有不同的`O`、`OU`和`DC`。
参数对`certificateKeyFile/CAFile`和`clusterFile/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

可视化

enter image description here

如果您只使用一个CA证书common-ca.crt

enter image description here


非常感谢您的帮助,真是帮了大忙。我一直在为分片集群和x509身份验证而苦恼,问题是我在外部数据库中使用客户端证书主题字符串创建了用户,但是我无法连接到mongos,它一直显示UserNotFound。 - Hirbod
@Hirbod 请为此开一个新问题。 - Wernfried Domscheit

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接