前言

MongoDB 默认情况下是没有启用身份认证和访问控制的,需要我们手动进行配置和启用,这里我们采用默认的 SCRAM 认证机制。

大致流程:

  • 创建用户
  • 生成节点间身份认证的 Key 文件
  • 停止集群节点
  • 删除原有节点容器
  • 重新启动新的容器

创建用户

mongosh "mongodb://<IP>:<PORT>,<IP>:<PORT>,<IP>:<PORT>/?replicaSet=betterde&readPreference=primaryPreferred"
admin = db.getSiblingDB("admin")
admin.createUser(
  {
    user: "root",
    pwd: passwordPrompt(),
    roles: [ { role: "root", db: "admin" } ]
  }
);
Enter password
*************
{
  ok: 1,
  '$clusterTime': {
    clusterTime: Timestamp({ t: 1677817269, i: 1 }),
    signature: {
      hash: Binary(Buffer.from("79633f9be574bdc6265a2762e9bcda55d7864ab2", "hex"), 0),
      keyId: Long("7205813851093204998")
    }
  },
  operationTime: Timestamp({ t: 1677817269, i: 1 })
}

db.getUsers();
{
  users: [
    {
      _id: 'admin.root',
      userId: new UUID("42eca873-b5fa-4623-bd89-02f00edce81f"),
      user: 'root',
      db: 'admin',
      roles: [ { role: 'root', db: 'admin' } ],
      mechanisms: [ 'SCRAM-SHA-1', 'SCRAM-SHA-256' ]
    }
  ],
  ok: 1,
  '$clusterTime': {
    clusterTime: Timestamp({ t: 1677816808, i: 1 }),
    signature: {
      hash: Binary(Buffer.from("092d36c40817c92cc135574924774d0d24e02538", "hex"), 0),
      keyId: Long("7205813851093204998")
    }
  },
  operationTime: Timestamp({ t: 1677816808, i: 1 })
}

用户创建完成后还需要为集群节点开启身份认证功能。

生成 Key 文件

MongoDB ReplicaSet Cluster 的认证方式配置与单节点不同,ReplicaSet Cluster 模式需要为节点之间的链接配置一个相同的 Key。

openssl rand -base64 756 > mongodb.key
chmod 400 mongodb.key

如果你的集群是运行在 Docker 容器中的,那么切记将这个 mongodb.key 的所有者修改为容器运行时的用户和组,否则会导致 MongoDB 服务因读取 Key 失败而无法启动!

如果不确定的话可以进入 MongoDB 中查看数据文件的所有者信息,例如:

ls -la /data
total 24
drwxr-xr-x 4 root    root     4096 Feb  2 23:28 .
drwxr-xr-x 1 root    root     4096 Mar  3 03:39 ..
drwxr-xr-x 2 mongodb mongodb  4096 Feb  2 23:28 configdb
drwxr-xr-x 5 mongodb root    12288 Mar  3 06:32 db

id mongodb
uid=999(mongodb) gid=999(mongodb) groups=999(mongodb)

获得容器内的 mongodb 用户对应的 ID 后,将前面生成的 mongodb.key 文件的所有者和组设置为这个 ID:

sudo chown 999:999 mongodb.key

这样就可以使用这个 Key 作为集群节点之间的认证凭证了。

重新启动 MongoDB 容器

sudo docker stop mongodb
sudo docker rm mongodb
sudo docker run -d \
    --name mongodb \
    -p 27017:27017 \
    -v /data/mongodb:/data/db \
    -v /data/mongodb.key:/srv/mongodb/mongodb.key \
    mongo:latest \
    mongod --auth --keyFile=/srv/mongodb/mongodb.key --replSet betterde --bind_ip 0.0.0.0

如果不出意外的话,MongoDB 服务就正常启动了,这里主要加入了两个参数:

  • –auth: 开启身份认证
  • –keyFile: 设置集群节点间认证的 Key 文件

上述步骤需要再集群的其他节点上都执行一遍!

I hope this is helpful, Happy hacking…