首页 / 资讯中心 / 文章详情

SQL Server数据库加固规范实战:账号权限、日志审计与协议加密

SQL Server数据库加固规范实战:账号权限、日志审计与协议加密 ★ FEATURED ARTICLE
简介面向数据库运维、安全管理人员及需要满足合规要求的政企IT团队这份Sql Server数据库系统加固规范文档提供了一套可落地的安全配置基线。内容围绕账号管理、认证授权、日志配置、通信协议、设备安全等核心模块展开细化到具体核查项与操作指引涵盖最小权限分配、密码不少于12位且90天更新、登录失败锁定、双因素认证、SSL/TLS加密通信、防火墙与入侵检测、防病毒安装和定期安全更新等要求能够直接对照企业内网环境逐项整改也可作为等保测评、安全自查和加固方案编制的依据。资源包包含1个doc文件压缩包大小1.73MB文档目录清晰、条目编号规范便于翻阅和内部培训复用。目前已有245人学习下载适合正在完善数据库安全基线、梳理加固清单或编写运维文档的读者快速参考。1. SQL Server加固规范一份能落地的检查清单而不是文档库里的摆设在数据库安全这件事上很多人是被等保测评或安全扫描逼到墙角的。真正把 SQL Server 加固规范读进去的人会明白它不是一堆抽象的应开启应配置而是一份带编号、带实施命令、带回退方案的作业指导书。这套规范来自某运营商管理信息系统部 2022 年 3 月发布的 MSSQL 加固规范覆盖账号管理、日志配置、通信协议、设备安全四个维度所有检查项统一编号为 SHG-Mssql-xx-xx-xx每一条都标了实施风险、重要等级和回退方案。适合接手存量数据库、要做安全合规整改的 DBA 和运维人员照着逐条执行能避开大多数低级风险也适合作为内审基线文档留存。2. 账号管理与认证授权六个检查项背后的权限收敛逻辑账号管理是这套规范里条目最多、最容易被照着删一删的部分。六个编号从 SHG-Mssql-01-01-01 到 01-06覆盖了账号分配、无效账号清理、服务账号权限、最小权限原则、数据库角色和强口令。拆完这六条你会发现它其实在讲一件事把每个账号的权限边界画清楚把共享和默认的隐患全部消掉。2.1 先盘点账号全景从 syslogins 到 server_principals规范第一条 SHG-Mssql-01-01-01 要求为不同管理员分配不同账号避免共享账号。实施前先列出现有登录名规范原文用的命令是USE master; SELECT name, password FROM syslogins ORDER BY name;这段命令在 SQL Server 2000 里能直接看到 password 字段但在 2005 以后的版本里syslogins 视图的 password 列默认返回乱码或 NULL直接抄规范命令会得到一张基本没有参考价值的清单。常见做法是换成 2005 的系统视图SELECT principal_id, name, type_desc, is_disabled FROM sys.server_principals WHERE type IN (S, U) ORDER BY name;type 为 S 的是 SQL 登录名type 为 U 的是 Windows 登录名is_disabled 标记是否被禁用。参数说明这条查询能看到所有实例级主体但看不到每个账号在哪些库里有权限想看库级权限要再 join sys.database_principals。规范原文建议用 sp_addlogin 创建账号那是 2000 时代的存储过程2005 之后推荐用 CREATE LOGINCREATE LOGIN user_name_1 WITH PASSWORD password1, CHECK_POLICY ON; CREATE LOGIN user_name_2 WITH PASSWORD password2, CHECK_POLICY ON;CHECK_POLICY ON 是这条命令的关键参数它让新密码必须满足 Windows 密码策略的长度、复杂度和过期要求而不是像旧语法那样只检查非空。2.2 无效账号与启动账号的清理边界规范 SHG-Mssql-01-01-02 要求删除或锁定无效账号原文操作路径是企业管理器 - SQL Server 组 - 登录 - 右键删除并给出了判断依据询问管理员哪些账号是无效账号。这句话看着像废话其实是提醒你不要看哪个登录名不顺眼就删。我在实际拆解时遇到过两次翻车都是把 SQL Server 服务的启动账号当成冗余账号给删了结果服务直接起不来。删除前先做交叉核对确认这个登录名不是服务账号也不是某个作业的所有者SELECT servicename, service_account FROM sys.dm_server_services;这条命令能列出 SQL Server 相关 Windows 服务当前使用的登录账户。回退方案在规范里写得极简增加删除的帐户但在生产环境想恢复一个被删的 SQL 登录名最稳妥的办法是提前记录它的 sid 和密码哈希。2005 可以用 sys.sql_logins 查到这两样SELECT name, sid, password_hash FROM sys.sql_logins WHERE name 待删除账号;有了 sid恢复时可以用 CREATE LOGIN ... WITH SID ... 把账号原样加回来权限映射不会乱。这个动作是规范原文没有展开的但遇到一次作业归属漂移你就懂了。2.3 限制启动账号权限三个边界一个红线规范 SHG-Mssql-01-01-03 是限制 SQL Server 服务启动账号的权限原文建议新建服务账号后将其从 User 组中删除且不提升为 Administrators 组成员只授予启动 SQL Server 所需的最少权限。这里有个容易误解的点从 User 组删除不是说账号不能登录系统而是让它不具备交互式登录和普通用户权限只保留作为服务登录这一项能力。现代 Windows Server 环境下最常用来替代的方案是使用虚拟账号或托管服务账号 gMSA密码由域控制器自动轮换运维人员不需要手动改服务密码。红线只有一条不要图省事把 SQL Server 服务改成 LocalSystem 或本地管理员组成员。子进程的权限继承是实打实的一旦数据库被注入或提权攻击者拿到的直接是系统级权限日志审计在这些场景里已经没有意义。2.4 最小权限与数据库角色用角色兜住权限而不是直接撒给账号规范 SHG-Mssql-01-01-04 和 01-05 连着看最有价值先是取消业务账号不需要的服务器角色和数据库角色再是引入统一角色来管理对象权限。原文给的权限范围是 SELECT、INSERT、UPDATE、DELETE、EXEC、DRI 六种其中 DRI 是 REFERENCES 权限很多初学者会漏掉但业务表之间有外键约束时缺了它表结构变更会报权限不足。常见做法是先在业务库里建角色再把对象权限授给角色最后把账号加入角色USE [business_db]; CREATE ROLE rw_role; GRANT SELECT, INSERT, UPDATE, DELETE ON dbo.orders TO rw_role; GRANT EXEC ON dbo.sp_order_sync TO rw_role; ALTER ROLE rw_role ADD MEMBER app_user;参数说明rw_role 是自定义角色名建议按业务模块命名便于审计GRANT EXEC 只给存储过程执行权不要顺手给 ALTER 或 CONTROLALTER ROLE ... ADD MEMBER 在 SQL Server 2012 有效2000 环境对应的是 sp_addrolemember。判断依据规范写的是业务测试正常实际操作时要注意权限只从角色来账号本身不持有任何直接对象权限否则换人维护时权限追溯就是一场灾难。2.5 空密码与 sa 强口令最直观也最容易被跳过规范 SHG-Mssql-01-01-06 原文的命令非常有时代感USE master; SELECT name, password FROM syslogins WHERE password IS NULL ORDER BY name; EXEC sp_password 旧口令, 新口令, 用户名;syslogins 表里 password 列为 NULL 表示空密码这在 SQL Server 2000 和兼容模式下有效2005 以后强制密码策略新登录名已经无法设置空密码但历史升级库里可能仍残留旧账号。现代版本里对应做法是靠 CHECK_POLICY 兜底修改口令用 ALTER LOGINALTER LOGIN sa WITH PASSWORD 新强口令, CHECK_POLICY ON;关于强口令的强度规范正文只给了sa 至少 10 位的下限我一般按更严格的标准执行长度不少于 12 位包含大写、小写、数字、特殊字符四类中的三类90 天强制更换登录失败超过 5 次锁定账号。注意一点sa 账号在 2005 默认是禁用的如果合规检查要求启用 sa改完密码后要确认它没有被加入任何 SQL Agent 作业或维护计划的登录链中否则密码轮换会连带影响一批自动化任务。3. 日志与审计把审计级别调到全部之前先想清楚三件事日志配置在规范里只有一条编号 SHG-Mssql-02-01-01要求把审计级别调整为全部身份验证调整为SQL Server 和 Windows。命令本身简单到一句话但全量审计对生产库的影响远不止翻一个下拉框拆完这条规范我更确定先想清楚三件事再动手。3.1 审计级别全部到底记录了哪些内容打开数据库属性选择安全性把审计级别改为全部后SQL Server 会把所有登录事件写入错误日志和 Windows 事件日志包括登录账号、登录成功或失败、登录时间、远程登录 IP。这里有个容易被忽略的点规范原文写的是数据库属性但登录审计实际是实例级配置在 SQL Server 2000 里对应服务器属性 - 安全性2014 以后的路径是服务器属性 - 安全性 - 登录审核改错层级会出现明明改了审计级别日志里还是只有失败登录的情况。2008 的版本可以用 server audit 把登录审计独立落盘不污染错误日志USE master; GO CREATE SERVER AUDIT audit_login TO FILE (FILEPATH D:\sqlaudit\); GO CREATE SERVER AUDIT SPECIFICATION audit_login_spec FOR SERVER AUDIT audit_login ADD (SUCCESSFUL_LOGIN_GROUP, FAILED_LOGIN_GROUP) WITH (STATE ON);FILEPATH 指定的目录要提前建好且 SQL Server 服务账号要有写入权限否则审计启动时报错。SUCCESSFUL_LOGIN_GROUP 和 FAILED_LOGIN_GROUP 分别对应成功和失败登录事件审计落盘文件默认是 .sqlaudit 格式后续用 sys.fn_get_audit_file 读取。3.2 日志保留与磁盘空间的账本开启全量审计后最先暴露的问题不是安全性而是磁盘。假设每秒有 20 次登录尝试一条审计记录几十到一百多字节一小时就是数 MB暴力破解扫上几天C 盘或审计盘很快告警。SQL Server 错误日志采用循环覆盖机制2000 时代需要手动执行 DBCC ERRORLOG 轮换现代版本可以配置最多保留文件数。Windows 事件日志侧的容量策略也要同步检查否则事件日志满了之后审计记录会直接丢失。常见做法是加一条每日轮换任务EXEC sp_cycle_errorlog;这条命令主动把当前错误日志切换成历史文件并新建一个建议放进维护计划的每日任务里。配套一个磁盘空间监控脚本低于阈值就告警防止日志把盘写满导致数据库自动关闭或审计失效。3.3 登录审计的补位LOGON 触发器记录客户端 IP审计级别全部能记录登录时间和是否成功但错误日志里查 IP 要翻半天2000 时代的日志字段还不全。2005 可以用 LOGON 触发器把登录事件实时写进独立审计表USE msdb; GO CREATE TABLE dbo.login_audit ( login_name nvarchar(128), login_time datetime, client_ip varchar(32) ); GO CREATE TRIGGER trg_logon_audit ON ALL SERVER FOR LOGON AS BEGIN INSERT INTO msdb.dbo.login_audit(login_name, login_time, client_ip) SELECT ORIGINAL_LOGIN(), GETDATE(), CONNECTIONPROPERTY(client_net_address); END;触发器要建在 msdb 这类独立数据库不要放业务库否则业务库恢复时登录审计跟着失效。最关键的坑是LOGON 触发器如果在执行时报错登录会被直接拒绝相当于给自己挖了一个拒绝服务的坑。生产环境上这种触发器必须用 BEGIN TRY / BEGIN CATCH 包住写库逻辑并保证 msdb 的写入权限始终正常。4. 通信协议加固裁剪协议、注册表三键值与强制加密规范 SHG-Mssql-03 系列包含三条网络协议只保留 TCP/IP加固 TCP/IP 协议栈的注册表参数以及强制协议加密。这三条从减少暴露面到内核加固再到传输加密层层递进。拆完这一章的结论是通信协议加固是整套规范里技术含量最高、实施顺序最容易搞反的部分。4.1 服务网络实用工具只保留 TCP/IP其余协议全部禁用规范原文的路径是在 Microsoft SQL Server 程序组运行服务网络实用工具建议只使用 TCP/IP禁用其他协议。SQL Server 2000 时代默认监听协议包括 TCP/IP、Named Pipes命名管道和 VIA命名管道走 139/445 端口与 SMB 服务混在一起容易被跨协议传播的工具横向移动。2008 的操作位置在SQL Server 配置管理器 - SQL Server 网络配置 - MSSQLSERVER 的协议禁用 Named Pipes 和 VIA保留 TCP/IPShared Memory 协议看情况远程应用为主的实例可以直接禁用但本机用 SSMS 连接的 DBA 会发现连不上或变慢体验上像卡了一下。操作完确认监听端口用系统命令核对netstat -ano | findstr :1433输出里会显示监听进程 PID到服务列表里核对这个 PID 对应的是 sqlservr.exe 而不是其他程序。如果实例监听非默认端口 1433业务侧连接串和防火墙入站规则要同步调整这一点是协议裁剪中最常见的翻车点。4.2 TCP/IP 协议栈加固三个注册表键值的真实含义规范 SHG-Mssql-03-01-02 给的是操作系统层 TCP/IP 栈加固和 SQL Server 版本没有直接关系键值位置都在 HKLM\System\CurrentControlSet\Services\Tcpip\Parameters 下。建议直接核对键值再决定是否修改reg query HKLM\System\CurrentControlSet\Services\Tcpip\Parameters /v DisableIPSourceRouting reg query HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters /v EnableICMPRedirect reg query HKLM\System\CurrentControlSet\Services\Tcpip\Parameters /v SynAttackProtect三个键值的含义和调整目标分别是键值建议值作用DisableIPSourceRouting2完全禁止 IP 源路由防御源路由欺骗攻击EnableICMPRedirect0禁用 ICMP 重定向防止伪造报文篡改路由表SynAttackProtect2开启 SYN 攻击保护配合半开连接阈值参数生效补充说明SynAttackProtect 在现代 Windows Server 版本中已经由系统内置的动态 SYN 防御机制部分替代写进去不报错但不代表它在每代系统上都有同等的防御效果查这个键更多是为了满足基线合规核查点。改完注册表后需要重启系统或至少重启网卡才会完全生效这也是改完没效果的最常见原因——不是键值写错了是没触发重读。4.3 强制协议加密证书、TLS 与客户端连接串规范 SHG-Mssql-03-01-04 要求把服务器网络配置工具的常规设置为强制协议加密。2000 时代这个开关在服务端勾选后所有客户端连接必须走加密通道。现代版本对应的是配置管理器 - SQL Server 网络配置 - MSSQLSERVER 协议 - 标志 - ForceEncryption设为是。这里最核心的坑是SQL Server 默认使用自签名证书客户端不信任这台服务器的证书加密链路根本建立不起来。正确顺序是先给服务器申请一张证书CN 与机器名一致再开启强制加密最后用客户端验证SELECT session_id, encrypt_option, client_net_address FROM sys.dm_exec_connections;encrypt_option 为 TRUE 表示该连接已加密。如果强制加密开了之后出现证书链验证失败或SSL Provider 接收数据时出错基本可以断定是客户端驱动版本太老或服务器证书不在客户端信任列表里。测试环境可以先让客户端连接串加 TrustServerCertificatetrue 验证链路生产环境必须换正式证书或统一升级驱动。5. 加固实施避坑实录五条让数据库直接翻车的操作设备其他安全要求这一块规范给了两条停用不必要的存储过程SHG-Mssql-04-01-01和安装补丁SHG-Mssql-04-01-02。补丁管理那条的原始操作是 select version并附带了一份 SQL Server 2000 的版本对照表版本号补丁版本8.00.194SQL Server 2000 RTM8.00.384SQL Server 2000 SP18.00.534SQL Server 2000 SP28.00.760SQL Server 2000 SP38.00.2039SQL Server 2000 SP4提醒一句现代 SQL Server 的补丁核对不能只看大版本号还要对照官方月度累计更新说明。下面重点讲危险存储过程停用过程中最容易出问题的五个操作全部按现象 - 原因 - 解决来拆。5.1 删了 xp_cmdshell作业和调度脚本批量报警现象按照规范删掉 xp_cmdshell 等扩展存储过程后第二天凌晨 SQL Agent 作业和 DTS 包批量失败报未能找到存储过程。原因存量系统里经常有调度脚本通过 xp_cmdshell 调用外部程序或写文件删除扩展存储过程后这些依赖全部断裂。规范列了一长串建议删除的存储过程但没提先查依赖这一步。解决删除前先全库查依赖SELECT DISTINCT o.name FROM syscomments c JOIN sysobjects o ON c.id o.id WHERE c.text LIKE %xp_cmdshell%;2005 的环境改用 sys.sql_modules 查。确认没有依赖后再执行删除。SQL Server 2005 以后更推荐的做法不是删除而是禁用回退成本完全不同EXEC sp_configure show advanced options, 1; RECONFIGURE; EXEC sp_configure xp_cmdshell, 0; RECONFIGURE;sp_configure 方式可以随时改回来而 sp_dropextendedproc 删除后需要手工重建代价大了不止一个量级。5.2 注册表键值改完安全扫描报告原封不动现象三个 TCP/IP 注册表键值都改成了规范要求的值扫描报告显示这些检查项仍然不通过。原因注册表键值改完后没有重启系统或者系统版本较新SynAttackProtect 键值在这个版本上已不再承担原有职能。解决重启系统后再跑扫描扫描前用 reg query 逐项核对键值状态以重启后行为为准。不要拿刚改完未刷新的数值当整改依据这类问题在攻防中都属于看着改了实际没生效的黑匣子。5.3 删除无效账号SQL Server 服务起不来现象按 SHG-Mssql-01-01-02 清理无效账号后实例服务启动失败事件日志提示找不到服务账号。原因被删的账号恰恰是 SQL Server 服务登录账户而不是业务账号。解决动手前在服务管理器里确认服务的登录身份并配合 sys.dm_server_services 交叉核对。如果账号已经删了最快的临时恢复是把服务登录身份改成 LocalSystem 或 NetworkService但长期方案还是要重建专用服务账号并恢复服务属性。5.4 开启强制协议加密一批客户端连接全部失败现象ForceEncryption 开启后多台客户端的连接抛SSL Provider, error: 0或证书信任错误应用连不上库。原因客户端驱动太老只支持老版本 TLS而服务器系统已默认关闭这些协议或服务器端自签名证书不在客户端信任列表。解决分批切换而不是集群一把梭。先用最新驱动在测试环境验证加密链路再让核心应用先切外围应用逐步切全部稳定后保持强制加密。回退动作就是临时关闭 ForceEncryption但由此带来的安全窗口要在下一个维护窗口内补上。5.5 sa 改完强口令业务系统连环报登录失败现象把 sa 密码改成强口令后多个业务系统在凌晨连接池刷新时集中报警登录失败。原因应用连接串里写死 sa 和旧口令密码变更后连接池里的旧连接全部失效应用没有自动重连机制。解决把 sa 当成应急通道而不是应用通道。改密码前先看谁在用 sa 连接SELECT s.login_name, c.client_net_address, s.program_name FROM sys.dm_exec_sessions s JOIN sys.dm_exec_connections c ON s.session_id c.session_id WHERE s.login_name sa;确认没有业务依赖后再改。如果应用无法联动修改宁可不改 sa先通过防火墙放行来源和账号权限收窄来降低风险等应用改造完成后再轮换密码。6. 加固验收与回退一张自检表一份后悔药整套规范拆完最值得拿走的其实是一个可执行的验收路径以及每一条都配套的回退动作。这里整理一份能直接打印的自检表把 SHG 编号变成生产环境可核对的硬性指标。6.1 逐项自检把 SHG 编号变成可核对的运行指标检查项验证命令 / 路径期望结果账号唯一性SELECT name FROM sys.server_principals WHERE type S每个管理员独立登录名无共享账号空密码SELECT name FROM sys.sql_logins WHERE password_hash IS NULL无记录sa 强口令ALTER LOGIN sa WITH PASSWORD ..., CHECK_POLICY ON已生效sa 保持禁用审计级别服务器属性 - 安全性 - 登录审核成功与失败登录均记录协议裁剪配置管理器 - 协议仅 TCP/IP 启用TCP/IP 栈加固reg query 三个键值分别为 2 / 0 / 2强制加密SELECT encrypt_option FROM sys.dm_exec_connectionsTRUE危险存储过程SELECT name FROM sysobjects WHERE name LIKE xp[_]cmdshell不存在或已禁用补丁版本SELECT VERSION高于已知漏洞修复版本6.2 回退方案才是这份规范最值钱的部分这套规范每个编号都带回退方案字段例如账号删除对应增加删除的帐户注册表修改对应还原更改键值。拆过的加固文档里能把回退写进正文的是少数。我的执行习惯是为每个检查项保留三样东西变更前基线导出文件、变更脚本原文、一行能完成的回退命令。操作顺序固定为先备份 master 和 msdb再逐条实施每条完成后跑一次业务连通性测试记录耗时和影响范围。6.3 一次失败的加固让我养成的习惯几年前做某库存系统的 SQL Server 加固我先改了 sa 密码结果跑批脚本半夜连接失败业务中断了两个小时。原因就是连接串里写死了旧口令我改密码时没有先查 sys.dm_exec_sessions也没有做回退演练。从那以后我每次做数据库加固都强制走一遍先记录当前状态再逐条实施每条做完验证业务把回退命令单独存成一个文件任何意外都能在两分钟内还原。这份规范的价值不只是罗列了多少检查项而是它把每条操作的风险等级和回退路径都标了出来哪怕命令还停留在 SQL Server 2000 时代思路放到 2016、2019、2022 上依然成立。希望帮到你。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?
咨询建站