Files
Cloud-book/数据库/MongoDB_2025/MongoDB安全管理.md
2025-08-27 17:10:05 +08:00

273 lines
8.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 安全管理
确保数据库的安全是任何应用都必须考虑的关键问题。MongoDB 提供了丰富的安全特性,包括认证、授权、加密等,以保护数据免受未经授权的访问。本章节将详细介绍如何配置和管理 MongoDB 的各项安全功能。
---
## 安全概述
MongoDB 的安全模型主要围绕以下几个核心概念构建:
- **认证 (Authentication)**: 验证用户身份,确认“你是谁”。
- **授权 (Authorization)**: 控制经过认证的用户可以执行哪些操作,确认“你能做什么”。
- **加密 (Encryption)**: 保护数据在传输过程TLS/SSL和静态存储时Encryption at Rest的安全。
- **审计 (Auditing)**: 记录数据库上发生的活动,以便进行安全分析和合规性检查。
默认情况下MongoDB 的安全特性是**未启用**的。必须显式地配置和启用它们。
---
## 认证机制 (Authentication)
启用认证是保护数据库的第一步。当认证启用后,所有客户端和数据库节点之间的连接都必须提供有效的凭据。
### 启用认证
`mongod.conf` 配置文件中或通过命令行参数启用认证:
```yaml
# mongod.conf
security:
authorization: enabled
```
或者
```bash
mongod --auth
```
### 认证方法
MongoDB 支持多种认证机制,最常用的是 **SCRAM (Salted Challenge Response Authentication Mechanism)**
- **SCRAM-SHA-1**: 默认机制。
- **SCRAM-SHA-256**: 更强的加密算法,建议在 MongoDB 4.0 及以上版本中使用。
### 创建管理员用户
在启用认证之前,必须先创建一个具有 `userAdminAnyDatabase` 角色的用户管理员。这个用户将用于创建和管理其他用户。
1. **以无认证模式启动 `mongod`**
2. **连接到 `admin` 数据库并创建用户**:
```javascript
use admin
db.createUser({
user: "myUserAdmin",
pwd: passwordPrompt(), // or a plain-text password
roles: [ { role: "userAdminAnyDatabase", db: "admin" } ]
})
```
3. **重启 `mongod` 并启用认证**。
---
## 授权与基于角色的访问控制 (RBAC)
MongoDB 使用基于角色的访问控制Role-Based Access Control, RBAC来管理用户权限。权限被定义为**角色 (Role)**,然后将角色分配给用户。
### 内置角色 (Built-In Roles)
MongoDB 提供了一系列预定义的角色,涵盖了常见的管理和操作需求。
- **数据库用户角色**: `read`, `readWrite`
- **数据库管理员角色**: `dbAdmin`, `dbOwner`, `userAdmin`
- **集群管理员角色**: `clusterAdmin`, `clusterManager`, `hostManager`
- **备份与恢复角色**: `backup`, `restore`
- **所有数据库角色**: `readAnyDatabase`, `readWriteAnyDatabase`, `userAdminAnyDatabase`, `dbAdminAnyDatabase`
- **超级用户角色**: `root` (拥有所有权限)
### 自定义角色 (Custom Roles)
如果内置角色无法满足精细化权限控制需求,可以创建自定义角色。
```javascript
use myAppDB
db.createRole({
role: "salesDataViewer",
privileges: [
{ resource: { db: "myAppDB", collection: "sales" }, actions: ["find"] }
],
roles: []
})
```
### 管理用户和角色
- `db.createUser()`: 创建用户。
- `db.updateUser()`: 更新用户信息(如密码、角色)。
- `db.dropUser()`: 删除用户。
- `db.createRole()`: 创建角色。
- `db.grantRolesToUser()`: 为用户授予角色。
- `db.revokeRolesFromUser()`: 撤销用户的角色。
---
## 网络加密 (TLS/SSL)
为了保护数据在网络传输过程中的安全,防止窃听和中间人攻击,应该为 MongoDB 部署启用 TLS/SSL 加密。
### 配置 TLS/SSL
1. **获取 TLS/SSL 证书**: 可以使用自签名证书(用于内部测试)或从证书颁发机构 (CA) 获取证书。
2. **配置 `mongod` 和 `mongos`**: 在配置文件中指定证书文件、私钥文件和 CA 文件。
```yaml
net:
tls:
mode: requireTLS
certificateKeyFile: /path/to/mongodb.pem
CAFile: /path/to/ca.pem
```
3. **客户端连接**: 客户端在连接时也需要指定 TLS/SSL 选项。
```shell
mongo --ssl --sslCAFile /path/to/ca.pem --sslPEMKeyFile /path/to/client.pem ...
```
---
## 静态数据加密 (Encryption at Rest)
对于高度敏感的数据,除了网络加密,还应该考虑对存储在磁盘上的数据文件进行加密。
- **WiredTiger 的原生加密**: MongoDB Enterprise 版本支持使用 WiredTiger 存储引擎的原生加密功能。它使用本地密钥管理器或第三方密钥管理服务(如 KMIP来管理加密密钥。
- **文件系统/磁盘加密**: 也可以在操作系统层面或通过云服务商提供的功能(如 AWS KMS, Azure Key Vault对存储设备进行加密。
---
## 实践操作
### 需求描述
构建一个完整的MongoDB安全管理环境模拟企业级应用的安全需求。该场景需要配置认证机制、创建不同权限的用户角色并验证安全策略的有效性。通过实际操作来理解MongoDB安全管理的核心概念和最佳实践。
### 实践细节和结果验证
```shell
# 1. 启用认证并创建管理员用户
# 首先以无认证模式启动MongoDB
mongod --dbpath /data/mongodb/ins11 --port 27117 --fork --logpath /data/mongodb/logs/ins11.log
# 连接到MongoDB并创建管理员用户
mongosh --port 27117
# 在mongosh中执行
use admin
db.createUser({
user: "admin",
pwd: "ealgeslab123",
roles: [{ role: "userAdminAnyDatabase", db: "admin" }]
})
# 验证管理员用户创建成功
db.getUsers()
# 预期结果显示创建的admin用户信息
# 2. 重启MongoDB并启用认证
# 停止MongoDB服务
db.adminCommand("shutdown")
# 以认证模式重新启动
mongod --auth --dbpath /data/mongodb/ins11 --port 27117 --fork --logpath /data/mongodb/logs/ins11.log
# 使用管理员账户登录
mongosh --port 27117 -u "admin" -p "ealgeslab123" --authenticationDatabase "admin"
# 3. 创建业务数据库和用户
# 创建应用数据库
use ecommerce
# 创建具有读写权限的业务用户
db.createUser({
user: "appUser",
pwd: "appPassword123",
roles: [{ role: "readWrite", db: "ecommerce" }]
})
# 验证业务用户创建成功
db.getUsers()
# 预期结果显示appUser用户信息
# 4. 创建自定义角色
# 创建只允许查询和更新特定集合的自定义角色
db.createRole({
role: "productManager",
privileges: [
{
resource: { db: "ecommerce", collection: "products" },
actions: ["find", "update"]
}
],
roles: []
})
# 创建使用自定义角色的用户
db.createUser({
user: "productAdmin",
pwd: "productPassword123",
roles: [{ role: "productManager", db: "ecommerce" }]
})
# 验证自定义角色和用户
db.getRoles({ showPrivileges: true })
db.getUsers()
# 预期结果显示productManager角色和productAdmin用户
# 5. 测试用户权限
# 使用业务用户连接
mongosh --port 27117 -u "appUser" -p "appPassword123" --authenticationDatabase "ecommerce"
# 测试读写权限
use ecommerce
db.products.insertOne({ name: "Laptop", price: 999, category: "Electronics" })
db.products.find()
db.products.updateOne({ name: "Laptop" }, { $set: { price: 899 } })
# 预期结果:所有操作成功执行
# 6. 测试自定义角色权限
# 使用自定义角色用户连接
mongosh --port 27017 -u "productAdmin" -p "productPassword123" --authenticationDatabase "ecommerce"
use ecommerce
# 测试允许的操作
db.products.find()
db.products.updateOne({ name: "Laptop" }, { $set: { description: "High-performance laptop" } })
# 预期结果:查询和更新操作成功
# 测试禁止的操作
db.products.insertOne({ name: "Mouse", price: 25 })
# 预期结果:操作失败,提示权限不足
db.products.deleteOne({ name: "Laptop" })
# 预期结果:操作失败,提示权限不足
# 8. 查看用户和角色信息
# 查看所有用户
use admin
db.system.users.find().pretty()
# 查看所有角色
db.system.roles.find().pretty()
# 查看当前用户权限
db.runCommand({ connectionStatus: 1 })
# 预期结果:显示当前连接的用户信息和权限
# 9. 权限管理操作
use ecommerce
# 为用户添加新角色
db.grantRolesToUser("appUser", [{ role: "dbAdmin", db: "ecommerce" }])
# 撤销用户角色
db.revokeRolesFromUser("appUser", [{ role: "dbAdmin", db: "ecommerce" }])
# 修改用户密码
db.updateUser("appUser", { pwd: "newPassword123" })
# 验证权限变更
db.getUser("appUser")
# 预期结果:显示用户的最新角色信息
```