德雷克与陷阱
119.9MB · 2026-03-05
在数据库安全体系中,如果说身份鉴别是“门禁系统”,权限控制是“内部区域划分”,那么审计追踪就是全方位的“监控系统”。它记录着谁、在什么时间、从哪里、执行了什么操作、操作结果如何——这些信息不仅是事故溯源的“黑匣子”,更是满足等保合规要求的必备条件。
本文将深入 KingbaseES 的审计体系,从基础配置到高级运维,助你构建“可追溯、可控制、可运维”的安全审计能力。作为“KingbaseES 安全三部曲”的终章,本文将与前两篇《用户、会话与连接控制》、《对象访问权限管理》协同联动,共同构建事前预防、事中控制、事后溯源的关键防线,为数据库安全治理打下坚实基础。
面对“谁删除了业务数据”的故障复盘,若缺失审计日志,责任界定将陷入无据可查的盲区。审计的核心价值恰恰在于:
KingbaseES 提供了三种互补的审计粒度,根据官方文档定义:
| 审计类型 | 审计内容 | 类比理解 | 适用场景 |
|---|---|---|---|
| 服务器事件审计 | 服务器启动、停止、重载配置、用户登录、用户登出 | 监控系统开关门、断电等事件 | 追踪数据库服务状态、发现暴力破解 |
| 语句级别审计 | 对 DDL、DML、DQL、DCL、TCL 等语句引发的事件进行审计 | 监控“有人在操作”而不是“操作了什么” | 发现高危操作(如 DROP、TRUNCATE) |
| 模式对象级别审计 | 在确定的模式对象(表、视图、存储过程、函数、序列)上执行操作时引发的事件审计 | 监控“谁进了金库、拿了什么” | 核心敏感表精细化追踪 |
审计日志本身也是敏感信息,因此 KES 严格遵循“三员分立”原则,通过权限隔离实现相互监督:
| 角色 | 职责 | 查看范围 | 限制 |
|---|---|---|---|
| SAO(审计管理员) | 开启/关闭审计开关,配置对 SYSTEM 和 SSO 的审计策略 | SYSTEM、SSO 的操作记录 | 不能创建业务表,不能修改 SSO 密码 |
| SSO(安全管理员) | 配置对 SAO 和普通用户的审计策略 | SAO、普通用户的操作记录 | 不能创建业务表,不能修改 SAO 密码 |
| SYSTEM(系统管理员) | 日常业务运维 | 无法查看任何审计记录 | 受 SAO 监控 |
为了更直观地理解审计系统的运作机制,我们将审计生命周期划分为配置、运行、审计三个阶段。下图展示了 SAO(审计管理员)、业务用户与系统之间的交互流程:
审计功能依赖 sysaudit 插件。关键前置条件:确保 max_worker_processes 参数值有足够余量,否则审计后台进程无法启动。
-- 1. 检查并发进程数是否满足要求
SHOW max_worker_processes;
# 2. 编辑配置文件,添加审计插件
vim /data/kingbase.conf
shared_preload_libraries = '..., sysaudit' # 在原有插件列表后添加
# 3. 重启数据库
sys_ctl restart -D /data
审计功能由 SAO 用户统一管理:
-- 以 SAO 身份连接
c test sao
-- 开启全局审计总开关
ALTER SYSTEM SET sysaudit.enable = 'on';
SELECT sys_reload_conf();
-- 确认开启状态
SHOW sysaudit.enable;
sysaudit 插件提供的主要审计参数如下:
| 参数 | 使用说明 | 推荐配置 |
|---|---|---|
sysaudit.serverevent | ⭐ 服务器事件审计开关(启停、重载) | on (生产必开) |
sysaudit.userevent | ⭐ 用户事件审计开关(登录登出) | on (生产必开) |
sysaudit.enable | 审计功能总开关 | on |
sysaudit.syntaxerror | 语法错误审计开关 | off (按需开启) |
sysaudit.bgw_workers | 审计后台进程数,默认为 1 | 默认即可 |
sysaudit.shared_cache | 审计共享内存大小,默认 10MB | 内存充裕可调大 |
sysaudit.third_store_num | 批量提交审计日志条数,默认为 1 | 高并发可调至 100 |
语句级审计关注“某类操作”。注意权限边界:SAO 用户只能为 SYSTEM 和 SSO 用户配置审计规则。
-- 以 SAO 身份登录
c test sao
-- 审计 system 用户的表创建和删除操作
SELECT sysaudit.set_audit_stmt('CREATE TABLE', 'system', null, null);
SELECT sysaudit.set_audit_stmt('DROP TABLE', 'system', null, null);
-- 查看已配置的审计规则
SELECT * FROM sysaudit.all_audit_rules;
对象级审计实现精细化监控。注意权限边界:SSO 用户负责为普通用户和 SAO 用户配置审计规则。
首先创建测试用户和测试表:
-- 以 SYSTEM 身份连接
c test system
-- 创建测试普通用户 user01
CREATE USER user01 PASSWORD 'Kingbase@123';
-- 创建测试业务表
CREATE TABLE business_info (id int, info text);
CREATE TABLE account_info (id int, account_no text, balance numeric);
-- 授予 user01 必要的权限
GRANT SELECT, INSERT, UPDATE, DELETE ON business_info TO user01;
GRANT SELECT, INSERT, UPDATE, DELETE ON account_info TO user01;
-- 插入测试数据
INSERT INTO business_info VALUES (1, 'test data');
INSERT INTO account_info VALUES (1001, '6228480012345678', 10000.00);
-- 以 SSO 身份登录配置审计规则
c test sso
-- 审计普通用户 user01 对 business_info 表的所有操作
SELECT sysaudit.set_audit_object('TABLE', 'user01', 'public', 'business_info');
-- 审计所有用户对 account_info 表的操作
SELECT sysaudit.set_audit_object('TABLE', null, 'public', 'account_info');
-- 查看已配置的审计规则
SELECT * FROM sysaudit.all_audit_rules;
执行结果示例:
audit_id | audit_target | audit_type | audit_users | audit_schema | audit_objname | audit_objoid | creator_name
----------+--------------+------------+-------------+--------------+---------------+--------------+--------------
16400 | Object | table | user01 | public | business_info | 16387 | sso
16407 | Object | table | | public | account_info | 16401 | sso
从审计规则查询结果可以看出:
以 user01 身份执行一系列操作,触发审计记录:
-- 以 user01 身份连接
c test user01
-- 执行业务操作
SELECT * FROM business_info;
INSERT INTO business_info VALUES (2, 'more data');
UPDATE business_info SET info = 'updated' WHERE id = 1;
DELETE FROM business_info WHERE id = 2;
-- 查询核心表
SELECT * FROM account_info WHERE id = 1001;
以 SSO 身份登录 security 数据库,查看 user01 的审计记录:
-- 以 SSO 身份连接 security 数据库
c security sso
-- 查询 user01 的审计记录
SELECT username, opr_type, obj_name, result, audit_ts
FROM sysaudit_record_sso
WHERE username = 'user01'
ORDER BY audit_ts DESC;
执行结果示例:
username | opr_type | obj_name | result | audit_ts
----------+----------+---------------+--------+-------------------------------
user01 | 查询 | account_info | 成功 | 2026-03-02 20:46:00.293064+08
user01 | 删除 | business_info | 成功 | 2026-03-02 20:45:59.595305+08
user01 | 更新 | business_info | 成功 | 2026-03-02 20:45:59.595301+08
user01 | 插入 | business_info | 成功 | 2026-03-02 20:45:59.595293+08
user01 | 查询 | business_info | 成功 | 2026-03-02 20:45:59.595266+08
-- 取消编号为 16400 的审计策略(需由创建者执行)
CALL sysaudit.remove_audit(16400);
-- 取消所有审计策略
CALL sysaudit.remove_audit(null);
不同身份的审计员通过不同视图查询记录,这是三员分立的直接体现。
SAO 视角:查看 SYSTEM 和 SSO 的操作
c security sao
SELECT username, opr_type, obj_name, result, audit_ts
FROM sysaudit_record_sao
WHERE audit_ts > current_date - interval '7 days'
ORDER BY audit_ts DESC;
SSO 视角:查看 SAO 和普通用户的操作
c security sso
SELECT username, opr_type, obj_name, result, audit_ts
FROM sysaudit_record_sso
ORDER BY audit_ts DESC;
-- === 步骤 1:system 用户创建测试表 ===
c - system
CREATE TABLE demo_tbl (id int);
-- === 步骤 2:sao 用户开启审计、配置规则 ===
c - sao
ALTER system SET sysaudit.enable = on;
SELECT sys_reload_conf();
SELECT sysaudit.set_audit_stmt('DROP TABLE', 'system', null, null);
-- === 步骤 3:查看审计规则 ===
SELECT * FROM sysaudit.all_audit_rules;
-- === 步骤 4:system 执行操作触发审计 ===
c - system
DROP TABLE demo_tbl;
-- === 步骤 5:sao 登录 security 库查看审计日志 ===
c security sao
SELECT username, opr_type, obj_name, result FROM sysaudit_record_sao
WHERE opr_type = '删除表' ORDER BY audit_ts DESC;
-- === 步骤 6:取消审计规则 ===
c test sao
SELECT sysaudit.remove_audit(16421);
随着业务运行,审计表会逐渐膨胀。KES 通过“转储”机制将历史审计记录从在线表迁移到加密文件中,释放在线存储空间。
-- === 查看当前审计记录量 ===
SELECT COUNT(*), MIN(audit_ts), MAX(audit_ts) FROM sysaudit_record_sao;
-- === 转储 30 天前的记录 ===
SELECT sysaudit.dump_auditlog(30);
-- === 查看生成的转储文件 ===
SELECT sysaudit.show_audlog_dump_file();
-- === 需要时从文件恢复 ===
SELECT sysaudit.restore_auditlog('AUDIT_DUMP_FILE-20260123_143000');
前置准备: 在执行以下 SQL 前,请务必在操作系统层面完成目录创建与授权:
mkdir -p /archive/audit_dump
chown kingbase:kingbase /archive/audit_dump
chmod 700 /archive/audit_dump
配置命令:
-- === 配置自动转储参数 ===
ALTER SYSTEM SET sysaudit.auditlog_dump_dir = '/archive/audit_dump';
ALTER SYSTEM SET sysaudit.enable_auto_dump_auditlog = 'on';
ALTER SYSTEM SET sysaudit.max_auditlog_size = '10GB';
ALTER SYSTEM SET sysaudit.auditlog_keep_days = 90;
SELECT sys_reload_conf();
KES 支持将审计日志存储到独立的审计数据库中,实现审计数据与生产数据的物理隔离:
-- === 配置远程审计数据库连接 ===
ALTER SYSTEM SET sysaudit.audit_table_hostaddr = '192.168.126.16';
ALTER SYSTEM SET sysaudit.audit_table_port = '54321';
ALTER SYSTEM SET sysaudit.audit_table_user = 'sao';
ALTER SYSTEM SET sysaudit.audit_table_password = '******';
ALTER SYSTEM SET sysaudit.local_sao_password = '******';
SELECT sys_reload_conf();
审计功能对数据库性能的影响主要来源于:
三种审计类型对性能的影响程度:
服务器事件审计 < 语句级别审计 < 模式对象级别审计
基于前文实践案例,我们可以总结出一套实用的分级审计策略。
| 级别 | 审计对象 | 审计类型 | 审计用户 | 适用场景 |
|---|---|---|---|---|
| L1 | 核心敏感表 | 对象级审计 | 所有用户 | 资金账户、客户信息等,需全量记录 |
| L2 | 重要业务表 | 对象级审计 | 特定应用户 | 业务流水表,仅审计应用账号,减少干扰 |
| L3 | 普通业务表 | 语句级审计 | 所有用户 | 配置表、字典表,仅关注 DDL 结构变更 |
| L4 | 日志/临时表 | 无审计 | - | 数据量大且价值低,不创建规则 |
-- L1:核心敏感表做对象级审计(对所有用户)
SELECT sysaudit.set_audit_object('TABLE', null, 'public', 'account_info');
SELECT sysaudit.set_audit_object('TABLE', null, 'public', 'customer_info');
-- L2:重要业务表做对象级审计(仅对特定用户)
SELECT sysaudit.set_audit_object('TABLE', 'app_user', 'public', 'transaction_log');
SELECT sysaudit.set_audit_object('TABLE', 'app_user', 'public', 'order_info');
-- L3:普通业务表只审计 DDL 操作
SELECT sysaudit.set_audit_stmt('DDL', 'app_user', 'public', null);
-- 内存充裕时可增大审计缓存,减少磁盘 I/O
ALTER SYSTEM SET sysaudit.shared_cache = '20MB';
-- 高并发场景调整批量提交条数,平衡内存占用与写入频率
ALTER SYSTEM SET sysaudit.third_store_num = '100';
-- 配置自动转储阈值,防止单表过大影响查询性能
ALTER SYSTEM SET sysaudit.max_auditlog_size = '10GB';
ALTER SYSTEM SET sysaudit.enable_auto_dump_auditlog = 'on';
SELECT sys_reload_conf();
某交易系统需满足:
| 审计对象 | 审计类型 | 审计内容 | 配置角色 | 保留策略 |
|---|---|---|---|---|
| 系统事件 | 服务器事件审计 | 启停、登录失败 | SAO | 6 个月 |
| 核心交易表 | 对象级审计 | 所有 DML 操作 | SSO | 2 年 |
| 重要业务表 | 对象级审计 | 仅对应用户审计 | SSO | 1 年 |
| 普通业务表 | 语句级审计 | 仅 DDL 操作 | SSO | 1 年 |
-- === 1. 以 SAO 身份配置基础审计 ===
c security sao
ALTER SYSTEM SET sysaudit.serverevent = 'on';
ALTER SYSTEM SET sysaudit.userevent = 'on';
-- === 2. 配置对象级审计(SSO 负责) ===
c test sso
-- 核心交易表:对所有用户做对象级审计
SELECT sysaudit.set_audit_object('TABLE', null, 'public', 'account_info');
-- 重要业务表:仅对应用户做对象级审计
SELECT sysaudit.set_audit_object('TABLE', 'app_user', 'public', 'business_info');
-- === 3. 查看已配置的审计规则 ===
SELECT * FROM sysaudit.all_audit_rules;
-- === 配置自动转储 ===
ALTER SYSTEM SET sysaudit.auditlog_dump_dir = '/data/audit_archive';
ALTER SYSTEM SET sysaudit.enable_auto_dump_auditlog = 'on';
ALTER SYSTEM SET sysaudit.max_auditlog_size = '10GB';
ALTER SYSTEM SET sysaudit.auditlog_keep_days = 730; -- 2 年
SELECT sys_reload_conf();
-- 以 app_user 身份执行操作后,SSO 查询审计记录
c security sso
-- 查询 app_user 对 business_info 表的操作
SELECT username, opr_type, obj_name, result, audit_ts
FROM sysaudit_record_sso
WHERE username = 'app_user' AND obj_name = 'business_info'
ORDER BY audit_ts DESC;
-- 查询所有用户对 account_info 表的操作
SELECT username, opr_type, obj_name, result, audit_ts
FROM sysaudit_record_sso
WHERE obj_name = 'account_info'
ORDER BY audit_ts DESC;
标准化排查步骤:
security 数据库。SHOW sysaudit.enable;
SELECT * FROM sys_stat_activity WHERE backend_type LIKE '%audit%';
SELECT * FROM sysaudit.all_audit_rules;
sysaudit_record_sao,SSO 查 sysaudit_record_sso)。解决方案:
ALL 类型)。max_auditlog_size 参数值,触发更频繁的转储。SELECT sysaudit.dump_auditlog(0); 立即转储并清理在线数据。性能优化检查清单:
shared_cache 和 third_store_num 参数是否适配当前负载?排查思路:
ls -ld <目录>).dbms_log,搜索 "dump" 或 "audit" 关键词,定位具体错误(如 "Permission denied")。至此,我们完成了KingbaseES安全体系的三部曲:
三者合一,方能构建坚不可摧的数据安全堡垒。
通过本文的深入解析,我们掌握了:
在实际应用中,建议始终遵循“最小必要”原则:在满足合规和安全需求的前提下,尽可能缩小审计范围、降低审计粒度,找到安全与性能的最佳平衡点。
延伸阅读: