ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

等保测评数据库实操指南:MySQL、Oracle、Redis 等五类数据库检查清单

等保测评数据库实操指南:MySQL、Oracle、Redis 等五类数据库检查清单 简介这份作业指导书面向数据库运维、安全测评与等保合规从业人员系统梳理了MySQL、Oracle、SQL Server、Postgres、Redis五类主流数据库在等级保护测评中的实操要点。资源包内含1个docx文档大小约1.83MB按数据库类型分五个部分编排结构清晰、便于按需查阅。内容覆盖各数据库的连接登录方式与测评基本查询语句例如MySQL的密码复杂度与有效期、登录失败处理、超时时间、用户登录IP限制、审计开启及远程加密管理SQL Server的密码策略、失败锁定、自动超时退出、用户权限与终端IP访问测试Postgres的版本、用户名、密码有效期、失败次数限制与审计参数以及Redis的连接与测评查询方法。读者可据此快速定位对应数据库的核查命令与判断依据减少自行摸索成本适合作为等保测评现场作业的参考手册与自查清单。目前已有785人学习下载。1. 等保测评里数据库这一关为什么总在“看起来没问题”的地方翻车做过等保测评的人都有一个共识主机、网络、应用层的整改往往还能靠堆设备、加策略糊弄过去唯独数据库这一块最容易在“看起来没问题”的地方翻车。MySQL、Oracle、SQL Server、PostgreSQL、Redis 这五类数据库几乎覆盖了国内绝大多数业务系统但它们的等保测评作业逻辑完全不同——关系型数据库查的是身份鉴别、访问控制、安全审计、数据完整性Redis 这类缓存数据库查的是未授权访问、危险命令禁用、持久化文件权限。很多团队拿着同一份检查表去套所有数据库结果就是 MySQL 过了、Redis 裸奔、Oracle 的审计策略根本没开。这篇作业指导书要解决的问题很具体给你一套可以照着走的流程把五类数据库的等保测评从“凭感觉查”变成“按清单过”。适合谁看一是正在做等保整改的运维和 DBA二是需要出具测评结论的测评机构工程师三是负责统筹等保项目的安全负责人。我不会只讲概念每一类数据库都会落到具体的查询语句、配置文件路径、参数值和验证命令上。先立住一个判断等保测评不是把数据库加固到最严而是把测评项逐条对应到可验证的证据上证据链完整比配置漂亮更重要。2. 五类数据库的等保测评项拆解从身份鉴别到数据完整性2.1 关系型数据库的四个核心测评维度MySQL、Oracle、SQL Server、PostgreSQL 虽然语法和架构不同但在等保 2.0 的测评框架下核心维度是一致的身份鉴别、访问控制、安全审计、数据完整性。身份鉴别看的是有没有强密码策略、有没有多因素认证、登录失败有没有锁定访问控制看的是账号权限有没有最小化、有没有多余的默认账号、角色划分是否清晰安全审计看的是有没有开启审计日志、日志能不能追溯到具体用户和操作数据完整性看的是传输和存储有没有加密、备份是否可恢复。这四个维度在测评时不是并列关系而是有优先级的。身份鉴别和访问控制是必查项几乎每个等保三级项目都会重点看安全审计在三级以上是强制项二级项目可能只做抽查数据完整性则更多看业务系统的实际需求比如涉及个人敏感信息的系统会重点查加密。我一般会先确认系统的等保级别再决定每个维度的检查深度避免在二级项目上花三级的时间。2.2 Redis 为什么不能套用关系型数据库的检查表Redis 的等保测评逻辑和关系型数据库有本质区别。Redis 默认没有用户名概念只有一个可选的 requirepass 密码而且早期版本默认绑定 0.0.0.0 且无密码。等保测评对 Redis 的核心关注点是有没有未授权访问、有没有禁用危险命令、持久化文件有没有权限控制、有没有绑定内网地址。很多团队在整改时只加了密码但没改 bind 配置结果 Redis 仍然监听在所有网卡上。测评时用 redis-cli -h 目标IP 直接连如果不需要密码就能执行 INFO 命令这一项直接判不符合。另一个高频问题是 CONFIG、FLUSHALL、KEYS 这些危险命令没有重命名或禁用攻击者一旦连上就能清库或导出所有键。Redis 的等保整改必须同时做三件事设密码、改绑定地址、重命名危险命令缺一不可。2.3 测评证据的采集方式命令、配置文件与日志等保测评的结论必须有证据支撑不能只靠“我配了”。关系型数据库的证据采集主要靠三类一是查询语句比如 MySQL 的 SELECT user,host FROM mysql.user 看账号列表Oracle 的 SELECT username, account_status FROM dba_users 看账号状态二是配置文件比如 PostgreSQL 的 pg_hba.conf 看认证方式SQL Server 的配置管理器看混合认证模式三是日志文件比如 MySQL 的 general_log 和 audit_logOracle 的 AUD$ 表。Redis 的证据采集更直接redis-cli 连上去执行 CONFIG GET 看关键参数检查 redis.conf 里的 bind、requirepass、rename-command 配置再看持久化文件 dump.rdb 和 appendonly.aof 的权限。我一般会把这些证据按测评项编号整理成表格每一项对应一条命令或一个文件路径测评时直接照着采避免现场翻文档。3. MySQL 与 PostgreSQL 的实操检查账号、权限与审计配置3.1 MySQL 账号安全与密码策略的检查命令MySQL 的等保测评从账号清单开始。先连上数据库执行下面这条查询看有没有匿名账号、有没有 host 为 % 的账号、有没有空密码账号-- 查看所有账号及其来源主机 SELECT user, host, authentication_string, plugin FROM mysql.user ORDER BY user, host; -- 检查是否存在匿名账号user 为空 SELECT user, host FROM mysql.user WHERE user ; -- 检查是否存在 host 为 % 的账号允许任意主机连接 SELECT user, host FROM mysql.user WHERE host %; -- 检查密码是否为空authentication_string 为空 SELECT user, host FROM mysql.user WHERE authentication_string OR authentication_string IS NULL;这三条查询的结果直接对应等保测评的身份鉴别项。匿名账号必须删除host 为 % 的账号要确认是否必要空密码账号必须立即整改。MySQL 8.0 之后默认使用 caching_sha2_password 插件比 mysql_native_password 更安全测评时可以把这个作为加分项。密码策略的检查要看 validate_password 插件有没有安装和启用-- 查看密码策略插件状态 SHOW PLUGINS WHERE Name validate_password; -- 查看密码策略参数 SHOW VARIABLES LIKE validate_password%;如果 validate_password 没有启用等保三级项目基本会判不符合。关键参数是 validate_password.policy建议设为 MEDIUM 或 STRONGvalidate_password.length 建议不低于 8。设置完策略后已有账号的密码不会自动重新校验需要手动 ALTER USER 重置一次。3.2 PostgreSQL 的 pg_hba.conf 与审计日志配置PostgreSQL 的访问控制核心在 pg_hba.conf 文件里。这个文件决定了哪些主机、哪些用户、哪些数据库可以用什么认证方式连接。等保测评时重点看有没有 trust 认证方式因为 trust 意味着完全信任不需要密码# 查看 pg_hba.conf 中的认证配置 cat /var/lib/pgsql/data/pg_hba.conf | grep -v ^# | grep -v ^$ # 检查是否存在 trust 认证 grep -i trust /var/lib/pgsql/data/pg_hba.conf如果发现 trust必须改成 md5 或 scram-sha-256。scram-sha-256 比 md5 更安全PostgreSQL 10 之后都支持。改完 pg_hba.conf 后需要 reload 配置# 重新加载 PostgreSQL 配置 pg_ctl reload -D /var/lib/pgsql/data # 或者用 SQL 命令 SELECT pg_reload_conf();审计日志方面PostgreSQL 默认只记录启动、关闭和错误信息不记录具体查询。等保三级项目需要开启 pgaudit 扩展或者配置 log_statement-- 查看当前日志配置 SHOW log_statement; SHOW log_connections; SHOW log_disconnections; -- 建议配置在 postgresql.conf 中修改 -- log_statement all 或 ddl -- log_connections on -- log_disconnections on -- log_line_prefix %t [%p]: [%l-1] user%u,db%d,app%a,client%h log_statement 设为 all 会记录所有 SQL 语句对性能有影响生产环境建议设为 ddl 或 mod。log_line_prefix 的格式决定了日志能不能追溯到具体用户和客户端 IP等保测评时会检查这个格式是否包含用户、数据库、客户端地址三个要素。3.3 用 SQL 验证权限最小化与角色分离访问控制的测评核心是权限最小化。MySQL 和 PostgreSQL 都需要检查有没有账号拥有超出业务需要的权限。MySQL 的检查命令-- 查看所有用户的权限 SELECT * FROM mysql.user WHERE user NOT IN (mysql.sys, mysql.session, mysql.infoschema); -- 查看具体用户的授权 SHOW GRANTS FOR app_user192.168.1.%; -- 检查是否有用户拥有 SUPER 或 FILE 权限 SELECT user, host FROM mysql.user WHERE Super_priv Y OR File_priv Y;SUPER 权限允许用户终止其他会话、修改全局变量FILE 权限允许读写服务器文件这两个权限在等保测评中属于高风险项。业务账号不应该有这两个权限只有 DBA 账号可以保留。PostgreSQL 的权限检查-- 查看所有角色及其属性 SELECT rolname, rolsuper, rolcreaterole, rolcreatedb, rolcanlogin FROM pg_roles WHERE rolname NOT LIKE pg_%; -- 查看数据库级别的权限 SELECT datname, datacl FROM pg_database; -- 查看表级别的权限 SELECT grantee, table_schema, table_name, privilege_type FROM information_schema.table_privileges WHERE grantee NOT IN (postgres, PUBLIC);PostgreSQL 的 PUBLIC 角色默认拥有一些权限等保测评时建议回收 PUBLIC 的不必要权限特别是 CREATE 权限。角色分离方面建议把业务账号、只读账号、管理账号分开不要用同一个账号做所有事。4. Oracle 与 SQL Server 的实操检查审计策略与认证模式4.1 Oracle 审计策略的开启与验证Oracle 的等保测评最容易被扣分的地方是审计没开。Oracle 的审计分传统审计和统一审计两种11g 默认用传统审计12c 之后推荐统一审计。先检查当前审计状态-- 查看传统审计参数 SHOW PARAMETER audit_trail; -- 查看统一审计策略12c 及以上 SELECT policy_name, enabled_option, audit_condition FROM audit_unified_policies; -- 查看已启用的统一审计策略 SELECT policy_name, enabled_option FROM audit_unified_enabled_policies;audit_trail 参数如果是 NONE说明审计完全没开等保测评直接判不符合。如果是 DB审计记录写在数据库表里如果是 OS写在操作系统文件里如果是 XML写在 XML 文件里。等保三级建议设为 DB 或 XML方便查询和保留。开启传统审计的步骤-- 修改审计参数需要重启数据库 ALTER SYSTEM SET audit_trail DB SCOPE SPFILE; -- 重启后开启具体审计项 AUDIT CREATE SESSION BY ACCESS; AUDIT CREATE TABLE BY ACCESS; AUDIT DROP TABLE BY ACCESS; AUDIT ALTER TABLE BY ACCESS; AUDIT GRANT BY ACCESS; AUDIT REVOKE BY ACCESS; -- 查看审计记录 SELECT username, action_name, obj_name, timestamp FROM dba_audit_trail ORDER BY timestamp DESC;统一审计的开启方式不同需要先创建审计策略再启用-- 创建统一审计策略 CREATE AUDIT POLICY audit_ddl_policy ACTIONS CREATE TABLE, DROP TABLE, ALTER TABLE; -- 启用策略 AUDIT POLICY audit_ddl_policy; -- 查看审计记录 SELECT audit_type, dbusername, action_name, object_name, event_timestamp FROM unified_audit_trail ORDER BY event_timestamp DESC;统一审计比传统审计更灵活可以按条件过滤但配置复杂度也更高。我一般建议新系统直接用统一审计老系统如果已经开了传统审计可以保持不动避免迁移风险。4.2 SQL Server 的混合认证模式与登录审计SQL Server 的等保测评第一个检查点是认证模式。SQL Server 支持 Windows 认证和混合认证两种模式混合认证允许 SQL Server 账号登录风险更高。检查方式-- 查看服务器认证模式 SELECT SERVERPROPERTY(IsIntegratedSecurityOnly) AS IsWindowsOnly; -- 返回 1 表示仅 Windows 认证返回 0 表示混合认证 -- 查看所有登录账号 SELECT name, type_desc, is_disabled, create_date, modify_date FROM sys.server_principals WHERE type IN (S, U, G) ORDER BY name; -- 查看是否有空密码或弱密码账号需要结合策略检查 SELECT name, is_policy_checked, is_expiration_checked FROM sys.sql_logins;is_policy_checked 为 0 表示没有启用密码策略is_expiration_checked 为 0 表示密码不过期。等保测评要求这两个至少有一个为 1三级项目建议都设为 1。SQL Server 的审计功能通过 SQL Server Audit 实现可以审计登录失败、权限变更、数据修改等-- 创建服务器级别审计 CREATE SERVER AUDIT [Audit_Login] TO FILE (FILEPATH D:\AuditLogs\, MAXSIZE 100 MB, MAX_ROLLOVER_FILES 10) WITH (ON_FAILURE CONTINUE); -- 启用审计 ALTER SERVER AUDIT [Audit_Login] WITH (STATE ON); -- 创建审计规范 CREATE SERVER AUDIT SPECIFICATION [Audit_Login_Spec] FOR SERVER AUDIT [Audit_Login] ADD (FAILED_LOGIN_GROUP), ADD (SUCCESSFUL_LOGIN_GROUP), ADD (DATABASE_PERMISSION_CHANGE_GROUP) WITH (STATE ON); -- 查看审计记录 SELECT event_time, action_id, succeeded, server_principal_name, statement FROM sys.fn_get_audit_file(D:\AuditLogs\*, DEFAULT, DEFAULT);审计文件路径要确保有足够的磁盘空间MAX_ROLLOVER_FILES 控制文件轮转数量。ON_FAILURE CONTINUE 表示审计写入失败时继续运行等保测评一般建议设为 CONTINUE避免审计故障导致业务中断。4.3 用配置查询验证密码策略与登录失败锁定Oracle 的密码策略通过 PROFILE 管理检查命令-- 查看所有 PROFILE 的密码策略 SELECT profile, resource_name, limit FROM dba_profiles WHERE resource_name IN ( FAILED_LOGIN_ATTEMPTS, PASSWORD_LIFE_TIME, PASSWORD_REUSE_MAX, PASSWORD_VERIFY_FUNCTION ) ORDER BY profile, resource_name; -- 查看用户使用的 PROFILE SELECT username, profile FROM dba_users WHERE account_status OPEN;FAILED_LOGIN_ATTEMPTS 建议设为 5 到 10PASSWORD_LIFE_TIME 建议设为 90 天以内PASSWORD_VERIFY_FUNCTION 应该指向一个密码复杂度校验函数。Oracle 默认的 DEFAULT PROFILE 这些值都是 UNLIMITED必须修改。SQL Server 的登录失败锁定通过策略组管理检查方式-- 查看登录失败锁定策略需要 Windows 策略或 SQL Server 策略 SELECT name, is_policy_checked, is_expiration_checked, LOGINPROPERTY(name, BadPasswordCount) AS BadPasswordCount, LOGINPROPERTY(name, LockoutTime) AS LockoutTime FROM sys.sql_logins;SQL Server 的锁定策略依赖 Windows 的账户策略如果 SQL Server 运行在域环境里直接继承域策略如果是独立服务器需要在本地安全策略里配置。等保测评时会检查锁定阈值和锁定时间建议阈值设为 5 次锁定时间设为 15 分钟以上。5. Redis 与全类数据库的避坑排查从未授权访问到审计缺失5.1 Redis 未授权访问与危险命令的排查Redis 的未授权访问是等保测评中最常见的不符合项。排查步骤# 从外部主机尝试连接替换为目标 IP redis-cli -h 192.168.1.100 -p 6379 # 如果不需要密码就能执行命令说明存在未授权访问 INFO server CONFIG GET requirepass CONFIG GET bind如果 INFO 命令能直接执行说明没有设密码或者密码没生效。检查 redis.conf# 查看关键配置 grep -E ^(bind|requirepass|rename-command|protected-mode) /etc/redis/redis.conf # 推荐配置 # bind 127.0.0.1 或 bind 内网IP # requirepass 强密码 # protected-mode yes # rename-command CONFIG # rename-command FLUSHALL # rename-command FLUSHDB # rename-command KEYS protected-mode 是 Redis 3.2 之后引入的保护模式当没有设密码且没有绑定特定地址时只允许本地连接。但很多团队为了远程管理把 protected-mode 设为 no这就等于把 Redis 暴露出去。rename-command 把危险命令重命名为空字符串等于禁用该命令这是等保测评的推荐做法。5.2 审计日志缺失与日志保留周期的整改审计日志缺失是五类数据库的通病。MySQL 的 general_log 默认关闭Oracle 的 audit_trail 默认 NONESQL Server 默认没有审计规范PostgreSQL 默认只记录错误Redis 只有慢查询日志。等保测评要求审计日志保留至少 6 个月三级项目要求 12 个月。整改时要注意日志保留周期和磁盘空间的平衡。MySQL 的 general_log 如果设为 ON所有查询都会写入文件高并发场景下磁盘很快写满。我一般建议用 audit_log 插件代替 general_log只记录必要的操作类型。Oracle 的审计记录存在 SYSTEM 表空间需要定期清理和归档否则会把表空间撑爆。SQL Server 的审计文件要设置 MAX_ROLLOVER_FILES避免无限增长。PostgreSQL 的 log_statement 设为 all 时日志量会大幅增加建议配合 log_rotation_age 和 log_rotation_size 做轮转。Redis 的慢查询日志通过 slowlog-log-slower-than 配置等保测评不强制要求但建议开启作为辅助证据。5.3 常见踩坑记录现象、原因与解决坑一MySQL 改了密码策略但旧账号没生效。现象是 validate_password 已启用但旧账号仍然能用弱密码登录。原因是密码策略只对新密码生效已有密码不会重新校验。解决方法是逐个账号执行 ALTER USER ‘user’‘host’ IDENTIFIED BY ‘新密码’强制刷新密码。坑二Oracle 审计开了但查不到记录。现象是 audit_trail 设为 DB但 dba_audit_trail 表里没有数据。原因是审计项没有单独开启audit_trail 只是总开关具体操作需要 AUDIT 语句逐项开启。解决方法是执行 AUDIT CREATE SESSION、AUDIT CREATE TABLE 等语句再用 SELECT 验证。坑三SQL Server 审计文件写满磁盘。现象是审计日志目录占满磁盘业务写入失败。原因是 MAXSIZE 设得太大或者 MAX_ROLLOVER_FILES 设得太多。解决方法是把 MAXSIZE 设为 100MB 以内MAX_ROLLOVER_FILES 设为 10 以内并配置定期归档。坑四PostgreSQL 改了 pg_hba.conf 但没生效。现象是配置文件已改但连接仍然用旧认证方式。原因是 pg_hba.conf 修改后需要 reload 或 restartreload 对已有连接不生效。解决方法是执行 pg_ctl reload 后断开所有现有连接再重连或者直接 restart。坑五Redis 设了密码但仍然未授权访问。现象是 requirepass 已配置但外部仍然能连。原因是 bind 没有改Redis 仍然监听 0.0.0.0而且 protected-mode 被设为 no。解决方法是同时修改 bind 为内网地址、设 requirepass、保持 protected-mode yes三个条件同时满足才能阻断未授权访问。6. 把等保测评从一次性检查变成常态化验证等保测评不是每年做一次就完事数据库的配置会随着业务变更、版本升级、人员操作而漂移。我见过太多系统在测评通过后三个月因为一次紧急扩容把 Redis 的 bind 改回了 0.0.0.0或者因为一次版本升级把 MySQL 的密码策略插件卸掉了。真正省心的做法是把测评项变成常态化验证脚本每周跑一次发现漂移立即告警。下面是一个跨数据库的验证脚本框架用 Python 实现可以按数据库类型分别检查关键项import subprocess import json from datetime import datetime # 检查项配置数据库类型、连接方式、检查命令、期望结果 CHECKS { mysql: { cmd: mysql -u check_user -p密码 -e \SELECT user,host FROM mysql.user WHERE user OR host%;\, expect_empty: True, desc: 检查匿名账号和任意主机账号 }, redis: { cmd: redis-cli -h 127.0.0.1 CONFIG GET bind, expect_contains: 127.0.0.1, desc: 检查 Redis 绑定地址 }, postgresql: { cmd: grep -i trust /var/lib/pgsql/data/pg_hba.conf, expect_empty: True, desc: 检查 PostgreSQL trust 认证 } } def run_check(db_type, config): 执行单个检查项返回是否符合 try: result subprocess.run( config[cmd], shellTrue, capture_outputTrue, textTrue, timeout10 ) output result.stdout.strip() if config.get(expect_empty): passed len(output) 0 elif config.get(expect_contains): passed config[expect_contains] in output else: passed False return { db: db_type, desc: config[desc], passed: passed, output: output[:200], # 截断避免日志过长 time: datetime.now().isoformat() } except Exception as e: return { db: db_type, desc: config[desc], passed: False, output: str(e), time: datetime.now().isoformat() } def main(): 遍历所有检查项并输出结果 results [] for db_type, config in CHECKS.items(): result run_check(db_type, config) results.append(result) status 通过 if result[passed] else 不符合 print(f[{status}] {db_type}: {result[desc]}) # 输出 JSON 格式便于对接告警系统 print(json.dumps(results, ensure_asciiFalse, indent2)) if __name__ __main__: main()这个脚本的逻辑很直接每个检查项定义一条命令和期望结果expect_empty 表示命令输出为空才算通过expect_contains 表示输出包含指定字符串才算通过。实际使用时把连接命令和密码替换成环境变量避免硬编码。输出格式用 JSON方便对接监控系统做告警。参数调整方面timeout 设为 10 秒是防止某个数据库连接卡住导致整个脚本挂起。output 截断到 200 字符是避免日志文件过大。如果要做更细粒度的检查可以扩展 CHECKS 字典比如加上 Oracle 的 audit_trail 检查、SQL Server 的 IsIntegratedSecurityOnly 检查。我自己的习惯是把这个脚本放在跳板机上用 crontab 每周一早上跑一次结果写入日志文件同时把不符合项推送到内部告警群。这样等保测评前只需要看最近三个月的验证记录就能证明数据库配置没有漂移测评师也会认可这种常态化验证的证据链。希望帮到你。本文还有配套的精品资源点击获取
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进