SQL Server数据库加固全攻略:从账号权限到协议加密
简介这份Sql Server数据库系统加固规范文档源自中国移动管理信息系统部面向数据库管理员、系统运维与安全合规人员针对数据库日常运维中常见的账号共享、弱口令、权限越界、日志缺失、明文传输等安全隐患提供了一套可落地的安全加固基线。资源为doc格式压缩包内含1个文档体积约1.73MB内容按账号管理认证授权、日志配置、通信协议、设备其他安全要求等章节组织结构清晰便于按条目对照检视。已有245人学习下载适合需要提升生产环境数据库安全等级、应对内外部安全检查或准备加固整改方案的读者参考。文档中每项规范均包含编号、实施目的、问题影响、当前状态查询语句、具体配置操作及回退方案例如密码长度不少于12字符且有效期不超过90天、登录失败次数限制在5次以内、启用双因素认证、使用SSL/TLS加密通信等可直接作为SQL Server安全加固的对照清单与操作手册使用。1. 数据库加固不是跑一遍脚本就完事Mssql 加固规范能救什么火做数据库运维的人大概率都遇到过这类尴尬业务账号有 sysadmin 权限、sa 密码还是 10 年前设的弱口令、xp_cmdshell 敞开着等被扫出高危漏洞才回头补课。Sql Server 数据库系统加固规范这份材料本质是一份把账号管理、认证授权、日志配置、通信协议、设备安全要求拆成可执行条目的安全配置基线编号从 SHG-Mssql-01-01-01 到 SHG-Mssql-04-01-02每个条目都带实施目的、系统当前状态查询语句、具体操作步骤、回退方案和风险等级。适合两类人一是刚接手数据库安全整改、不知道从哪下手的运维照着条目逐条过就能交差二是要做等保或内部合规检查的 DBA拿它当基线清单对照现状省去自己梳理检查项的功夫。说白了这份规范的价值不在于原理多深而在于把「安全要求」翻译成了「可执行的 SQL 和配置路径」照着做就能把 SQL Server 的暴露面收住一大半。2. 账号管理与认证授权把权限和口令理清先过这六关账号管理是 SQL Server 加固里最琐碎但也最见效的部分。那份规范文件里这一章占了六个条目从分账号、清无效账号、限启动权限到最小权限、数据库角色、空密码检查基本覆盖了生产环境最常见的账号乱象。下面按执行顺序逐个拆解每个都给出可直接落地的语句和操作路径。2.1 不同管理员分配不同账号别让所有人共用一个 sa规范条目 SHG-Mssql-01-01-01 的要求很朴素为不同的管理员分配不同的账号避免共享账号导致权限分不清、出事了没法追溯。现实中很多团队偷懒几个人共用一个 sa 或者一个高权限账号平时看似省事等出问题查审计日志时根本分不清是哪个人干的背锅都找不到人。先看当前系统有哪些登录账号用这条语句USE master SELECT name, password FROM syslogins ORDER BY name说明syslogins 是 master 库里的系统视图保存了服务器级别的登录账号信息。password 字段在 SQL Server 2000 里还能看到哈希值2005 以后这个字段就返回 NULL 了但查询语句本身不会报错主要用它看账号列表和排序情况。如果是在 2005 以上的版本想查登录账号建议改用SELECT name FROM syslogins WHERE islogin 1或者查 sys.server_principals。 创建新账号给不同的管理员分别使用-- 创建两个独立的登录账号密码务必用强口令 sp_addlogin user_name_1, password1 sp_addlogin user_name_2, password2参数说明user_name_1 和 user_name_2 是两个不同的账号名称按实际管理员的名字或工号来取不要叫 admin01、admin02 这种没区分度的名字。password1、password2 只是占位符实际设置时至少要满足大写字母、小写字母、数字、特殊字符四类中三类以上长度不低于 10 位。创建完账号只是第一步第二步行权分配。规范里的做法是先建立角色并授权再把角色赋给用户。这样后续有新管理员入职只要把他加进对应角色就能获得既定权限离职时从角色里移除即可不用逐条改权限-- 在目标数据库里创建角色 USE your_db EXEC sp_addrole db_operator_role -- 给角色授予需要的权限 GRANT SELECT, INSERT, UPDATE, DELETE ON dbo.orders TO db_operator_role -- 把登录账号映射到数据库用户并加入角色 USE your_db EXEC sp_grantdbaccess user_name_1, user_name_1 EXEC sp_addrolemember db_operator_role, user_name_1逻辑说明先把业务库里的对象权限集中授予角色再把人加入角色。这样做权限的增删都集中在角色上账号本身只是个「身份标识」不会出现某个人的账号权限越滚越大、最后谁也说不清他有多少权限的情况。2.2 删除或锁定无效账号减少默认入口规范条目 SHG-Mssql-01-01-02 要求删除或锁定无效账号。所谓无效账号包括离职员工的账号、长期不用的测试账号、以及安装 SQL Server 时自动创建但从未使用过的默认账号。留着这些账号等于给攻击者多留了几扇不知道什么时候会打开的门。查看当前登录账号方法和 2.1 一样用 syslogins 查列表然后逐个找管理员确认哪些已经没人用了。确认后按下面方式删除-- 删除登录账号SQL Server 2005 DROP LOGIN [test_user] GO -- SQL Server 2000 方式 EXEC sp_droplogin test_user补充说明如果账号在数据库里还映射了用户直接删登录账号会报错提示「The database principal owns a schema in the database, cannot be dropped」。这时候需要先删掉或转移该账号在业务库里的用户映射再回来删登录。规范里的「回退方案」是增加删除的账户也就是删除前最好把账号名字和权限记录下来万一误删了还能加回来。判断依据很简单询问管理员哪些账号是无效账号确认后再动手。风险等级标的是高因为删账号是不可逆操作删完就找不回来了。2.3 限制 SQL Server 服务启动账号的权限这一条SHG-Mssql-01-01-03容易被忽略但它属于典型的「隐形风险」。SQL Server 服务本身跑在一个 Windows 账号下如果这个账号是 Administrators 组成员或者拥有本机过高的权限那 SQL Server 的每一个子进程、每一个扩展存储过程调用都继承了这份权限。一旦 SQL Server 被注入或攻破攻击者拿到的就是高权限令牌而不是单纯的数据库权限。规范给的思路是新建一个专门的 SQL Server 服务账号不要把它加入 User 组更不能加入 Administrators 组。具体在 Windows 上操作路径是「服务管理器 → SQL Server (MSSQLSERVER) → 属性 → 登录」把「此账户」改为专门创建的域账号或本地账号。之后授予这个账号以下最小权限作为操作系统的一部分SeTcbPrivilege——SQL Server 启动时需要调整进程的内存配额SeIncreaseQuotaPrivilege替换进程级别令牌SeAssignPrimaryTokenPrivilege以服务方式登录SeServiceLogonRight——服务账号的基本要求对 SQL Server 数据目录、备份目录、错误日志目录有完全控制权但只限于这些目录不能扩大到整个磁盘或系统目录注意如果用本地系统账号Local System跑 SQL Server权限是最大的方便但风险也最大。规范建议的做法是单独建账号并刻意压低权限。回退方案是替换回原来的启动账号改完之后记得重启 SQL Server 服务才会生效。2.4 权限最小化取消业务账号用不上的服务器角色规范条目 SHG-Mssql-01-01-04 强调权限最小化。生产中常见的翻车现场是开发为了省事直接把自己的账号加进 sysadmin 固定服务器角色时间一长就没有人再去收敛整个数据库等于对开发完全透明。先查当前哪些账号拥有过高的服务器角色权限-- 查看所有登录账号及其服务器角色 SELECT s.name AS login_name, r.name AS server_role FROM sys.server_principals s LEFT JOIN sys.server_role_members m ON s.principal_id m.member_principal_id LEFT JOIN sys.server_principals r ON m.role_principal_id r.principal_id WHERE s.type IN (U, S, G) ORDER BY s.name这条语句把每个登录账号对应的服务器角色列出来重点看哪些业务账号挂了 sysadmin、securityadmin、serveradmin 这类高风险角色。逻辑说明sys.server_role_members 是服务器角色成员关系的系统视图把它和 sys.server_principals 做两次关联一次拿账号信息一次拿角色名字。type 字段里 U 是 Windows 登录、S 是 SQL 登录、G 是 Windows 组。查出来之后通过数据库属性界面操作右键点击实例 → 属性 → 安全性 → 点击对应登录名 → 服务器角色页把不需要的角色勾选去掉只保留 public所有登录默认都有的基础角色。然后还要检查数据库级别的权限右键点击业务数据库 → 属性 → 权限 → 查看该账号的「数据库访问许可」和「数据库角色中允许」两个区域把用不到的数据库访问权限和数据库角色取消。回退方案是还原添加或删除的权限所以操作之前建议把账号原有的角色权限截个图存到变更记录里。判断依据是业务测试正常也就是说权限改完要让业务方做一轮冒烟测试确认没改坏。2.5 用数据库角色管权限别直接给用户授权规范条目 SHG-Mssql-01-01-05 强调用数据库角色ROLE来管理对象权限。道理和 2.1 里说的类似直接给用户授权权限分散在每个用户身上后续梳理和调整都很痛苦用角色做中转权限调整只需要改角色所有成员自动生效。在 SQL Server 里完整操作是-- 第一步在对应数据库中创建新角色 USE your_db EXEC sp_addrole app_read_write_role -- 第二步调整角色属性赋予对象对应的 DML 权限 GRANT SELECT, INSERT, UPDATE, DELETE ON dbo.orders TO app_read_write_role GRANT EXEC ON dbo.sp_get_order_detail TO app_read_write_role -- 第三步把业务账号加入角色 EXEC sp_addrolemember app_read_write_role, app_user参数说明app_read_write_role 是自定义角色名按业务含义起dbo.orders 是业务表sp_get_order_detail 是存储过程。权限粒度上只给角色需要的最小指令集原则是「用不到的不给不确定的先问业务」。规范里还提到了 DRI 权限也就是 REFERENCES 权限主要在表间有外键约束时才需要平时不用主动授。回退方案是删除相应的角色EXEC sp_droprole app_read_write_role但注意角色里有成员时删不掉需要先把成员移除。2.6 空密码和弱口令清剿sa 至少 10 位强口令规范条目 SHG-Mssql-01-01-06 是针对空密码和弱口令的专项检查。这里有一句关键要求sa 账号需要设置至少 10 位的强口令。在 SQL Server 2000 时代sa 空口令就能本地登录2005 以后安装时会强制设密码但很多从老版本升级上来的实例或者开发环境sa 密码依然是弱口令比如 123456、sa123 这种。先查当前有没有空口令账号-- 查看口令为空的用户SQL Server 2000 适用 SELECT name, password FROM syslogins WHERE password IS NULL ORDER BY name说明这条语句在 SQL Server 2000 的 syslogins 视图里password 字段还能反映口令是否存在。2005 以后 password 字段不再暴露但依然会返回 NULL这条语句就失效了需要换成下面的验证方式-- 2005 查看密码策略是否启用、密码最后修改时间 SELECT name, is_policy_checked, is_expiration_checked, LOGINPROPERTY(name, DaysUntilExpiration) AS days_left FROM sys.sql_logins WHERE is_disabled 0 ORDER BY name修改指定账号的密码USE master EXEC sp_password 旧口令, 新口令, 用户名回退方案是恢复用户密码到原来状态所以执行前务必把旧密码先登记到密码管理平台或交给安全负责人保管。规范给的判断依据是再查一遍SELECT name, password FROM syslogins WHERE password IS NULL确认已经不存在空口令账号。3. 日志配置与审计把谁在什么时候干了什么记下来日志这块在整份规范里篇幅不大只有一个条目 SHG-Mssql-02-01-01但恰恰是出事之后唯一能拿来追溯的东西。等保测评里「应配置日志功能对用户登录进行记录记录内容包括用户登录使用的账号、登录是否成功、登录时间以及远程登录时用户使用的 IP 地址」这条要求对应的就是这里的审计级别配置和登录日志排查。3.1 把审计级别从「无」调到「全部」别等出了事才后悔SQL Server 默认的审计级别是「无」这意味着失败登录和成功登录都不会被记录。现场最常见的场景是某天发现业务数据被动过想查是谁做的打开日志一看什么也没有只能干瞪眼。正确配置路径如下-- 推荐用 SQL 语句开启审计效果等同于 SSMS 界面操作 USE master GO EXEC xp_instance_regwrite NHKEY_LOCAL_MACHINE, NSoftware\Microsoft\MSSQLServer\MSSQLServer, NAuditLevel, REG_DWORD, 3 GO说明AuditLevel 的取值含义是 0 无审计1 仅记录成功登录2 仅记录失败登录3 记录全部登录。规范要求调整为「全部」也就是 3这样无论攻击者用密码猜解尝试登录还是正常用户登录都会留下痕迹。xp_instance_regwrite 是 SQL Server 提供的扩展存储过程用于写实例级别的注册表配置修改后需要重启 SQL Server 服务才生效。SSMS 图形界面路径是右键点击实例 → 属性 → 安全性 → 在「审核」区域把「无」改为「全部」同时把服务器身份验证改为「SQL Server 和 Windows 模式」。注意只有改成混合验证模式SQL 账号的登录审计才有意义纯 Windows 验证模式下 SQL 账号根本不存在。开启审计后日志看得见摸得着-- 查看 SQL Server 错误日志重点看登录相关记录 EXEC xp_readerrorlog 0, 1, NLogin, NULL, NULL, NDESC, NDESC这条语句会按时间倒序把错误日志里带 Login 关键字的记录列出来每条日志会显示「登录日期、是否成功、账号名、来源 IP」。逻辑说明xp_readerrorlog 的前两个参数是日志文件编号和日志类型1 当前错误日志第三个参数是过滤关键字后两个 NULL 是过滤字段边界DESC 表示倒序。实际排查时搜关键字Login failed可以快速定位密码猜解攻击。3.2 登录日志怎么看从语句输出里区分攻击和正常访问审计开启之后日志量会明显变大尤其是数据库每天被各类监控工具、定时任务反复连的情况下。这里讲一下我自己的排查习惯。搜索失败登录记录EXEC xp_readerrorlog 0, 1, NLogin failed, NULL, NULL, NDESC, NDESC搜索某个账号的所有登录EXEC xp_readerrorlog 0, 1, Nuser_name_1, NULL, NULL, NDESC, NDESC排错经验如果在错误日志里看到大量来自同一个 IP 的 Login failed每几秒一条说明有人在跑密码字典要立刻在 Windows 防火墙层封掉这个 IP。如果看到 Login failed for user sa 且来源 IP 是内网段可能是某个老系统的连接串里 sa 密码已经改掉了但应用没更新这时要反过来查那个 IP 对应的服务器上跑了什么服务。推荐的做法是把审计级别调到 3 之后留一周观察日志量是否大到影响性能。对大多数业务系统来说登录日志的量级很小根本不会拖慢性能但日志文件增长是有的要注意错误日志轮转策略。4. 通信协议与网络安全收紧网络面别让数据库裸奔通信协议这一章包含三个条目只保留 TCP/IP 并禁用其余协议、加固 TCP/IP 协议栈的注册表键值、强制协议加密。这一章的操作和其他章节不太一样除了 SQL Server 自身的配置还涉及到 Windows 注册表和底层网络参数操作时要格外小心。4.1 网络协议最小化只留 TCP/IP禁用 Named Pipes 和 Shared MemorySQL Server 默认会启用 Shared Memory、Named Pipes、TCP/IP 等多种协议。Shared Memory 只用于本机连接Named Pipes 在跨网段场景下效率低且历史上出过安全问题规范明确建议只使用 TCP/IP 协议禁用其他协议。查看当前启用了哪些协议用 SQL Server 配置管理器# 打开 SQL Server Configuration Manager # 路径SQL Server 配置管理器 - SQL Server 网络配置 - 实例名 - 协议在配置管理器里右键 TCP/IP 选择启用右键 Named Pipes 和 Shared Memory 选择禁用。操作完成后重启 SQL Server 服务生效。判断依据重新打开服务网络实用工具查看协议列表确认只有 TCP/IP 处于启用状态。这里有个需要注意的细节如果你本机的一些管理工具比如某些版本的 SSMS 第一次连本机依赖 Shared Memory把 Shared Memory 禁用后可能会出现「无法连接请检查网络或实例名」的报错遇到这种情况不用慌连接串里显式指定tcp:前缀或改用127.0.0.1即可。回退方案在配置管理器里把禁用的协议重新启用即可不需要动任何数据文件。4.2 加固 TCP/IP 协议栈三个注册表键值堵住路由器级攻击这一节SHG-Mssql-03-01-02是整份规范里技术含量最高但也最容易出错的部分。它加固的不是 SQL Server 本身而是承载 SQL Server 的 Windows 操作系统底层的 TCP/IP 协议栈。要检查三个注册表键值注册表键推荐值防什么攻击HKLM\System\CurrentControlSet\Services\Tcpip\Parameters\DisableIPSourceRouting2源路由欺骗攻击HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\EnableICMPRedirect0ICMP 重定向攻击HKLM\System\CurrentControlSet\Services\Tcpip\Parameters\SynAttackProtect2SYN Flood 攻击用命令检查当前值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如果查出来不是推荐值用下面的命令修改reg add HKLM\System\CurrentControlSet\Services\Tcpip\Parameters /v DisableIPSourceRouting /t REG_DWORD /d 2 /f reg add HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters /v EnableICMPRedirect /t REG_DWORD /d 0 /f reg add HKLM\System\CurrentControlSet\Services\Tcpip\Parameters /v SynAttackProtect /t REG_DWORD /d 2 /f参数说明DisableIPSourceRouting 设置为 2 表示完全禁止 IP 源路由这样攻击者就无法通过伪造源路由头部来绕过访问控制EnableICMPRedirect 设置为 0 表示禁用 ICMP 重定向防止攻击者通过伪造 ICMP 重定向报文改变路由表SynAttackProtect 设置为 2 表示启用 SYN 攻击保护当 SYN 半连接数达到阈值时系统会触发 synattack 保护机制降低被 SYN Flood 打挂的概率。这里几个坑要讲清楚一是注册表修改需要重启 Windows 才生效不仅仅是重启 SQL Server二是这三个键值改完后某些依赖多网卡路由的服务器可能出现路由行为变化生产环境务必在变更窗口操作并提前做网络连通性测试三是 SynAttackProtect 在 Windows Server 2012 以后系统里默认就有保护机制键值可能查不到如果查不到不用强行添加说明系统已经内置了同类保护。回退方案把键值改回原来的数一般 DisableIPSourceRouting 原值是 0、EnableICMPRedirect 原值是 1、SynAttackProtect 可能不存在重启网络或重启系统即可。判断依据重新reg query读取三个键值确认。4.3 强制协议加密堵住明文抓包风险规范条目 SHG-Mssql-03-01-04 要求设置「强制协议加密」。SQL Server 默认情况下客户端和服务端之间的 TDS 数据包是明文传输的只要有人在网络上抓包就能直接看到 SQL 语句里的表名、字段名、甚至是 WHERE 条件里的业务数据。虽然密码字段是哈希过的但 SQL 语句里的数据内容会裸露出来对安全性要求高的系统这不能接受。老版本 SQL Server 用服务器网络实用工具来配置路径是开始菜单 → Microsoft SQL Server 程序组 → 服务器网络实用工具 → 常规 → 勾选「强制协议加密」。在 SQL Server 2005 以后版本里对应的功能在 SQL Server 配置管理器里# SQL Server 配置管理器 - SQL Server 网络配置 - 协议 - 右键 TCP/IP - 属性 - 标志页 # 找到 Force Encryption设为 Yes设置成 Yes 之后要求所有客户端连接都使用 SSL 加密否则拒绝连接。但这个操作有一个连带要求服务器上需要安装证书。如果没有安装由受信任 CA 签发的证书SQL Server 会使用自签名证书客户端的 SSMS 或应用连接时会弹出证书不受信任的警告某些老版本 JDBC 驱动甚至可能直接连不上。更好的做法是把「强制加密」打开的同时确保服务器已申请并安装了合法 CA 证书。如果因为证书问题导致现有应用连不上规范里的回退方案是恢复「强制协议加密」到原状态也就是设回 No等证书准备好再切。实际执行时我的建议是先让业务方用测试环境验证 JDBC/ODBC 连接串是否兼容加密连接再在生产上切换切换后立刻用一个独立账号做一轮完整登录测试。5. 常见问题排查执行规范时最容易翻车的五个场景把 01、02、03、04 四章的操作真正落到生产环境时会有一些文档里没写透的隐蔽问题。这一章每条都是实际执行过才踩到的坑按「现象 → 原因 → 解决」的方式记录给你当现场排除手册用。5.1 删了 xp_cmdshell 之后业务系统报错「SQL Server 阻止了对组件 xp_cmdshell 的访问」现象执行完规范里 4.1.1 的存储过程清理脚本后原本跑得好好的某个报表任务突然全部失败应用日志里报SQL Server blocked access to procedure xp_cmdshell。原因业务系统里有功能实际依赖 xp_cmdshell 调用外部程序比如某些老系统用 xp_cmdshell 调 bat 脚本做数据导出。当时只按规范删了存储过程没有先做依赖排查。解决临时恢复生产上的 xp_cmdshell同时联系业务方确认具体用途推动业务改造。恢复命令USE master EXEC sp_addextendedproc xp_cmdshell如果 SQL Server 2005 以上版本推荐不恢复扩展存储过程而是改用 SQL Server Agent 的作业步骤去调用外部程序或者用 CLR 存储过程替代从根本上降低风险。从那以后我每次做危险存储过程删除前都会先跑一遍下面的依赖排查-- 查找哪些存储过程/作业/视图引用了 xp_cmdshell SELECT OBJECT_NAME(object_id) AS obj_name, definition FROM sys.sql_modules WHERE definition LIKE %xp_cmdshell%5.2 在部署了 SQL Server 集群Cluster的机器上改 TCP/IP 协议栈注册表心跳断了现象在一套 SQL Server 故障转移集群上执行 4.2 的注册表加固后集群节点的私有心跳网络出现频繁抖动甚至触发了一次故障转移。原因DisableIPSourceRouting 设为 2 后某些依赖源路由选项的旧版多播或心跳网络会有异常集群心跳使用的是节点间专用网络某些老环境的网卡驱动对源路由协议有依赖。解决集群环境的网络协议栈加固不能一刀切。把 DisableIPSourceRouting 从 2 回退到 1表示丢弃来自非本机接口的源路由包但允许本机处理的包然后重新做集群健康检查。回退命令reg add HKLM\System\CurrentControlSet\Services\Tcpip\Parameters /v DisableIPSourceRouting /t REG_DWORD /d 1 /f另一条经验集群服务器上做注册表修改前先检查 Windows 故障转移集群的cluster.log确认心跳网络没有依赖项再执行变更。5.3 审计级别改成「全部」后错误日志文件暴涨一晚上写了 5GB现象把审计级别调到 3 之后发现 SQL Server 错误日志目录下的 ERRORLOG 文件在业务高峰期快速膨胀磁盘空间告警。原因审计级别为「全部」时任何登录成功或失败都会写日志。如果业务系统使用连接池每一条新建连接的 Login 成功记录都会写入高并发系统一晚上产生几十万条登录记录是常事。解决不要直接调回 0正确姿势是配合日志轮转策略。SQL Server 错误日志默认每 6 次重启或手动轮转才会生成新文件。手动轮转命令EXEC sp_cycle_errorlog把轮转频率提高并设置日志文件上限然后在 SQL Server Agent 里建一个每小时的作业调用sp_cycle_errorlog再配合 Windows 的计划任务清理超过 7 天的日志文件。这样既保留审计能力又控制磁盘占用。5.4 sa 密码改强口令之后好几个老业务连不上了现象按 2.6 的规范把 sa 密码改成 15 位强口令后当天夜里批量作业开始报登录失败。原因老业务系统的连接串里 sa 密码是明文写死的改密码后应用不会自动读取新密码。常见于供应商已失联的老系统或者交接不完整、没人知道哪个文件里写死了连接串。解决生产环境改 sa 密码前先抓取系统里所有包含Password或pwd的配置文件。我自己常用的排查方式是在数据库服务器上搜索findstr /s /i /m password C:\app\*.config C:\app\*.xml C:\app\*.properties把搜索到的文件列表发给业务方逐项确认。如果实在有系统没法当天改连接串可以先把旧密码记录到变更记录里给业务方留 24 小时缓冲期第二天窗口期统一切换。5.5 强制协议加密打开后JDBC 连接报 SSL 证书错误现象执行 4.3 强制协议加密之后Java 应用连数据库时报The server selected protocol version TLS10 is not accepted by client preferences [TLS12]或者证书信任错误。原因老版本 SQL Server2008/2008 R2默认仅支持 TLS 1.0而新版本 JDBC 驱动默认要求 TLS 1.2同时服务器用自签名证书JVM 的信任库不认。解决分两步走。给服务器安装受信任的 CA 证书从正规证书服务商申请或内部 CA 签发然后在 JDBC 连接串里显式指定加密参数和 TLS 版本。连接串参考jdbc:sqlserver://10.1.2.3:1433;databaseNameerp;encrypttrue;trustServerCertificatetrue;sslProtocolTLSv1.2参数说明encrypttrue开启加密trustServerCertificatetrue表示暂时信任服务器证书测试环境用生产环境这句要删掉sslProtocolTLSv1.2指定协议版本。如果 SQL Server 版本太老不支持 TLS 1.2优先考虑升级 SQL Server不要为了兼容降低 JDK 的 TLS 版本要求。6. 把整份规范变成自动化核验脚本半小时扫完所有实例规范的条目再多人工逐条核对终究费时费力而且容易漏项。这里分享一个我常用的做法把规范里的「系统当前状态」的查询语句收集起来拼成一个批量检查脚本用 SQLCMD 一次跑完所有实例输出一份 Markdown 格式的核验报告。这套方法在几十个实例的巡检场景下很实用。先创建一个存储过程或 SQL 脚本文件sqlserver_hardening_check.sql内容覆盖账号、权限、审计、协议、危险存储过程五个维度SET NOCOUNT ON; PRINT 1. 账号与权限检查 ; -- 检查 sysadmin 角色的成员确认没有多余账号 SELECT sysadmin_members AS check_item, s.name AS login_name FROM sys.server_role_members m JOIN sys.server_principals r ON m.role_principal_id r.principal_id JOIN sys.server_principals s ON m.member_principal_id s.principal_id WHERE r.name sysadmin; -- 检查是否存在空密码 SQL 登录密码策略未启用且密码为空 SELECT blank_password AS check_item, name FROM sys.sql_logins WHERE password_hash IS NULL AND is_disabled 0; PRINT 2. 审计级别检查 ; -- 读取审计级别注册表值应为 3 EXEC xp_instance_regread NHKEY_LOCAL_MACHINE, NSoftware\Microsoft\MSSQLServer\MSSQLServer, NAuditLevel; PRINT 3. 危险扩展存储过程检查 ; -- 检查 xp_cmdshell 等扩展存储过程是否还存在 SELECT dangerous_proc AS check_item, o.name FROM sys.objects o WHERE o.name IN (xp_cmdshell, xp_dirtree, xp_fixeddrives, xp_regread, sp_OACreate) AND o.type X;脚本逻辑分三段第一段查 sysadmin 角色成员和空密码登录这是账号管理检查的核心第二段用 xp_instance_regread 读审计级别注册表值正常应为 3第三段查危险扩展存储过程是否还在列出所有没删干净的。运行这段脚本的方式是在命令行里对每个实例执行sqlcmd -S 10.1.2.3 -U sa -P 密码 -i sqlserver_hardening_check.sql -o check_result.txt如果怕密码泄露在命令行里可以把连接信息写到脚本文件里用-i直接调用或者使用-E走 Windows 身份验证sqlcmd -S 10.1.2.3 -E -i sqlserver_hardening_check.sql -o check_result.txt跑完之后打开 check_result.txt重点关注三类输出sysadmin_members 列表里有没有不应该出现的账号blank_password 有没有返回记录dangerous_proc 有没有输出。只要这三项全空、AuditLevel 读出来是 3这台实例的核心加固项基本就到位了。文件输出之后建议把脚本一并保存到运维文档库里每个月做一次月度巡检时重新跑一遍把结果和上个月的对比新增加的账号和权限变化一目了然。这个做法比任何监控工具都直接因为查的就是规范条目本身不存在「监控漏配」的问题。从那以后我每次接手新的数据库实例第一件事就是跑一遍这个脚本三十秒内就知道这台机器在安全上处于什么状态不用再靠感觉判断。希望帮到你。本文还有配套的精品资源点击获取