08-27-周三_17-09-29
This commit is contained in:
273
数据库/MongoDB_2025/MongoDB安全管理.md
Normal file
273
数据库/MongoDB_2025/MongoDB安全管理.md
Normal file
@@ -0,0 +1,273 @@
|
||||
# 安全管理
|
||||
|
||||
确保数据库的安全是任何应用都必须考虑的关键问题。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")
|
||||
# 预期结果:显示用户的最新角色信息
|
||||
```
|
Reference in New Issue
Block a user