Mongo-Express 容器可以通过 TLS 连接到 MongoDB 吗?

问题描述 投票:0回答:2

我有一个 mongo 容器,从

requireTLS
TLS 模式开始,还有一个 mongo-express 容器。 Mongo-express 似乎无法使用 TLS 连接到 mongo。

我的

docker-compose.yml

version: '3.1'
services:
  mongodb1:
    image          : "mongo:4.2"
    container_name : "mongodb-001"
    ports:
      - '27017:27017'
    environment:
      MONGO_INITDB_ROOT_USERNAME : "admin"
      MONGO_INITDB_ROOT_PASSWORD : "adminpasswd"
    volumes:
      - "./mongo-data:/data/db"
      - "./etc_mongod.conf:/etc/mongod.conf"
      - "./certificates:/etc/certificates:ro"
    command:
      - "--tlsMode"
      - "preferTLS"
      - "--tlsDisabledProtocols"
      - "none"
      - "--tlsCertificateKeyFile"
      - "/etc/certificates/certificateKey.pem"
      - "--tlsCAFile"
      - "/etc/certificates/CA.crt"
      - "--tlsAllowConnectionsWithoutCertificates"

  mongo-express:
    image          : "mongo-express:latest"
    container_name : "mongo-express-001"
    ports:
      - '8081:8081'
    depends_on:
      - mongodb1
    volumes:
      - "./certificates/CA.crt:/etc/certificates/CA.crt:ro"
    environment:
      ME_CONFIG_MONGODB_SERVER: "mongodb-001"
      ME_CONFIG_MONGODB_PORT: "27017"
      ME_CONFIG_MONGODB_ENABLE_ADMIN: "false"
      ME_CONFIG_MONGODB_AUTH_DATABASE: "admin"
      ME_CONFIG_MONGODB_AUTH_USERNAME: "admin"
      ME_CONFIG_MONGODB_AUTH_PASSWORD: "adminpasswd"
      ME_CONFIG_MONGODB_ADMINUSERNAME: "admin"
      ME_CONFIG_MONGODB_ADMINPASSWORD: "adminpasswd"
      ME_CONFIG_SITE_SSL_ENABLED: "true"
      ME_CONFIG_MONGODB_CA_FILE: "/etc/certificates/CA.crt"

...以及我收到的错误消息:

mongodb-001      | 2020-10-09T14:16:13.299+0000 I  NETWORK  [listener] connection accepted from 172.31.0.3:44774 #2 (1 connection now open)
mongodb-001      | 2020-10-09T14:16:13.305+0000 I  NETWORK  [conn2] Error receiving request from client: SSLHandshakeFailed: The server is configured to only allow SSL connections. Ending connection from 172.31.0.3:44774 (connection id: 2)
mongodb-001      | 2020-10-09T14:16:13.305+0000 I  NETWORK  [conn2] end connection 172.31.0.3:44774 (0 connections now open)
mongo-express-001 | 
mongo-express-001 | /node_modules/mongodb/lib/server.js:265
mongo-express-001 |         process.nextTick(function() { throw err; })
mongo-express-001 |                                       ^
mongo-express-001 | Error [MongoError]: connection 0 to mongodb-001:27017 closed
mongo-express-001 |     at Function.MongoError.create (/node_modules/mongodb-core/lib/error.js:29:11)
mongo-express-001 |     at Socket.<anonymous> (/node_modules/mongodb-core/lib/connection/connection.js:200:22)
mongo-express-001 |     at Object.onceWrapper (events.js:422:26)
mongo-express-001 |     at Socket.emit (events.js:315:20)
mongo-express-001 |     at TCP.<anonymous> (net.js:674:12)
mongo-express-001 exited with code 1

请注意:

  • 我可以使用 mongo shell 连接到 MongoDB,其参数与传递给 mongo-express 的参数相同:
mongo "mongodb://admin:adminpasswd@mongodb-001:27017/admin?authSource=admin" --tls --tlsCAFile certificates/CA.crt
  • 如果我以
    preferTLS
    模式启动 MongoDB,mongo-express 连接可以工作
mongodb docker-compose tls1.2 mongo-express
2个回答
0
投票

tl;博士

使用以下代码创建一个新的

config.js
文件

module.exports = {
  mongodb: {
    connectionOptions: {
      ssl: true,
    }
  }
};

并将该文件挂载到您的 docker compose 文件中

/node_modules/mongo-express/config.js

说明

这似乎是他们的 config.default.js 文件的问题。里面有这个

module.exports = {                                                                                                     
  mongodb: {                                                                                                           
    // if a connection string options such as server/port/etc are ignored
    connectionString: mongo.connectionString || getConnectionStringFromEnvVariables(),
                                                                                                                   
    connectionOptions: {                              
    // ssl: connect to the server using secure SSL
    ssl: process.env.ME_CONFIG_MONGODB_SSL || mongo.ssl,
                                                                                                                   
    // sslValidate: validate mongod server certificate against CA
    sslValidate: process.env.ME_CONFIG_MONGODB_SSLVALIDATE || true,
                                                                                                                   
    // sslCA: array of valid CA certificates                                                                         
    sslCA: sslCAFromEnv ? [sslCAFromEnv] : [],

    // autoReconnect: automatically reconnect if connection is lost                                 
    autoReconnect: true,                                                                                             
                                                                                                                   
    // poolSize: size of connection pool (number of connections to use)
    poolSize: 4,                                   
  }
}

您会注意到存在一个环境变量,该环境变量未在其文档中列出(有原因)。

ME_CONFIG_MONGODB_SSL

这是启用 tls 支持所必需的。然而,您自己设置环境变量除了抛出错误并中断express之外什么也不做,因为它没有被转换为布尔值。所以它只是读取为字符串“true”或“false”。

此代码已在其 npm 包代码中修复,但自 2021 年底以来,他们尚未更新其 docker 映像。因此,我找到的唯一“修复”是使用以下代码创建一个新的

config.js
文件

module.exports = {
  mongodb: {
    connectionOptions: {
      ssl: true,
      sslValidate: true,
    }
  }
};

然后将此文件挂载到 docker-compose 文件中的

/node_modules/mongo-express/config.js
处。它会读取这些并覆盖默认值。

注意:我还添加了

sslValidate
键:值对,因为它同样缺乏类型转换。因此,如果您完全省略
ME_CONFIG_MONGODB_SSLVALIDATE
环境变量,它将被设置为 true,但如果您将环境变量包含为 true 或 false,它只会中断(未定义的行为)。


0
投票

当 mongo-express 位于同一个 docker 网络中时,来自 mongo-express 的连接开始工作得更好,例如

docker network create netw1
docker network connect netw1 mongo
docker network connect netw1 mongo-exprs

网络可以用合适的参数定义

docker network create --attachable --internal netw1
© www.soinside.com 2019 - 2024. All rights reserved.