如何审计PostgreSQL超级用户对pg_user_mappings视图的访问?
可行,以下是几种实现审计的方案
方法1:使用pgAudit审计扩展
pgAudit是PostgreSQL生态中成熟的审计工具,可精准捕获特定对象的访问操作(Greenplum也兼容该扩展):
- 先安装扩展:
CREATE EXTENSION pgaudit; - 修改数据库配置文件(PostgreSQL为
postgresql.conf,Greenplum需同步所有节点配置),启用审计:shared_preload_libraries = 'pgaudit' # 需重启数据库生效 pgaudit.log = 'read' pgaudit.log_parameter = on - 针对
gp_user_mappings视图配置审计规则,仅监控超级用户的SELECT操作:
审计记录会写入数据库日志文件,可定期解析或监控这些日志获取操作详情。-- 为所有超级用户开启该视图的审计 ALTER ROLE superuser SET pgaudit.log_relation = 'gp_user_mappings';
方法2:自定义视图+触发器审计
由于系统视图无法直接创建触发器,可通过替代视图实现审计:
- 创建与原视图结构一致的自定义视图:
CREATE VIEW custom_gp_user_mappings AS SELECT * FROM gp_user_mappings; - 创建审计日志表存储记录:
CREATE TABLE gp_user_mappings_audit_log ( audit_id SERIAL PRIMARY KEY, operator TEXT NOT NULL, operate_time TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, query_content TEXT NOT NULL ); - 编写触发器函数,记录超级用户的SELECT操作:
CREATE OR REPLACE FUNCTION audit_gp_user_mappings_func() RETURNS TRIGGER AS $$ BEGIN IF EXISTS (SELECT 1 FROM pg_roles WHERE rolname = current_user AND rolsuper = true) THEN INSERT INTO gp_user_mappings_audit_log (operator, query_content) VALUES (current_user, current_query()); END IF; RETURN NEW; END; $$ LANGUAGE plpgsql; - 在自定义视图上创建触发器:
CREATE TRIGGER trigger_audit_gp_user_mappings INSTEAD OF SELECT ON custom_gp_user_mappings FOR EACH STATEMENT EXECUTE FUNCTION audit_gp_user_mappings_func(); - 限制原视图访问权限,强制使用自定义视图:
REVOKE SELECT ON gp_user_mappings FROM PUBLIC; GRANT SELECT ON custom_gp_user_mappings TO PUBLIC;
方法3:数据库日志过滤
无需额外扩展,通过配置日志参数筛选目标操作:
- 修改
postgresql.conf开启全量语句日志:log_statement = 'all' log_line_prefix = '%t [%p]: user=%u,db=%d ' - 用日志分析工具(如grep)定期扫描日志,提取超级用户访问目标视图的记录:
该方法简单直接,但需做好日志轮转和存储管理,避免日志量过大。grep "user=.*superuser.*SELECT.*gp_user_mappings" /path/to/postgresql/pg_log/*.log
注意事项
- Greenplum集群需确保所有节点配置同步,避免审计遗漏。
- 审计日志需设置严格权限,仅授权审计人员访问,防止日志泄露或篡改。
- 方法2中需限制超级用户直接访问原系统表的权限,避免绕过审计。
内容的提问来源于stack exchange,提问作者Ahmad Qudan
相关产品推荐
相关产品推荐

