权限管理
问题
数据库的权限管理体系是什么?如何实现最小权限原则?
答案
一、权限管理层次
二、MySQL 权限管理
用户与权限
-- 创建用户(限定来源 IP)
CREATE USER 'app_user'@'10.0.0.%' IDENTIFIED BY 'StrongPass123!';
-- 授予权限(按需分配)
-- 应用账号:只允许 DML
GRANT SELECT, INSERT, UPDATE, DELETE ON mydb.* TO 'app_user'@'10.0.0.%';
-- 只读账号
GRANT SELECT ON mydb.* TO 'readonly_user'@'10.0.0.%';
-- 管理员账号(仅限特定 IP)
GRANT ALL PRIVILEGES ON mydb.* TO 'admin_user'@'10.0.1.100';
-- 细粒度:只允许查某些列
GRANT SELECT (id, name, email) ON mydb.users TO 'limited_user'@'10.0.0.%';
-- 查看权限
SHOW GRANTS FOR 'app_user'@'10.0.0.%';
-- 撤销权限
REVOKE DELETE ON mydb.* FROM 'app_user'@'10.0.0.%';
-- 刷新权限
FLUSH PRIVILEGES;
常见权限列表
| 权限 | 说明 | 风险等级 |
|---|---|---|
| SELECT | 查询 | 低 |
| INSERT | 插入 | 低 |
| UPDATE | 更新 | 中 |
| DELETE | 删除 | 中 |
| CREATE | 建表/建库 | 高 |
| DROP | 删表/删库 | 极高 |
| ALTER | 修改表结构 | 高 |
| GRANT | 授权给其他用户 | 极高 |
| SUPER | 超级权限 | 极高 |
| FILE | 读写服务器文件 | 极高 |
三、PostgreSQL 权限管理
PostgreSQL 提供更精细的权限模型:
-- 创建角色
CREATE ROLE app_role;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO app_role;
-- 创建用户(用户 = 可登录的角色)
CREATE USER app_user WITH PASSWORD 'StrongPass123!' IN ROLE app_role;
-- Schema 级权限
GRANT USAGE ON SCHEMA public TO app_role;
-- 序列权限(自增 ID 需要)
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA public TO app_role;
-- 默认权限(新建表自动继承)
ALTER DEFAULT PRIVILEGES IN SCHEMA public
GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO app_role;
行级安全(Row Level Security)
PostgreSQL 支持 RLS,限制用户只能访问特定行:
-- 启用行级安全
ALTER TABLE orders ENABLE ROW LEVEL SECURITY;
-- 策略:用户只能看自己的订单
CREATE POLICY user_orders ON orders
FOR ALL
USING (user_id = current_setting('app.current_user_id')::INT);
-- 应用中设置当前用户
SET app.current_user_id = '42';
SELECT * FROM orders; -- 只返回 user_id = 42 的订单
RLS 的优势
- 安全下沉到数据库层:即使应用SQL写错了也不会泄露数据
- 对 ORM 透明:不需要修改查询逻辑
- Supabase 大量使用 RLS 实现多租户隔离
四、最小权限原则实践
┌────────────────────────────────────────────────┐
│ 数据库账号分类 │
├──────────────┬──────────────┬──────────────────┤
│ 应用账号 │ 运维账号 │ 分析账号 │
│ SELECT/INSERT │ CREATE/ALTER │ SELECT │
│ UPDATE/DELETE │ DROP/BACKUP │ (只读副本) │
│ 限定应用 IP │ 限定堡垒机 IP │ 限定 BI 工具 IP │
└──────────────┴──────────────┴──────────────────┘
| 原则 | 具体做法 |
|---|---|
| 按角色分配 | 应用、DBA、分析师使用不同账号 |
| 按环境隔离 | 开发、测试、生产使用不同账号和密码 |
| 限制来源 IP | 应用账号限定应用服务器 IP 段 |
| 禁用 root 远程 | root@localhost 仅限本地操作 |
| 定期审查 | 定期清理不再使用的账号 |
| 密码策略 | 强密码 + 定期轮换 |
五、多租户数据隔离
| 方案 | 说明 | 隔离级别 | 成本 |
|---|---|---|---|
| 独立数据库 | 每个租户一个库 | 最强 | 最高 |
| 独立 Schema | 同库不同 Schema | 强 | 中 |
| 共享表 + tenant_id | WHERE 条件过滤 | 中 | 最低 |
| 共享表 + RLS | 行级安全策略 | 中偏强 | 低 |
常见面试问题
Q1: 为什么不能用 root 账号连接生产数据库?
答案:
- 权限过大:root 可以 DROP DATABASE、修改其他用户权限
- 无法审计:所有操作都用 root,无法追溯具体操作人
- 安全风险:一旦密码泄露,攻击者获得完整控制权
- 误操作:DELETE 忘了 WHERE 条件直接清空表
Q2: 如何实现数据库连接的安全认证?
答案:
- 强密码策略:16+ 字符,包含大小写、数字、特殊字符
- SSL/TLS 连接:加密传输层,防止密码嗅探
- 证书认证:使用 x509 客户端证书(替代密码)
- IAM 认证:云数据库(如 AWS RDS)支持 IAM 临时凭证
- 密钥管理:密码存储在 Vault 等密钥管理系统,而非代码或配置文件
Q3: 什么是 RBAC?在数据库中如何实现?
答案:
RBAC(Role-Based Access Control)基于角色的访问控制:
-- 定义角色
CREATE ROLE app_readonly;
CREATE ROLE app_readwrite;
CREATE ROLE app_admin;
-- 角色授权
GRANT SELECT ON ALL TABLES IN SCHEMA public TO app_readonly;
GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO app_readwrite;
GRANT ALL PRIVILEGES ON SCHEMA public TO app_admin;
-- 用户分配角色
GRANT app_readonly TO analyst_user;
GRANT app_readwrite TO app_user;
GRANT app_admin TO dba_user;
好处:权限管理集中在角色上,人员变动时只需修改角色分配。