Can a Mongo-Express container connect to MongoDB with TLS?

I have a mongo container, started with the requireTLS TLS mode, and a mongo-express container. Mongo-express does not seem to manage to connect to mongo using TLS.

My 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"

...and the error message I get:

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

Note that:

  • I can connect to MongoDB using a mongo shell with the same parameters I pass to mongo-express:
mongo "mongodb://admin:adminpasswd@mongodb-001:27017/admin?authSource=admin" --tls --tlsCAFile certificates/CA.crt
  • Если я запустил MongoDB в preferTLS режим, соединение монго-экспресс работает

1 ответ

тл;др

Создайте новый файл со следующим кодом

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

и смонтируйте этот файл в файле компоновки докеров по адресу

Объяснение

Похоже, это проблема с их файлом 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,                                   
  }
}

Вы заметите существование переменной env, которая не указана (небезосновательно) в их документации.ME_CONFIG_MONGODB_SSL

Это необходимо для включения поддержки tls. Однако установка env var самостоятельно ничего не дает, кроме как выдает ошибку и прерывает экспресс из-за того, что она не приводится к логическому значению. Так что это просто читается как строка «истина» или «ложь».

Этот код исправлен в их коде пакета npm, но они не обновляли свой образ докера с конца 2021 года. Таким образом, единственное «исправление», которое я нашел для этого, — создать новыйconfig.jsфайл со следующим кодом

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

Затем смонтируйте этот файл в/node_modules/mongo-express/config.jsв вашем файле docker-compose. Он прочитает их и перезапишет значения по умолчанию.

Примечание: я добавилsslValidateпара ключ: значение также из-за того, что она страдает от того же недостатка приведения типов. Итак, если вы опуститеME_CONFIG_MONGODB_SSLVALIDATEenv var полностью, он будет установлен как true, но если вы включите env var как true или false, он просто сломается (неопределенное поведение).

Другие вопросы по тегам