Skip to content

MongoDB 认证配置

启用认证

1. 准备管理员用户

在启用认证之前,需要创建一个具有管理员权限的用户。

步骤1:启动MongoDB实例(无认证模式)

bash
# 启动MongoDB实例(无认证)
mongod --dbpath /data/db

步骤2:连接到MongoDB实例

bash
# 连接到MongoDB实例
mongo

步骤3:创建管理员用户

javascript
// 切换到admin数据库
use admin

// 创建root用户,具有最高权限
db.createUser({
  user: "root",
  pwd: "strongPassword123",
  roles: [ { role: "root", db: "admin" } ]
})

// 创建userAdminAnyDatabase用户,用于管理所有数据库的用户
db.createUser({
  user: "userAdmin",
  pwd: "userAdminPassword",
  roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
})

2. 启用认证重启MongoDB

步骤1:停止当前MongoDB实例

bash
# 连接到MongoDB实例
mongo

# 停止实例
use admin
db.shutdownServer()

步骤2:使用认证模式启动MongoDB

bash
# 使用--auth选项启用认证
mongod --dbpath /data/db --auth

# 或使用配置文件
mongod --config /etc/mongod.conf

步骤3:配置文件方式启用认证

编辑mongod.conf文件:

yaml
# mongod.conf
security:
  authorization: enabled

# 其他配置...

3. 验证认证是否生效

bash
# 连接到MongoDB实例
mongo

# 尝试访问数据库,应失败
show dbs
# 输出:uncaught exception: Error: listDatabases failed: {
#   "ok" : 0,
#   "errmsg" : "command listDatabases requires authentication",
#   "code" : 13,
#   "codeName" : "Unauthorized"
# }

# 使用认证连接
mongo -u "root" -p "strongPassword123" --authenticationDatabase "admin"

# 或在连接后认证
mongo
use admin
db.auth("root", "strongPassword123")

# 验证成功后可以访问数据库
show dbs

用户管理

创建用户

创建普通用户

javascript
// 切换到目标数据库
use myDatabase

// 创建用户,具有读写权限
db.createUser({
  user: "myUser",
  pwd: "myPassword",
  roles: [ { role: "readWrite", db: "myDatabase" } ]
})

创建具有多个角色的用户

javascript
// 创建具有多个角色的用户
db.createUser({
  user: "multiRoleUser",
  pwd: "multiRolePassword",
  roles: [
    { role: "readWrite", db: "myDatabase" },
    { role: "read", db: "otherDatabase" },
    { role: "dbAdmin", db: "myDatabase" }
  ]
})

创建只读用户

javascript
// 创建只读用户
db.createUser({
  user: "readOnlyUser",
  pwd: "readOnlyPassword",
  roles: [ { role: "read", db: "myDatabase" } ]
})

查看用户

javascript
// 查看当前数据库的用户
show users

// 查看admin数据库的所有用户
use admin
db.getUsers()

// 查看特定用户的详细信息
db.getUser("myUser")

修改用户密码

javascript
// 修改当前数据库中用户的密码
db.changeUserPassword("myUser", "newPassword")

// 使用admin数据库修改任何用户的密码
use admin
db.changeUserPassword("myUser", "newPassword", { db: "myDatabase" })

修改用户角色

javascript
// 修改用户角色
db.updateUser("myUser", {
  roles: [
    { role: "readWrite", db: "myDatabase" },
    { role: "read", db: "otherDatabase" }
  ]
})

删除用户

javascript
// 删除当前数据库中的用户
db.dropUser("myUser")

// 使用admin数据库删除任何用户
use admin
db.dropUser("myUser", { db: "myDatabase" })

认证机制配置

SCRAM 认证机制

SCRAM(Salted Challenge Response Authentication Mechanism)是MongoDB 3.0+的默认认证机制,提供了更强的安全性。

SCRAM-SHA-256

MongoDB 4.0+默认使用SCRAM-SHA-256:

javascript
// 创建使用SCRAM-SHA-256的用户
db.createUser({
  user: "scramUser",
  pwd: "scramPassword",
  roles: [ { role: "readWrite", db: "myDatabase" } ],
  mechanisms: [ "SCRAM-SHA-256" ]
})

配置默认认证机制

mongod.conf中配置:

yaml
security:
  authorization: enabled
  sasl:
    authenticationMechanisms: SCRAM-SHA-256

X.509 证书认证

X.509证书认证允许使用SSL/TLS证书进行用户认证,适用于企业级安全需求。

1. 生成X.509证书

bash
# 生成CA证书
openssl req -newkey rsa:2048 -new -x509 -days 365 -nodes -out mongodb-ca.pem -keyout mongodb-ca.key

# 生成服务器证书
openssl req -newkey rsa:2048 -new -nodes -out mongodb-server.csr -keyout mongodb-server.key
openssl x509 -req -in mongodb-server.csr -CA mongodb-ca.pem -CAkey mongodb-ca.key -CAcreateserial -out mongodb-server.pem -days 365

# 生成客户端证书
openssl req -newkey rsa:2048 -new -nodes -out mongodb-client.csr -keyout mongodb-client.key
openssl x509 -req -in mongodb-client.csr -CA mongodb-ca.pem -CAkey mongodb-ca.key -CAcreateserial -out mongodb-client.pem -days 365

2. 配置MongoDB使用SSL/TLS

编辑mongod.conf文件:

yaml
net:
  port: 27017
bindIp: 0.0.0.0
ssl:
  mode: requireSSL
  PEMKeyFile: /etc/ssl/mongodb-server.pem
  CAFile: /etc/ssl/mongodb-ca.pem
  allowInvalidHostnames: false

security:
  authorization: enabled

3. 创建X.509用户

javascript
// 使用X.509证书DN作为用户名
use $external
db.createUser({
  user: "CN=client,OU=MyOrg,O=MyCompany,L=MyCity,ST=MyState,C=MyCountry",
  roles: [ { role: "readWrite", db: "myDatabase" } ],
  mechanisms: [ "MONGODB-X509" ]
})

4. 使用X.509证书连接

bash
# 使用X.509证书连接
mongo --ssl --sslPEMKeyFile /etc/ssl/mongodb-client.pem --sslCAFile /etc/ssl/mongodb-ca.pem --authenticationMechanism MONGODB-X509 --authenticationDatabase \$external

LDAP 认证(Enterprise)

MongoDB Enterprise版本支持LDAP认证,可以集成现有的LDAP目录服务。

配置LDAP认证

编辑mongod.conf文件:

yaml
security:
  authorization: enabled
auth:
  ldap:
    servers: "ldap.example.com"
    bind:
      queryUser: "cn=binduser,dc=example,dc=com"
      queryPassword: "bindPassword"
    userToDNMapping:
      "[<username>]" : "uid=<username>,ou=users,dc=example,dc=com"
    authz:
      queryTemplate: "dc=example,dc=com??sub?(&(objectClass=group)(memberUid={USER}))"

创建LDAP用户

javascript
use $external
db.createUser({
  user: "ldapuser",
  roles: [ { role: "readWrite", db: "myDatabase" } ],
  mechanisms: [ "PLAIN" ]
})

连接认证

命令行连接认证

bash
# 基本认证方式
mongo -u "username" -p "password" --authenticationDatabase "authDB"

# 连接到特定数据库
mongo -u "username" -p "password" --authenticationDatabase "authDB" myDatabase

# 使用URI连接字符串
mongo "mongodb://username:password@localhost:27017/myDatabase?authSource=authDB"

驱动程序连接认证

Node.js 驱动

javascript
const { MongoClient } = require('mongodb');

// URI连接字符串
const uri = "mongodb://username:password@localhost:27017/myDatabase?authSource=authDB";

// 连接选项方式
const uri = "mongodb://localhost:27017/myDatabase";
const options = {
  auth: {
    username: "username",
    password: "password"
  },
  authSource: "authDB"
};

const client = new MongoClient(uri, options);

Python 驱动(PyMongo)

python
from pymongo import MongoClient

# URI连接字符串
uri = "mongodb://username:password@localhost:27017/myDatabase?authSource=authDB"
client = MongoClient(uri)

# 连接选项方式
client = MongoClient(
    host="localhost",
    port=27017,
    username="username",
    password="password",
    authSource="authDB"
)

认证最佳实践

1. 使用强密码策略

  • 密码长度至少12个字符
  • 包含大小写字母、数字和特殊字符
  • 定期更换密码
  • 避免使用常见密码

2. 最小权限原则

  • 为用户分配最小必要权限
  • 避免使用root等超级用户进行日常操作
  • 为不同角色创建专用用户

3. 使用SCRAM-SHA-256认证机制

  • MongoDB 4.0+默认使用SCRAM-SHA-256
  • 提供更强的安全性
  • 支持盐值和迭代计数

4. 启用SSL/TLS加密

  • 加密客户端和服务器之间的通信
  • 防止中间人攻击
  • 保护敏感数据传输

5. 定期审计用户

  • 定期检查用户列表
  • 删除不再使用的用户
  • 审查用户权限

6. 使用角色分离

  • 管理员角色:管理用户和权限
  • 读写角色:日常业务操作
  • 只读角色:报表和查询

7. 备份认证数据

  • 定期备份admin.system.users集合
  • 确保备份数据安全存储
  • 测试恢复流程

常见问题与解决方案

问题1:忘记管理员密码

解决方案

  1. 停止MongoDB实例
  2. 以无认证模式启动
  3. 重置管理员密码
  4. 以认证模式重启
bash
# 停止实例
mongod --dbpath /data/db --shutdown

# 无认证模式启动
mongod --dbpath /data/db

# 连接并重置密码
mongo
use admin
db.changeUserPassword("root", "newStrongPassword")

# 停止并以认证模式重启
use admin
db.shutdownServer()
mongod --dbpath /data/db --auth

问题2:无法连接到启用认证的MongoDB

可能原因

  • 用户名或密码错误
  • 认证数据库错误
  • 认证机制不匹配
  • 网络连接问题

解决方案

bash
# 检查连接字符串
mongo "mongodb://username:password@localhost:27017/admin?authSource=admin&authMechanism=SCRAM-SHA-256"

# 检查MongoDB日志
tail -f /var/log/mongodb/mongod.log

# 验证用户存在
db.getUser("username")

问题3:用户没有预期的权限

解决方案

  • 检查用户角色
  • 确保角色分配正确
  • 检查认证数据库
javascript
# 查看用户角色
db.getUser("username")

# 更新用户角色
db.updateUser("username", {
  roles: [ { role: "readWrite", db: "myDatabase" } ]
})

认证相关命令参考

用户管理命令

javascript
// 创建用户
db.createUser(userDocument)

// 修改用户密码
db.changeUserPassword(username, newPassword)

// 更新用户信息
db.updateUser(username, updateDocument)

// 删除用户
db.dropUser(username)

// 查看用户
db.getUser(username)

// 查看所有用户
db.getUsers()

// 认证用户
db.auth(username, password)

角色管理命令

javascript
// 查看角色
db.getRole(roleName)

// 查看所有角色
db.getRoles()

// 创建自定义角色
db.createRole(roleDocument)

// 更新自定义角色
db.updateRole(roleName, updateDocument)

// 删除自定义角色
db.dropRole(roleName)

常见问题(FAQ)

Q1: 如何启用MongoDB的认证机制?

A1: 启用MongoDB认证机制的步骤:

  1. 创建管理员用户
  2. 停止MongoDB实例
  3. 使用--auth选项或配置文件启用认证
  4. 重启MongoDB实例

Q2: MongoDB默认的认证机制是什么?

A2: MongoDB 4.0+默认使用SCRAM-SHA-256认证机制,3.0-3.6版本默认使用SCRAM-SHA-1。

Q3: 如何创建具有管理员权限的用户?

A3: 创建管理员用户的命令:

javascript
use admin
db.createUser({
  user: "root",
  pwd: "strongPassword",
  roles: [ { role: "root", db: "admin" } ]
})

Q4: 如何使用认证连接MongoDB?

A4: 使用命令行连接:

bash
mongo -u "username" -p "password" --authenticationDatabase "admin"

或使用URI连接字符串:

bash
mongo "mongodb://username:password@localhost:27017/myDatabase?authSource=admin"

Q5: 如何重置忘记的管理员密码?

A5: 重置管理员密码的步骤:

  1. 以无认证模式启动MongoDB
  2. 连接到实例
  3. 重置密码
  4. 以认证模式重启

Q6: MongoDB支持哪些认证机制?

A6: MongoDB支持多种认证机制:

  • SCRAM-SHA-256
  • SCRAM-SHA-1
  • MONGODB-CR(已废弃)
  • MONGODB-X509
  • LDAP(Enterprise)
  • Kerberos(Enterprise)

Q7: 如何查看用户的权限?

A7: 查看用户权限的命令:

javascript
db.getUser("username")

Q8: 如何修改用户的角色?

A8: 修改用户角色的命令:

javascript
db.updateUser("username", {
  roles: [ { role: "readWrite", db: "myDatabase" } ]
})

Q9: 如何启用SSL/TLS加密?

A9: 在mongod.conf中配置:

yaml
net:
  ssl:
    mode: requireSSL
    PEMKeyFile: /path/to/server.pem
    CAFile: /path/to/ca.pem

Q10: 如何备份认证数据?

A10: 备份认证数据的命令:

bash
# 使用mongodump备份admin数据库
mongodump -u "root" -p "password" --authenticationDatabase "admin" --db "admin"