如何通过Docker在MongoDB上启用身份验证?


73

我想启动一个docker,mongodb:latest但只允许某些用户访问某些db(即enable --auth)。任何人都不能访问mongodb!作为docker启动的一部分,我应该如何做?

BTWdata directory在启动过程中通过使用以下命令位于主机上:-v /my/own/datadir:/data/db

Answers:


98

如果您看一下:

您会注意到:中使用了两个变量docker-entrypoint.sh

  • MONGO_INITDB_ROOT_USERNAME
  • MONGO_INITDB_ROOT_PASSWORD

您可以使用它们来设置root用户。例如,您可以使用以下docker-compose.yml文件:

mongo-container:
  image: mongo:3.4.2
  environment:
      # provide your credentials here
      - MONGO_INITDB_ROOT_USERNAME=root
      - MONGO_INITDB_ROOT_PASSWORD=rootPassXXX
  ports:
    - "27017:27017"
  volumes:
      # if you wish to setup additional user accounts specific per DB or with different roles you can use following entry point
    - "$PWD/mongo-entrypoint/:/docker-entrypoint-initdb.d/"
  # no --auth is needed here as presence of username and password add this option automatically
  command: mongod

现在,在启动容器时,docker-compose up您应该注意以下条目:

...
I CONTROL  [initandlisten] options: { net: { bindIp: "127.0.0.1" }, processManagement: { fork: true }, security: { authorization: "enabled" }, systemLog: { destination: "file", path: "/proc/1/fd/1" } }
...
I ACCESS   [conn1] note: no users configured in admin.system.users, allowing localhost access
...
Successfully added user: {
    "user" : "root",
    "roles" : [
        {
            "role" : "root",
            "db" : "admin"
        }
    ]
}

要添加除root用户之外的自定义用户,请使用入口点可执行脚本(在装入入口点时放置在$ PWD / mongo-entrypoint目录下docker-compose):

#!/usr/bin/env bash
echo "Creating mongo users..."
mongo admin --host localhost -u USER_PREVIOUSLY_DEFINED -p PASS_YOU_PREVIOUSLY_DEFINED --eval "db.createUser({user: 'ANOTHER_USER', pwd: 'PASS', roles: [{role: 'readWrite', db: 'xxx'}]}); db.createUser({user: 'admin', pwd: 'PASS', roles: [{role: 'userAdminAnyDatabase', db: 'admin'}]});"
echo "Mongo users created."

将执行Entrypoint脚本并创建其他用户。


4
我改用了用户名和密码环境变量(如您在回答中所展示的那样),以便我的mongo实例可以自动以身份验证模式启动。之前,我必须以不安全的方式启动它,使用docker-entrypoint .js脚本创建我的用户,然后以身份验证模式重启实例。当我尝试使用bash脚本创建新用户时(在新数据库中-不是admin),出现“身份验证失败”错误。我尝试直接在运行中的mongo容器中运行,但仍然出现相同的错误。您能为此想到什么原因?
littleK

2
如果您在数据库(而非管理员)中创建了其他用户,则可能需要提供其他选项--authenticationDatabase来告诉服务器在哪里寻找要与之进行身份验证的用户。您可以验证,如果验证通过两种方式运作: -连接从外壳,mongo DB --host -u USER -p PASS --authenticationDatabase DB-或者通过连接本地主机模式:mongo --host localhostuse YOUR_DB其次db.auth("USER","PASS")
jbochniak

谢谢,我以前不知道--authenticationDatabase指令。做到了。
littleK

env vars不会在已经创建的数据库上创建用户,但是它们确实确保mongod是使用--auth启动的,因为即使在第一次启动后,您仍然需要mongod docker-compose。如果那里没有什么重要的东西,您可以随时重docker-compose rm -fv <servicename>试...还是没有运气吗?如果安装了共享卷以保留数据,则必须将其清空。github.com/docker-library/mongo/issues/…–
pulkitsinghal


32

一种。您可以通过终端使用环境变量:

$ docker run -d --name container_name \
      -e MONGO_INITDB_ROOT_USERNAME=admin \
      -e MONGO_INITDB_ROOT_PASSWORD=password \
      mongo

如果您想测试一切是否正常:

// ssh into the running container
// Change container name if necessary
$ docker exec -it mongo /bin/bash

// Enter into mongo shell
$ mongo

// Caret will change when you enter successfully
// Switch to admin database
$> use admin
$> db.auth("admin", passwordPrompt())

// Show available databases
$> show dbs

如果要在首次运行时实例化数据库,请选中选项b。

b。您可以在Docker堆栈部署文件中使用环境变量,也可以在3.4至4.1版本的组合文件中使用环境变量。

正如官方mongo映像集的快速参考部分MONGO_INITDB_ROOT_USERNAME以及MONGO_INITDB_ROOT_PASSWORD您的yaml文件中所述:

mongo:
    image: mongo
    environment:
      MONGO_INITDB_ROOT_USERNAME: admin
      MONGO_INITDB_ROOT_PASSWORD: password

mongo映像中的docker-entrypoint.sh文件检查这两个变量是否存在,并相应地设置--auth标志。

C。您还可以使用Docker机密。

MONGO_INITDB_ROOT_USERNAMEMONGO_INITDB_ROOT_PASSWORD通过从docker-entrypoint.sh间接设置MONGO_INITDB_ROOT_USERNAME_FILEMONGO_INITDB_ROOT_PASSWORD_FILE变量:

mongo:
    image: mongo
    environment:
        - MONGO_INITDB_ROOT_USERNAME_FILE=/run/secrets/db_root_username
        - MONGO_INITDB_ROOT_PASSWORD_FILE=/run/secrets/db_root_password
    secrets:
      - db_root_username
      - db_root_password

docker-entrypoint.sh将MONGO_INITDB_ROOT_USERNAME_FILE和转换MONGO_INITDB_ROOT_PASSWORD_FILEMONGO_INITDB_ROOT_USERNAMEMONGO_INITDB_ROOT_PASSWORD

您可以使用MONGO_INITDB_ROOT_USERNAME,并MONGO_INITDB_ROOT_PASSWORD在你.sh.js脚本docker-entrypoint-initdb.d初始化数据库实例时,文件夹。

当容器启动首次它将与扩展执行文件.sh.js那个被发现在/docker-entrypoint-initdb.d。文件将按字母顺序执行。.jsmongo将使用MONGO_INITDB_DATABASE变量指定的数据库(如果存在)执行文件,否则进行测试。您也可以在.js脚本。

最后一种方法不在参考文档中,因此它可能无法在更新后保存下来。


1
我尝试了选项b,并且我仍然能够无需任何身份验证即可远程连接到mongo-我的意思是仅需键入即可mongo ip:port
sbk

@sbk曾经在mongodb中存在这种性质的错误,但据我所知已修复。这一定与您的设置有关。确保设置正确,然后尝试重新启动。
snnsnn

26

更好的进一步解决方案:
https : //blog.madisonhub.org/setting-up-a-mongodb-server-with-auth-on-docker/ https://docs.mongodb.com/v2.6/tutorial/add -用户管理员/

这是我针对相同问题所做的工作,并且确实有效。

  1. 在服务器上运行mongo docker实例

    docker run -d -p 27017:27017 -v ~/dataMongo:/data/db mongo
    
  2. 在正在运行的docker实例上打开bash。

    docker ps
    

    集装箱标识命令创建的状态端口名称

    b07599e429fb mongo“ docker-entrypoint ...” 35分钟前向上35分钟0.0.0.0:27017->27017/tcp musing_stallman

    docker exec -it b07599e429fb bash
    root@b07599e429fb:/#
    

    参考-https://github.com/arunoda/meteor-up-legacy/wiki/Accessing-the-running-Mongodb-docker-container-from-command-line-on-EC2

  3. 通过键入mongo输入mongo shell。

    root@b07599e429fb:/# mongo
    
  4. 在此示例中,我将设置一个名为ian的用户,并授予该用户对cool_db数据库的读写权限。

    > use cool_db
    
    > db.createUser({
        user: 'ian',
        pwd: 'secretPassword',
        roles: [{ role: 'readWrite', db:'cool_db'}]
    })
    

    参考:https : //ianlondon.github.io/blog/mongodb-auth/(仅第一点)

  5. 从mongod shell和bash退出。

  6. 使用以下命令停止docker实例。

    docker stop mongo
    
  7. 现在运行启用了auth的mongo docker。

    docker run -d -p 27017:27017 -v ~/dataMongo:/data/db mongo mongod --auth
    

    参考:如何通过Docker在MongoDB上启用身份验证?(乌斯曼·伊斯梅尔对此问题的回答)

  8. 我可以使用以下命令从本地Windows笔记本电脑连接到在Google Cloud服务器上运行的实例。

    mongo <ip>:27017/cool_db -u ian -p secretPassword
    

    参考:如何从Mac OS终端连接到远程mongo服务器


docker run -d -p 27017:27017 -v ~/dataMongo:/data/db mongo此命令如何启动不安全的mongo db?这有助于我们添加初始命令。
安库洛里亚

1
您好,谢谢您提供此答案,但我坚持执行第6步。您如何才能run知道已经有一个MongoDB容器?您必须杀死允许您设置auth的容器,然后使用auth重新运行它?我不明白
Eric Burel

2
@Eric是的,您必须先停止正在运行的docker实例,然后再次运行“ run”命令。我已经用此信息更新了答案。感谢您指出。
Sankaran Srinivasan

1
@Ankur,是的,该命令启动不安全的mongo,通过它可以添加安全性。
Sankaran Srinivasan

1
谢谢,但是这使我登录失败,因为现在我有2个不同的容器:一个带有用户但未设置auth的容器,一个带有auth但没有用户设置的容器,所以我无法连接。我想那-v ~/dataMonogo/data/db是我所不知道的,我对开发人员/托管人员不熟悉
Eric Burel

15

我尝试时很难

  • 创建除管理员以外的其他数据库
  • 添加新用户并启用对上述数据库的身份验证

所以我做了2020这里答案

我的目录看起来像这样

├── docker-compose.yml
└── mongo-entrypoint
    └── entrypoint.js

docker-compose.yml看起来像这样

version: '3.4'
services:
  mongo-container:
    # If you need to connect to your db from outside this container 
    network_mode: host
    image: mongo:4.2
    environment:
        - MONGO_INITDB_ROOT_USERNAME=admin
        - MONGO_INITDB_ROOT_PASSWORD=pass
    ports:
      - "27017:27017"
    volumes:
      - "$PWD/mongo-entrypoint/:/docker-entrypoint-initdb.d/"
    command: mongod

请更改adminpass与您的需要。

在内部mongo-entrypoint,我有entrypoint.js与此内容相关的文件:

var db = connect("mongodb://admin:pass@localhost:27017/admin");

db = db.getSiblingDB('new_db'); // we can not use "use" statement here to switch db

db.createUser(
    {
        user: "user",
        pwd: "pass",
        roles: [ { role: "readWrite", db: "new_db"} ],
        passwordDigestor: "server",
    }
)

再次在这里,您需要更改admin:passdocker-compose.yml之前声明的root mongo凭据。在另外你需要改变new_dbuserpass到新的数据库名称和凭据,你所需要的。

现在你可以:

docker-compose up -d

并从本地主机连接到该数据库,请注意,我已经有了mongo cli,您可以安装它,也可以执行上述容器以使用mongo命令:

mongo new_db -u user -p pass

或者您可以从其他计算机连接

mongo host:27017/new_db -u user -p pass

我的git存储库:https : //github.com/sexydevops/docker-compose-mongo

希望它可以帮助某人,我为此而失去了下午;)


非常感谢您将此内容写出来。这正是我所需要的。我需要做的一项更改是$PWD必须替换为.Note,管理员用户名必须不同于您要为新数据库创建的用户名
Joe Caruso

1
顺便说一句,有db = new Mongo().getDB("myDatabase"); docs.mongodb.com/manual/reference/method/Mongo.getDB

感谢一百万人救了我的命。我已经疯了将近一个星期。
cdaiga

8

官方mongo映像的Dockerfile在这里。默认命令是mongod,但是您可以重写以添加--auth开关,前提是已经配置了用户。

docker run -d .... mongodb:latest mongod --auth

如果必须创建用户,则需要批量装入启动脚本/entrypoint.sh以替换默认启动脚本,然后让该脚本创建用户并使用auth开关启动mongo。

docker run -d .... -v $PWD/my_custom_script.sh:/entrypoint.sh mongodb:latest

当我尝试将脚本作为卷安装时,出现错误“不是目录”
Janus Troelsen

1
我认为docker仅支持mount目录而不是文件。
Joey Yi Zhao

8

只需将.js文件拖放到入口点init文件夹中即可

例如entrypoint.js

var db = connect("mongodb://localhost/admin");

db.createUser(
    {
        user: "yourAdminUserName",
        pwd: "yourAdminPassword",
        roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
    }
)

docker-compose.yml:

db:
  image: mongo:3.2
  volumes:
   - /my/own/datadir:/data/db
   - ../mongo-entrypoint:/docker-entrypoint-initdb.d

手工完成其余部分或更多相同的工作。

如果您愿意,还可以将.sh文件放入init文件夹中以清理文件,以使它们不存在:zz-cleanup.sh。


6

我想发表评论,但信誉不够。

上面显示的添加用户的可执行脚本必须使用--authenticationDatabase adminNEWDATABASENAME进行修改 。

mongo --authenticationDatabase admin --host localhost -u USER_PREVIOUSLY_DEFINED -p PASS_YOU_PREVIOUSLY_DEFINED NEWDATABASENAME --eval "db.createUser({user: 'NEWUSERNAME', pwd: 'PASSWORD', roles: [{role: 'readWrite', db: 'NEWDATABASENAME'}]});"

https://i.stack.imgur.com/MdyXo.png


MONGO_INITDB_DATABASE变量可用于为下的脚本设置数据库名称(例如NEWDATABASENAME)/docker-entrypoint-initdb.d。默认值为test
Mohnish

4

@jbochniak:谢谢,尽管初读时我以为我已经发现了所有这些内容,但事实证明,您的示例(尤其是Mongo Docker映像的版本)帮助了我!

从v3.5开始,该版本(v3.4.2)和v3.4(当前对应于v3.4.3)仍支持通过这些变量指定的“ MONGO_INITDB_ROOT” (至少标记为“ 3”和“最新”)。如描述的那样工作您的答案和文档中所述进行工作。

我很快看了一下GitHub上的代码,但是看到了这些变量的类似用法,并且无法立即发现bug,应该在将其提交为bug之前这样做。


感谢您的警告,3.5再次检查了源,现在它也有它们:github.com/docker-library/mongo/blob/master/3.5/…–
pulkitsinghal

4

使用此图像修复:

使用docker-compose.yml

services:
  db:
    image: aashreys/mongo-auth:latest
    environment:
      - AUTH=yes
      - MONGODB_ADMIN_USER=admin
      - MONGODB_ADMIN_PASS=admin123
      - MONGODB_APPLICATION_DATABASE=sample
      - MONGODB_APPLICATION_USER=aashrey
      - MONGODB_APPLICATION_PASS=admin123
    ports:
      - "27017:27017"
     // more configuration

这也会创建一个“测试”数据库。我们如何预防呢?
WarrenV '17年

测试也许是默认数据库,则可以删除它。- MongoDB删除数据库
Mark Simon,

根据docker mongo docs的说法,它说:“当容器第一次启动时,它将执行在/docker-entrypoint-initdb.d中找到的扩展名为.sh和.js的文件。字母顺序的.js文件将由mongo使用MONGO_INITDB_DATABASE变量指定的数据库执行(如果存在),否则进行测试。” 因此,一旦进入数据库,就应该能够删除数据库。
卡尔saptarshi

1

您可以使用env变量设置mongo的用户名和密码

MONGO_INITDB_ROOT_USERNAME
MONGO_INITDB_ROOT_PASSWORD

使用简单的docker命令

docker run -e MONGO_INITDB_ROOT_USERNAME=my-user MONGO_INITDB_ROOT_PASSWORD=my-password mongo

使用docker-compose

version: '3.1'

services:

  mongo:
    image: mongo
    restart: always
    environment:
      MONGO_INITDB_ROOT_USERNAME: my-user
      MONGO_INITDB_ROOT_PASSWORD: my-password

最后一个选项是手动访问容器,并在mongo docker容器内设置用户和密码

docker exec -it mongo-container bash

现在您可以使用mongo shell命令配置所需的所有内容

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.