【问题标题】:MongoDB Server accepting server certificate as client certificateMongoDB 服务器接受服务器证书作为客户端证书
【发布时间】:2021-10-03 09:49:01
【问题描述】:

对于 MongoDB 中的 x509 证书身份验证,我似乎有点困惑。

TLDR: 我创建了服务器和客户端证书(由相同的 CA 签名,但 CN 和 OU 不同),在 MongoDB 中使用主题名称作为用户名创建了一个用户,并使用 c# 客户端 + 客户端证书成功连接。 使用 MongoDB Compass,我能够使用服务器证书作为客户端证书连接到服务器并从服务器读取数据。 为什么我能够使用错误的证书进行身份验证?是否无法根据每个证书控制权限?

扩展: 我使用 OpenSSL 创建了一个自签名根 CA,它签署了另一个证书,即我的 Signing-CA。 使用此签名 CA,我又创建了两个证书:

  • 服务器证书(CN=Server1,OU=Servers,O=project,ST=SH,C=DE)
  • 客户端证书(CN=Client1,OU=Clients,O=project,ST=SH,C=DE)

有了这些证书,我无需身份验证就启动了 MongoDB 实例,启动了副本集并使用以下命令为证书创建了一个用户:

db.getSiblingDB("$external").runCommand({createUser: "CN=Client1,OU=Clients,O=project,ST=SH,C=DE",roles: [{role: "readWrite", db: "admin"}, {role: "userAdminAnyDatabase", db: "admin"}, {role: "clusterAdmin", db: "admin"}, {role: "root", db: "admin"}]});。 我重新启动了服务器,这次使用更多参数来启动身份验证: --replSet *replicaSetName* --port *port* --dbpath *path* --logpath *path* --tlsMode requireTLS --clusterAuthMode x509 --tlsCAFile *path* --tlsCertificateKeyFile *path* --tlsClusterFile *path* --auth

我能够使用 C# 客户端毫无问题地进行连接,MongoDB Compass 也能正常工作。 但是当我测试其他证书来验证安全性时,我注意到完全可以使用服务器证书和密钥文件使用 MongoDB 指南针连接到服务器。 我不仅可以连接,还可以浏览和修改数据。

我的印象是,每个客户证书都必须在 $external 数据库中有一个关联帐户,因此只有我分配/授予此特定用户帐户的权限/角色。

这种行为应该发生吗? 是否可以为每个客户证书创建一个用户帐户并对不同的数据库授予不同的权限?

感谢您的关注和回答,祝您有美好的一天!

【问题讨论】:

    标签: mongodb security authentication ssl x509certificate


    【解决方案1】:

    Socket/TLS 连接和身份验证是高级连接建立过程中的独立步骤。

    人们使用“连接”一词来指代多个单独的操作和流程,在对其中任何一个进行故障排除时,您需要非常清楚您正在查看/询问的内容:

    1. 从驱动程序到服务器的套接字连接
    2. 由驱动程序进行的身份验证(不会发生在监视仍然通过套接字连接过程的连接时)
    3. 客户端对象创建(严格来说根本不是连接,尽管许多人草率地/错误地使用“连接”一词来指代创建客户端对象的操作 - 创建客户端对象本身不会将任何东西连接到任何地方)
    4. 执行操作(即使启用了身份验证的服务器也允许创建到它的套接字连接并执行诸如ismaster 命令之类的操作而无需身份验证)

    可能是想询问 #2,但您测试了 #3 或 #4,正如您现在应该看到的,这不一定会给您预期的结果。

    当启用 TLS 而“不安全的 TLS”未启用时,服务器将在套接字连接过程中验证客户端的 TLS 证书(客户端将验证服务器的)。正在验证的证书必须由配置验证器的 CA 签名。此时,如果您设法为客户端提供了与服务器证书一起使用的私钥(通常不应该发生),则没有任何东西阻止客户端向服务器提供服务器的证书。服务器在日志中警告这种情况。请注意,尚未进行任何身份验证。

    如果您使用 X.509 身份验证(必须在客户端配置,并且与提供用于套接字连接的证书分开,例如使用 authMechanism URI 选项),那么在成功的套接字连接和任何关联的证书验证,驱动程序将执行身份验证。此时您需要创建与证书上的可分辨名称匹配的服务器用户。

    MongoDB 具有设置 TLS 连接和 X.509 身份验证的指南,通读它们并完全按照书面说明进行操作,并验证每一步。

    【讨论】:

      【解决方案2】:

      这取决于您如何配置 mongod 进程。假设您有一个 mongod 的配置文件(默认路径是 /etc/mongod.conf),您将查看是否有 net.tlssecurity.clusterAuthMode 设置..

      具有这些设置的示例配置文件:

      storage:
        dbPath: /data/db
        journal:
          enabled: true
      systemLog:
        destination: file
        logAppend: true
        path: /var/log/mongodb/mongod.log
      net:
        port: 27017
        bindIp: 0.0.0.0
        tls:
          mode: requireTLS
          certificateKeyFile: /etc/ssl/node1.pem
          CAFile: /etc/ssl/ca.crt
          clusterFile: /etc/ssl/node1.pem
      processManagement:
        fork: true
        pidFilePath: /var/run/mongodb/mongod.pid
        timeZoneInfo: /usr/share/zoneinfo
      security:
        authorization: enabled
        clusterAuthMode: x509
      replication:
        replSetName: replset
      

      其他事情

      最近 MongoDB 从 SSL 切换到 TLS,因此根据您使用的版本,您可能会发现 SSL 而不是 TLS

      此外,您可能正在使用副本集,也可能没有。如果使用副本集,您需要决定副本集成员如何向其他成员进行身份验证。它应该使用密钥文件,还是应该使用 x509 以及普通数据库用户。

      此外,您还需要创建至少一个命名的数据库用户。如果连接的用户绑定到 localhost 并且不存在其他用户,系统将允许对连接的用户进行 root 访问。这称为localhost exception。缺少这些步骤是不完整且不安全的安装。

      【讨论】:

      • 我不使用配置文件,所有配置都是通过 powershell (windows 10) 中的命令行完成的,但我使用的参数与配置文件中的条目几乎一致。 My Server 是在复制模式下运行的 MongoDB Server 5.0 版。从我使用的参数“tlsClusterFile”和“tlsCertificateKeyFile”来看,复制成员的身份验证似乎也是证书身份验证。我添加了一个带密码的“管理员”用户,但我仍然可以使用服务器证书作为客户端证书。可以禁用此行为吗?
      • @HansWuast - 你的连接字符串是什么?具有密码的管理员用户将阻止 localhost 异常允许任何人以超级用户身份进入,因此现在归结为您的配置细节以及您的连接字符串。
      猜你喜欢
      • 1970-01-01
      • 2014-09-05
      • 1970-01-01
      • 2015-04-30
      • 2015-10-20
      • 1970-01-01
      • 2014-05-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多