数据库安全这件事,说大不大,说小不小。很多团队在业务上线之初,优先盯着功能和性能,把安全当成“后期再补”的选项;等到数据泄露、误删、越权这些事故真发生了,才意识到数据库的安全防线往往就是业务的生命线。YashanDB作为一款国产关系型数据库,这几年的生产落地越来越常见,它在身份认证、权限控制、审计、加密、高可用这些方向上的能力,基本覆盖了企业做数据库加固的绝大部分需求。这篇文章我就结合自己在生产环境里的使用体会,聊聊5个提升YashanDB安全性的关键措施,包括具体怎么配置、哪些参数值得关注、以及踩过哪些坑。适合刚接触YashanDB的DBA,也适合为合规整改做准备的运维和开发同学参考。
1. 认证加固:从入口掐断风险
先说为什么把认证放第一位。外部或内部攻击者无论用什么姿势进入数据库,第一步都要面对“你是谁”这个问题。如果基础认证做得稀烂,后面权限、加密、审计做得再好也白搭。YashanDB的账号体系比较接近主流商业数据库的风格,所以如果你有Oracle背景,上手会很快。
1.1 密码策略别只是口头要求
密码策略是最容易在制度层面写了、但在数据库层面没落地的东西。很多系统上线时创建的账号,密码都是比较简单好记的,改了业务密码也只在业务配置里记一下,并没有真正把密码复杂度、有效期、锁定策略装进数据库里。
YashanDB里可以通过PROFILE来管理密码策略。用CREATE PROFILE创建自定义配置,然后在LIMIT里设置密码有效期、最小长度、登录失败次数、锁定时间等。我把核心参数整理成一组参考:
CREATE PROFILE SEC_PASS LIMIT PASSWORD_LIFE_TIME 90 PASSWORD_MIN_LENGTH 12 FAILED_LOGIN_ATTEMPTS 5 PASSWORD_LOCK_TIME 1;上面这段的含义容易理解:密码最多用90天,至少12位;连续输错5次,账号锁1天。个人建议刚上线时不要一次性把失败次数压得太低,比如设成3次,很容易把运维同事的账号也锁掉,之后解锁的工单烦不死你。
创建好profile之后,可以绑定到用户上。新建用户这么用:
CREATE USER app_rw IDENTIFIED BY 'Str0ng@Passw0rd' PROFILE SEC_PASS;老用户也可以手动换绑:ALTER USER app_ro PROFILE SEC_PASS;
这里提醒一句:密码复杂度只靠长度不一定安全。如果后续版本支持密码复杂度校验函数,建议做成混合大小写、数字和特殊字符的组合;如果不支持,可以把最小长度适当调高,同时靠审计发现弱口令连接行为。
1.2 登录失败处理与账号锁
密码策略里其实有个容易被忽略的点:锁定时间。太短等于没锁,太长又容易被恶意利用来制造账号不可用。比如锁定30天,遇到外部扫描爆破,账号被锁了,业务可能连带着出问题。建议锁1天或者几小时,既保留教训,又不至于让业务长时间中断。
生产环境下,我更建议把DBA账号和高权限账号单独拉一组profile,锁定策略更严格,比如失败3次就锁。同时,DBA账号应该设置独立的密码管理流程,不要让所有DBA共用一套口令。把密码放到团队共享的配置中心里,至少做得到轮换和追溯。
登录失败处理这块还有个小细节:YashanDB默认的登录日志会记录失败IP和时间,排查爆破来源时很有用。建议定期翻一下告警日志里登录失败比较多的源IP,如果在内网环境中出现大量来自非业务网段的失败尝试,基本可以判断是主机层先被攻破了,这时光改密码没用,要先处理主机。
1.3 连接通道也要讲身份
认证不止是账号密码,还有通信层的身份校验。很多DBA习惯用远程口令连接数据库,这在网络环境比较开放时非常危险,因为账号、密码在网络上几乎等于明文传输。YashanDB支持TLS加密连接,建议在客户端和服务端开启SSL/TLS认证。
开启方式大致是:服务端提前生成证书,配置后重启数据库使参数生效;客户端连接串里带上加密协议。实际配置过程不同版本入口可能有差异,但核心思路一致:让数据库禁止非加密连接。如果网络里存在抓包工具,开启前后差异一目了然。抓包看到的密码不再是可读内容,这个体验比看任何安全制度都直观。
这里有个经验:很多团队只给生产库开了TLS,测试库、准生产库仍然用明文。攻击者往往先打容易打的,测试库一旦被拖出数据,生产库的安全也就名存实亡。建议所有环境统一启用,起码做到策略上一致。
2. 权限收敛:最小权限原则的落地
认证过关之后,真正决定风险敞口的是权限。很多安全事件不是外部攻击者拿到了高级权限,而是内部账号被滥用,或者业务账号权限范围过宽。最小权限原则在每个DBA嘴里都能说出来,实际操作中却很难做到位,主要原因是前期没梳理就一股脑授权,后面没人敢动。
2.1 先梳理账号,再谈授权
做权限收敛的第一步是盘点账号。在YashanDB里,可以通过系统视图查询现有用户和角色,比如用户列表、角色权限视图、对象权限视图。把每个账号的用途、归属人、最近登录时间拉成一个清单。
我习惯把账号分成四类:管理类(DBA、备份账号)、业务类(应用读写、应用只读)、开发类(开发联调、发布账号)、第三方类(数据同步、监控采集)。每一类给单独的授权模板,同类账号用同一个角色来管,不直接给用户授权对象权限。
| 账号类型 | 常见角色 | 使用场景 |
|---|---|---|
| 管理类 | DBA、BACKUP_ACCOUNT | 仅限运维使用,不做业务连接 |
| 业务类 | APP_RW / APP_RO | 应用读、写、只读,不授DDL权限 |
| 开发类 | DEV_RO / DEV_RW | 测试库可写,生产库只读或联调窗口授权 |
| 第三方类 | SYNC_MONITOR | 数据同步、监控采集的专用账号 |
清单里还要标出存量账号。我第一次做收敛时,发现一个有3年历史的陈旧账号,居然还有DBA角色,问了一圈没人知道是谁在用,最后直接回收。这种事一点不罕见,账号多的时候,权限泛滥不是故意,而是缺乏治理。
2.2 角色是权限管理的中心化抓手
YashanDB的角色体系比较成熟,角色可以看成一组权限的集合。把权限授权给角色,再把角色授予用户,后续调整时只要改角色,不用把几十个账号逐个改一遍。
举个例子,给业务只读账号建一个角色:
CREATE ROLE APP_RO_SCHEMA1; GRANT SELECT ON SCHEMA1.T_ORDER TO APP_RO_SCHEMA1; GRANT SELECT ON SCHEMA1.T_CUSTOMER TO APP_RO_SCHEMA1;然后把角色给账号:
GRANT APP_RO_SCHEMA1 TO app_ro;这样如果以后希望只读账号也能改某张表的某几列,只需要往角色里追加对象权限,所有挂这个角色的账号同步生效。反之,某个账号下个月要离职,只要从角色里撤销他的成员身份,或者直接锁账号。
用角色的另一个好处是审计时好追溯。权限下放给了谁、经由哪个角色,权限视图里看得清清楚楚。合规整改要提供权限矩阵时,角色结构天然就是一张关系表,比散装授权容易解释得多。
2.3 别忽视PUBLIC和默认权限
权限收敛里最容易被忽略的地方,是PUBLIC账号和默认授权。有些对象默认对PUBLIC开放,等于对所有人开放,这种隐含授权是最容易出隐患的。
建议把对象权限里授予PUBLIC的项拉出来逐项过一遍,把业务上确实需要公开的对象保留,其余全部回收。同理,系统权限里授予PUBLIC的项也要梳理,能不进PUBLIC就不进。
还有一类容易忽视的默认账号:安装数据库时自带的一些示例账号、内置账号。它们可能不具备密码策略,或者密码长期不变。建议查一查现网数据库里有哪些内置用户没被锁定,除了系统进程必需的账号,其余该锁的锁、该改密码的改密码。
实际操作中,权限收敛不能一年才做一次,要形成一个季度性的巡检动作。平时在变更流程里也加一道“授权审批”环节:任何新增授权必须有变更单,领完权限60天没使用,自动触发提醒回收。加这个机制之后,权限规模基本可控。
3. 数据加密:从链路到落盘
权限只能管住“谁能访问数据”,但数据在传输和存储过程中,依然可能被网络抓包或物理介质窃取。加密的价值是把最后一道防线变成数学问题:即使介质丢了,别人也只能拿到一堆密文。这一节聊链路加密、透明数据加密、备份加密三个层级。
3.1 传输加密:让流量不再裸奔
传输加密在第一部分提过,这里展开说说开通路径。内网是不是就绝对安全?我的答案是不见得。内部的测试人员如果具备抓包条件,都能看到流量内容;跨机房链路如果存在错误配置或中间设备,数据一样可能泄露。
在YashanDB里启用传输加密,大致是这几个环节:申请证书、配置数据库参数、客户端证书配置好、测试连接、最后再禁止非加密连接。每一步都要验证。我记得第一次做完之后,用抓包工具看网络载荷,先前能看到账号字符串,开启后变成了加密乱码,那一刻才觉得这套配置没白做。
迁移到加密网络时有个坑:连接参数里多了一个“加密开关”,应用侧连接池如果没同步修改,会导致连不上库。建议先在测试环境把应用连接参数全部刷一遍,再切换数据库侧策略,避免大范围不可用。如果不确定应用端支持情况,也可以先在数据库侧允许加密和非加密并存一段时间,等日志里观察非加密连接比例降到0再收紧。
3.2 透明数据加密:不改造应用的静态保护
透明数据加密(TDE)是很多企业的硬需求。所谓透明,就是应用侧完全无感,数据库自己负责把写入的数据加密、读取时解密。对于存储介质被偷、备份文件被拷走这类场景,这是最直接的缓解手段。
TDE的开启思路一般是:先创建加密密钥和加密表空间或加密列,再把需要保护的数据迁移进加密区域。不同版本支持程度不同,有的是表空间级别,有的是表级别或列级别。建议优先加密最关键的业务表空间,尤其是包含身份信息、财务数据的表。全库加密不是不行,但会有性能和管理复杂度开销,所以先按重要性规划范围。
开启TDE后,要特别注意密钥管理。丢失密钥等于永远失去数据,很多人只关心加密强度,却忽略了密钥备份。保险的密钥管理方式:主密钥至少在两处不同介质存放,密钥轮换周期要固定,密钥访问权限要单独审计。别等一次机房故障之后才发现密钥原先只保存在同一个存储上。
3.3 备份与导出文件的加密
备份文件是数据库安全的另一个黑洞。攻击者可能不直接打数据库,而是去偷备份介质、云存储对象或者DBA导出的数据文件。这些文件一旦落到手里,绕过数据库账号体系直接解析数据非常容易,前提是没加密。
YashanDB的备份能力里,建议把备份加密参数打开,同时为备份集单独设置密文口令。导出工具导出数据时也设置文件加密。运维脚本里尤其要注意:我见过不少导出后的临时文件以明文放在服务器临时目录,权限还很宽,这跟把数据贴到公网上没啥区别。
备份加密之后,恢复流程一定要演练一遍,包括:密钥还在不在、口令能不能对上、恢复后的数据能否被业务正常读取。如果不演练,遇到真正灾难时,备份加密反而可能变成数据不可用的元凶。备份加密的目的不是给恢复添堵,而是保证数据传输和存储过程中的机密性,两者要平衡。
4. 审计与审计数据治理
安全里有一句话:不知道发生过什么,就无法谈安全感。审计的价值在于事后可溯源。当发生越权查询、异常导出、删库这类事件时,没有审计日志,DBA只能靠猜。YashanDB提供了审计能力,实操中要解决三个层面:审计开没开、审计策略合不合理、审计日志有没有人看。
4.1 怎么开审计才是有效的
先确认审计参数是否打开。刚装好的数据库,审计默认未必是全量开启的。打开审计的命令,每个版本有所差异,但核心动作是把审计开关从NONE改成DB或OS级别。建议至少保留数据库内的审计记录,同时定期归档到独立存储上。
ALTER SYSTEM SET audit_trail = DB, EXTENDED SCOPE=SPFILE; -- 重启数据库后生效 SHOW PARAMETER audit_trail;扩展模式下审计日志会记录更详细的SQL绑定变量信息,这对事后排查非常关键。如果只记录“用户执行了一条SQL”,但看不到具体参数,排查时还是要靠应用日志,效率很低。扩展模式更符合安全审计的诉求。
不过审计日志本身会带来磁盘和性能开销,不要无差别地开全量审计。我的做法是先评估业务负载,再决定审计哪些用户和对象。高并发场景下,全量审计可能导致日志写入成为瓶颈,所以要分策略、分场景开。
4.2 审计策略怎么做场景化
场景化意味着不是“全部审”,而是按照风险大小设置策略。我常用的场景包括:
- 管理员行为:所有DBA权限账号执行的DDL、授权、用户管理操作全部审计。
- 敏感对象:涉及客户身份、财务信息的表的查询和修改操作开启审计。
- 异常行为:批量导出、大结果集查询、非工作时间访问重点审计。
- 登录行为:所有登录成功和失败记录都要审,失败次数单独盯。
下面这段是给业务账号加上对敏感表的访问审计:
AUDIT SELECT, UPDATE ON SCHEMA1.T_CUSTOMER BY app_rw; AUDIT SESSION BY app_rw;通过命令开启的审计策略,可以通过审计视图查看。这里建议把敏感对象清单放在变更单的固定字段里,每次新建表时顺手评估是否要加审计,而不是等事件发生后补记录。
4.3 审计日志别只存不读不防
开了审计不等于安全。日志如果只存不看,顶多算心理安慰。我见过不少团队,安全自查前临时查审计,结果日志表里几千页没人读过,关键时间段的记录被后来的日志覆盖。这提醒我们需要一套审计日志治理机制。
第一是保留周期。审计日志要有明确的保留时间和归档机制,比如在线保留30天,归档保留180天以上。归档最好推送到独立的日志平台,并做文件完整性校验。第二是定期巡检。每周抽一点时间看高强度登录失败、半夜的DDL操作、特权账号行为这三个指标,形成周报。第三是告警联动。把审计中比较敏感的事件类型接入工单系统,比如发现某账号第一次在凌晨3点执行了一次授权操作,系统应该能提醒到负责人。
审计日志也是合规检查的重要证据。做过等保的朋友都知道,检查项里大量内容是“有没有记录、能不能溯源、记录是否防篡改”。把这些机制提前建立好,整改成本会低很多。
5. 高可用与容灾:安全兜底的底线
如果前面的措施都被绕过,数据库还能不能扛住?这就是高可用与容灾的课题。安全不只有防入侵,还包括防丢失、防故障。数据一旦因为硬盘故障、误操作或机房级灾难丢失,再完美的权限和加密都无济于事。YashanDB提供了主备复制和备份恢复能力,关键是把这些能力真正用起来,而不是装完就完。
5.1 主备复制与故障切换
主备复制是高可用最常见的方案。一主一备或者一主多备,主库承担读写流量,备库通过日志同步保持数据一致。主库出问题时,可以切换到备库继续服务。
实际部署中,我建议至少做到:主备节点放在不同机柜或不同可用区,避免单点物理故障。同步方式的选择要结合业务容忍度,同步模式能尽量保证数据不丢,但对网络延迟敏感;异步模式性能更好,但极端情况下可能丢少量日志。两者没有绝对好坏,要根据业务的实际RPO要求来选,不能一刀切。
切换演练很重要。很多团队只在初始化时做过一次切换,之后再没测过。等真出问题时才发现备库日志断档、复制主备逻辑有问题、应用连接串没指向新主库。建议每季度做一次故障演练,把切换时间、数据偏差量记录下来,形成指标再持续改进。
5.2 备份恢复的演练才是真备份
备份本身不难,难的是恢复。在YashanDB里,可以用备份命令进行全量和增量备份。备份策略通常考虑:全量一周一次、增量一天一次,保留周期按恢复目标来定。一套基本策略可以这样排:
- 全量备:每周日02:00
- 增量备:周一至周六02:00
- 归档日志:每30分钟一次
- 备份集保留:至少14天或按合规周期
# 以定时任务方式执行的备份命令示例 0 2 * * 0 yasql / as SYSDBA -c "BACKUP DATABASE FORMAT '/backup/yashan/full_%T'"上面只是展示了思路,实际生产环境要配合备份脚本做压缩、命名、清理和日志检查。恢复演练不止要验证备份文件能用,还要验证恢复到某个时间点后,应用账号权限、表结构、业务数据是否一致。最理想的演练是选一个不重要的业务,从备份库里拉出一个完整实例,让测试团队跑一遍核心链路。
5.3 RPO/RTO指标怎么定更实际
RPO(恢复点目标)和RTO(恢复时间目标)是容灾设计里的两个关键指标。很多项目把RPO定为0,RTO定为几分钟,口号喊得很响,落地时却发现自己根本没有这样的网络条件和运维能力。
我建议指标定得现实一点:先看业务能接受丢多少数据、能停多久,再看现有主备模式和备份节奏能否支撑。比如核心交易系统可以定RPO小于等于5分钟,RTO小于等于30分钟,业务方认可后再倒推备份和复制配置。先有现实指标,后面发生灾难时就有明确的恢复预案。别把指标定成文档里的漂亮数字,关键时刻发现做不到,损失远比坦白更严重。
这个环节还有一个容易被忽略的安全点:备份介质本身也要纳入权限管理。备份存放目录如果任何运维人员都能随便拷贝,前面做的数据加密就白费了。建议备份目录做单独权限和控制,账密信息不要直接写在定时任务脚本里,可以配置成专用备份账号并从凭据管理系统中读取。
最后分享一点实操心得
数据库安全不是装个软件、跑个脚本就完成了,它是一个需要持续维护的工程。我个人在做YashanDB安全加固时,最深的体会是:每做一次整改,都要顺手更新对应的文档和巡检脚本,否则三个月后回看,很多参数为什么这么设、谁改过,又变成一笔糊涂账。刚开始觉得这些记录工作很琐碎,后来发现它才是安全体系里最有复利的一部分。大家可以把上面的五个措施拆成季度巡检清单,每季度花半天逐项过一遍,比憋大招式的一次性整改要有效得多。