简介:一份面向数据库管理员与安全运维人员的Sql Server数据库系统加固规范文档,围绕账号管理、认证授权、日志配置、通信协议、设备安全等维度,明确定义了数据库加固的具体策略与执行条目,可帮助企业排查数据库弱口令、共享账号、未加密传输等安全隐患。文档以编号化规范形式逐项展开,每一条均包含实施目的、问题影响、系统当前状态、参考配置操作、回退方案与判断依据,细致程度足以作为内部安全基线或等保整改依据直接落地。整体覆盖从登录账号分配、无效账号清理、启动账号权限限制到SSL/TLS加密通信、防病毒软件安装与定期安全更新的完整加固闭环,并以明确编号便于逐项对照与审计追溯。包体为1个doc文件,共计1.73MB,便于查阅、打印与二次修订,适合信息安全管理制度的编订与数据库日常运维参考。目前已有245人学习下载,对刚启动数据库安全治理的团队具有直接借鉴价值。
1. Sql Server数据库系统加固规范:先搞清你是加固还是加麻烦
一次针对 Sql Server 的加固如果只是关两个功能、改个端口、把 sa 禁掉,大概率一周内会被业务方追着回滚。真正的 Sql Server 数据库系统加固规范是一套可复查的基线:认证模式怎么定、哪些账号能碰 sysadmin、审计日志落在哪、备份有没有加密、改完配置之后如何证明系统还跑得通。这套东西适合三类人:接手了存量实例的运维、要给新系统定安全基线的开发负责人、被等保或内部安全审查追着要整改清单的 DBA。别把它当成一次性操作手册,它是每次变更前都要翻一遍的清单。
2. 安装与实例基线:把 Sql Server 的攻击面先收窄
2.1 安装期就要定死的三个选择:服务账号、认证模式、排序规则
Sql Server 加固规范的第一个动作不是写脚本,而是把"默认开着、但你根本没用"的面全部关掉。默认安装的实例暴露了不少外围功能:xp_cmdshell、CLR 集成、OLE 自动化、命名管道,还有所有人都知道的 1433 端口。这些功能本身不一定有漏洞,但每多一个面,你就多一个需要持续跟踪补丁、审计权限配置的点。攻击者从来不找你最强的防线,只找你没顾上的那一块。
安装时就有三个选择,装完再改成本极高,必须在装机评审阶段定死。第一个是服务账号。安装向导默认给的服务账号权限普遍偏高,有些直接是 Local System。生产实例我一般会单独建一个 Windows 账号,权限只给到"能启动 SQL Server 服务、能读写数据和日志目录、能访问备份目录"这几项,绝不加进本地 Administrators。逻辑很简单:SQL Server 进程万一被提权利用,它所在账号的权力上限就是你能承受的安全边界。
第二个是认证模式。Windows 认证模式在口令管理和审计上天然占优,复杂度、锁定阈值全部交给域策略统一管,不用在数据库里各搞一套。如果业务里有老应用、跨平台客户端只能用 SQL 登录名,那就只能选混合模式,但规范里要写死一条:每一个 SQL 登录名必须对应一个责任人,不允许出现"这个账号谁在用不知道"的情况。
第三个是排序规则(Collation)。安装时选错,后期要么改数据库排序规则重建系统库,要么忍受行为不一致。常见翻车场景是业务要求大小写不敏感或特定中文排序规则,装的时候没评审,上线半年后才发现 LIKE 查询行为和预期不一致。所以排序规则在加固规范里是"装前评审项",不是"装后整改项"。
2.2 关掉用不上的功能面:xp_cmdshell、CLR、远程 DAC
默认安装里有一批"听着有用、实际用不上"的功能,xp_cmdshell 允许在 SQL Server 进程里执行操作系统命令,一个 SQL 注入点就能变成命令执行;CLR 可以加载 .NET 程序集进 SQL Server 进程,属于高风险扩展面;OLE 自动化允许从 T-SQL 调 COM 对象,历史上出过多次利用案例。生产环境里大部分实例都不需要它们,基线动作就是全部关闭。
下面是我常用的基线关闭脚本,DBA 用管理员权限执行:
-- 加固基线:先打开高级配置项,否则后面的项看不到 EXEC sp_configure 'show advanced options', 1; RECONFIGURE; GO -- xp_cmdshell:默认关闭,若此前被打开过,这里强制关掉 EXEC sp_configure 'xp_cmdshell', 0; -- CLR:没有托管程序集的实例一律关闭 EXEC sp_configure 'clr enabled', 0; -- OLE 自动化:调 COM 对象的高危口,默认关 EXEC sp_configure 'Ole Automation Procedures', 0; -- 远程 DAC:专属管理员连接,默认仅本机,保持关闭 EXEC sp_configure 'remote admin connections', 0; -- 数据库邮件:不需要邮件告警的实例关掉 EXEC sp_configure 'Database Mail XPs', 0; RECONFIGURE; GO脚本逻辑不复杂:先打开show advanced options,否则后面的配置项根本不显示;改完统一RECONFIGURE让配置生效。这里有个新手常踩的坑:sp_configure有两个值,value是设定值,value_in_use是实际生效值。改完要查的就是后者,别看到value变 0 就以为完事了:
-- 核对实际生效值:value_in_use 为 0 才是真的关掉了 SELECT name, value, value_in_use FROM sys.configurations WHERE name IN ( 'xp_cmdshell', 'clr enabled', 'Ole Automation Procedures', 'remote admin connections', 'Database Mail XPs' );这套脚本在虚拟机和容器里的 SQL Server 同样适用,只是容器实例通常改完配置不持久,要在镜像构建阶段做掉,而不是等部署完再连进去改,否则容器一重建全部还原。
2.3 协议与端口:别把"改端口"当成加固的全部
SQL Server 默认监听 1433,自动化扫描工具扫到 1433 就直接开猜口令。所以很多加固规范第一条就是"改端口"。我的观点是:改端口要做,但它属于低成本干扰,不是安全边界。真正拦人的是认证强度、口令策略和传输加密,端口改不改,定向攻击都能扫出来。
协议层面,我一般只保留 TCP/IP,把 Named Pipes 禁掉。命名管道走的是 Windows 文件共享通道,对很多内网安全策略来说是个额外的开放面,业务早就没人用它了。配置在 SQL Server 配置管理器里改:实例协议 → TCP/IP 启用、Named Pipes 禁用,再在 IP 地址页签把监听端口从 1433 改成新端口,改完必须重启 SQL Server 服务。
| 配置项 | 加固值 | 说明 |
|---|---|---|
| TCP/IP | 启用 | 现代应用默认连接通道 |
| Named Pipes | 禁用 | 老协议,攻击面大于收益 |
| 监听端口 | 非 1433 | 降低自动化扫描命中率 |
| 隐藏实例 | 启用 | 防止 SQL Browser 枚举实例名 |
| 防火墙 | 只放行业务源 IP | 端口规则与连接串同步修改 |
隐藏实例有个副作用必须提前知道:客户端连命名实例时默认会去问 SQL Browser(UDP 1434),隐藏之后它不回答,连接字符串必须写成Server=tcp:主机名,14330这种完整格式。很多开发工具里配的是实例名,一隐藏就全连不上。所以改端口、隐藏实例、更新全部连接串、放行防火墙,这四件事必须在一个变更窗口里一起完成,少任何一件都是事故,具体踩坑案例放第五章讲。
3. 账号与权限加固:Sql Server 加固的核心不在密码复杂度
攻击面收窄之后,下一层是账号体系。Sql Server 加固规范里最该较真的不是"密码设多复杂",而是"谁拥有什么权限"。多数安全事故不是密码被猜出来,而是权限给大了:一个本应只读一张表的账号,被丢进了 sysadmin,攻击者拿到它就能删库。密码复杂度是挡第一波的,权限边界才是兜底的。
3.1 先判断认证模式,再决定 sa 怎么处置
第一步是看清当前认证模式,一句 T-SQL 就够:
-- 1 = 仅 Windows 认证;0 = 混合模式(SQL + Windows 认证) SELECT SERVERPROPERTY('IsIntegratedSecurityOnly') AS CurrentAuthMode;如果返回 0,说明实例跑在混合模式下,存在 SQL 登录名体系。这时候先别急着切认证模式,先盘一下sys.sql_logins里有哪些 SQL 登录名、每个被哪些应用或作业引用。混合模式本身不是原罪,原罪是"SQL 登录名口令弱、没有策略约束、权限还大"。存量实例的整改顺序很重要:先摸清账号清单,再动手改,不能反过来。
sa 的处置是规范里最敏感的一步。常见做法是重命名、禁用、改口令三件事一起做:
-- 1. 重命名,让暴力破解连账号名都要猜 ALTER LOGIN sa WITH NAME = [sa_dba_disabled]; -- 2. 禁用,任何连接都不能再用它 ALTER LOGIN [sa_dba_disabled] DISABLE; -- 3. 口令也改掉,防的是哪天有人忘了"已禁用"又给启用 ALTER LOGIN [sa_dba_disabled] WITH PASSWORD = '这里放一串不少于16位的随机口令';注意:凡是应用连接串里写死 sa 的,必须先切连接串再动 sa,顺序不能反。
禁 sa 之前,用配置中心或代码仓库全局搜一遍uid=sa、User ID=sa字样。这一步漏了,后面就是整片业务连不上,而且看起来像网络问题,最迷惑人。
3.2 口令策略:CHECK_POLICY 不是开了就完事
SQL Server 的口令复杂度策略其实不自己实现,它把检查外包给 Windows 本地安全策略。CHECK_POLICY = ON的意思是"此登录名遵循 Windows 口令策略",包括最小长度、复杂度要求、锁定阈值。这里有两个常见误用,写进规范里能省很多事。
第一个误用是只对新登录名生效。存量账号早就以弱口令存在了,整改动作是批量把存量 SQL 登录名也纳入策略:
-- 把存量 SQL 登录名纳入口令策略 -- 逐个执行,不要只覆盖新建账号 ALTER LOGIN [app_report] WITH CHECK_POLICY = ON, CHECK_EXPIRATION = ON; -- 强制下次登录时必须改口令 ALTER LOGIN [app_report] WITH MUST_CHANGE = ON;第二个误用是CHECK_POLICY和CHECK_EXPIRATION不同时开。只开策略不开过期,账号永远不会被要求定期换口令,策略等于半残。MUST_CHANGE = ON只在有过期策略时有意义,它让账号下次登录直接进入改密流程,适合接管存量账号时强制洗一遍口令。
还有个容易被忽略的点:锁定阈值在 Windows 策略里如果没配,CHECK_POLICY开了也不会帮你锁账号。要在域策略或本地安全策略里把"账户锁定阈值"设到 5 次以内,这才是暴力破解的真正拦路虎。SQL Server 这边只管把检查开关打开,兜底机制在操作系统那一层。
3.3 最小权限:sysadmin 里只该有运维管理员
最小权限在 SQL Server 里落地就一件事:先审计 sysadmin 成员,再给应用建"刚好够用"的账号。
-- 列出 sysadmin 角色的所有成员 SELECT p.name, p.type_desc, p.is_disabled FROM sys.server_role_members m JOIN sys.server_principals p ON m.member_principal_id = p.principal_id JOIN sys.server_principals r ON m.role_principal_id = r.principal_id WHERE r.name = 'sysadmin';查询结果里如果有应用账号、报表账号、甚至当年测试遗留的账号,就该清理。sysadmin 只保留运维管理员的登录名,而且每个登录名要能定位到具体的人,不接受共享账号。应用账号按角色拆分:
-- 应用只读账号:能查业务库,但没有任何写权限 CREATE LOGIN [app_report_ro] WITH PASSWORD = '独立强口令', CHECK_POLICY = ON, CHECK_EXPIRATION = ON; CREATE USER [app_report_ro] FOR LOGIN [app_report_ro]; ALTER ROLE db_datareader ADD MEMBER [app_report_ro]; -- 如果只允许读部分表,就收紧到对象级 REVOKE SELECT ON dbo.orders FROM [app_report_ro];| 角色 | 用途 | 规范建议 |
|---|---|---|
| sysadmin | 实例级运维 | 仅运维管理员,账号可追溯 |
| db_owner | 库结构变更 | 仅发布账号和开发负责人 |
| db_datareader | 只读查询 | 应用只读账号的默认选择 |
| 自定义角色 | 按业务对象授权 | 优先于直接给用户授对象权限 |
更细的做法是 schema 隔离:把应用的表收进独立 schema,应用账号拥有自己 schema 的权限,对别的 schema 连 SELECT 都没有。这样即使应用被注入,攻击者的活动范围也被 schema 边界挡住。链接服务器(Linked Server)是另一个常被漏掉的口子,用sp_helplinkedsrvlogin查一遍,没有明确需求一律回收openquery权限,否则它就是绕过实例权限体系的暗门。
4. 审计、加密与备份:加固的后半程防线
认证和权限做完了,接下来是"出事了你能不能知道、数据被拿走能不能用",对应三件事:审计、加密、备份。很多加固方案做到权限就收工,等于只修了门锁没装监控,也没给保险柜上锁。
4.1 登录审计:先保证失败登录和权限变更一定有记录
SQL Server 有个历史悠久的登录审计开关 AuditLevel,默认只记失败的登录,写在错误日志里。最省事的检查方式是直接读注册表:
-- 查看登录审计级别:0=无, 1=仅失败, 2=仅成功, 3=全部 EXEC xp_instance_regread N'HKEY_LOCAL_MACHINE', N'SOFTWARE\Microsoft\MSSQLServer\MSSQLServer', N'AuditLevel';不过现代实例我更推荐用服务器审计(Server Audit),它输出到文件,自带文件大小和轮转控制,比错误日志干净得多,也更好做归档分析:
-- 1. 定义审计目标:文件目录、单文件上限、保留文件数 CREATE SERVER AUDIT [Audit_Security_Basic] TO FILE (FILEPATH = N'D:\SQLAudit\', MAXSIZE = 512 MB, MAX_FILES = 8) WITH (QUEUE_DELAY = 1000, ON_FAILURE = CONTINUE); GO -- 2. 定义审计动作组:失败登录、登录名变更、角色成员变更 CREATE SERVER AUDIT SPECIFICATION [Audit_Spec_Security_Basic] FOR SERVER AUDIT [Audit_Security_Basic] ADD (FAILED_LOGIN_GROUP), ADD (LOGIN_CHANGE_GROUP), ADD (SERVER_ROLE_MEMBER_CHANGE_GROUP) WITH (STATE = ON); GO -- 3. 启动审计 ALTER SERVER AUDIT [Audit_Security_Basic] WITH (STATE = ON); GO几个参数值得解释。MAXSIZE和MAX_FILES配合形成轮转,写满 512 MB 就换下一个文件,最多保留 8 个,不会无限占盘。QUEUE_DELAY = 1000表示审计事件在队列里最多等 1 秒写盘,所以极端情况下最后 1 秒内的少量事件可能丢失,这是用完整性换性能的权衡。ON_FAILURE = CONTINUE表示审计写不进去时业务继续跑,生产环境多数选这个;如果选SHUTDOWN,审计失败会导致实例关停,后果自己掂量。另外审计目录必须先建好,SQL Server 不会替你创建目录。目录最好独立于数据盘,并单独加磁盘空间监控。
4.2 传输加密与静态加密:ForceEncryption 和 TDE 的取舍
传输加密是加固里最容易被跳过的一环。默认情况下新版本客户端和服务端的 TDS 流量有握手加密,但较老的客户端或某些配置下可能降级成明文,抓包就能看到 SQL 文本。服务端强制加密在 SQL Server 配置管理器里设置:实例协议 → 标志 → ForceEncryption = 是,改完重启服务。前提是服务器装了证书,且证书 CN 要和客户端连接时使用的主机名匹配,否则客户端会报证书链错误,这个坑比不加密还难排查。
当前会话是否已加密,用这个查:
-- encrypt_option 为 TRUE 说明当前连接是加密链路 SELECT session_id, encrypt_option, net_transport, client_net_address FROM sys.dm_exec_connections WHERE session_id = @@SPID;静态加密的代表是 TDE(透明数据加密),它把数据文件、日志文件、备份文件在落盘时加密。它防的威胁模型是"物理文件被拷走"——备份文件被拿走、数据文件被拖走,没有证书就解不开。但 TDE 不防内存窥探,也不防有权限的查询本身,很多人把这两件事搞混。
-- TDE 开启四步走 USE master; -- 1. 数据库主密钥 CREATE MASTER KEY ENCRYPTION BY PASSWORD = '主密钥独立强口令'; -- 2. 服务器证书 CREATE CERTIFICATE TDE_Cert_2024 WITH SUBJECT = 'TDE Certificate 2024'; GO -- 3. 目标库创建数据库加密密钥 USE [BusinessDB]; CREATE DATABASE ENCRYPTION KEY WITH ALGORITHM = AES_256 ENCRYPTION BY SERVER CERTIFICATE TDE_Cert_2024; GO -- 4. 开启加密(这步会全库扫描,挑低峰窗口) ALTER DATABASE [BusinessDB] SET ENCRYPTION ON; GO注意:TDE 证书与主密钥必须导出备份,并与数据库备份分开放置。
TDE 最大的坑不在 SQL 语句,在证书管理。一旦实例没了、证书没备份,TDE 数据库连附加都附加不上,等于数据跟着证书一起丢了,这是没有后悔药的一步。开启过程本身是全库加密扫描,I/O 和 tempdb 压力明显上升,生产环境务必在维护窗口执行,同时盯着点事务日志增长。
4.3 备份:加密、校验、恢复演练三件套
加固规范不覆盖备份,等于前面白做。攻击者拿不走线上数据,还可以拿你的备份文件。SQL Server 2014 起原生支持备份加密,配合 CHECKSUM 校验是标准动作:
-- 加密 + 压缩 + 校验,一次备份全带上 BACKUP DATABASE [BusinessDB] TO DISK = N'D:\SQLBackup\BusinessDB_2024.bak' WITH COMPRESSION, CHECKSUM, INIT, ENCRYPTION (ALGORITHM = AES_256, SERVER CERTIFICATE = BackupCert_2024);CHECKSUM让备份在写入和未来恢复时做页级完整性校验,能挡住"备份文件损坏但没发现"这类经典事故。INIT是覆盖同名文件,日常按规范归档的话文件名都带日期,这里用 INIT 是防止残留同名备份干扰恢复。备份证书和 TDE 证书要分开管理:TDE 证书管数据文件加密,备份证书管备份加密,恢复时两张证书可能都要用,证书导出文件建议用独立密码保护。
验证备份不能只做RESTORE VERIFYONLY,那只是校验头部和页校验:
RESTORE VERIFYONLY FROM DISK = N'D:\SQLBackup\BusinessDB_2024.bak' WITH CHECKSUM;我的习惯是每月至少做一次真实恢复:一台隔离的恢复实例,把最近的完整备份加日志备份按序还原,应用连上去跑一遍冒烟查询。备份文件能读出来,和能恢复成可查询的数据库,是两回事。日志链缺一环、证书不在,恢复就卡住。把恢复演练写进月度巡检,备份这步才算闭环。
5. Sql Server 加固避坑指南:5 个把生产干趴的翻车点
加固动作本身不难,难在改完之后的连锁反应。下面五条都是实际维护里见过或踩过的坑,每条按"现象 → 原因 → 解决"写全。照着规范做的时候,最可能翻车的点基本集中在这些位置。
5.1 现象一:切成 Windows 认证模式后,业务整体连不上
现象:实例从混合模式切成仅 Windows 认证,重启后所有用 SQL 账号连接的应用瞬间报 "Login failed for user",故障一直持续到回滚。
原因:切认证模式之前没盘清存量连接方式。很多老应用、报表工具、定时作业的连接字符串写死的是 SQL 登录名,Windows 认证模式下这些账号全部失效,无一幸免。
解决:把"认证模式变更"在规范里定性为停机级变更。操作前先跑SELECT name FROM sys.sql_logins WHERE type_desc = 'SQL_LOGIN';列出全部 SQL 登录名,逐个确认在哪些库、被哪些作业和应用引用,形成清单。全部业务连接都迁移到 Windows/域账号之后才允许切换。迁移不了的,就留在混合模式,但所有 SQL 登录名必须纳入口令策略和审计——混合模式不是不能加固,而是动作不能省。
5.2 现象二:禁用 sa 后,作业、复制、镜像全部失败
现象:按规范重命名并禁用了 sa,第二天早上值班发现 SQL Agent 作业大面积失败,日志里全是"无法以 sa 身份登录",部分高可用会话也断开。
原因:很多作业的 owner 或运行身份就是 sa。作业创建时如果没显式指定 owner,默认就是创建者的 SID,早期很多作业就是当年用 sa 建的。复制、镜像、日志传送这类组件,如果当初配置时用了 sa 权限,禁用后全部趴窝。
解决:动 sa 之前先查一遍作业归属:SELECT job.name, SUSER_SNAME(job.owner_sid) FROM msdb.dbo.sysjobs job WHERE job.enabled = 1;,凡是 owner 是 sa 的,一律改成专门的管理员登录名。复制和镜像的配置账号用低权限账号重新配置,不要复用 sa。规范里写死:涉及 sa 的任何操作,前置检查清单必须有"作业 owner 检查"和"高可用组件账号检查"两项。
5.3 现象三:审计一开,磁盘一天被写满
现象:登录审计上线当天,审计文件快速增长到数 GB,把磁盘写满,数据库开始告警,严重时影响业务写入。
原因:审计动作组选得太大,比如把SCHEMA_OBJECT_ACCESS_GROUP也加上了,等于把每一条 SELECT 都记下来;或者MAXSIZE、MAX_FILES没设,文件无限增长;又或者审计文件和数据库日志放在同一块盘上互相挤占。
解决:审计从最小集起步,先只加失败登录、登录名变更、权限变更三个动作组,跑两周看量级再决定扩不扩。文件上限在创建时就钉死,用MAX_FILES配合MAX_SIZE做轮转。审计目录独立于数据盘,加 80% 容量告警。记住审计是日志不是业务数据,丢几秒事件可以接受,把生产盘写满才是事故。
5.4 现象四:TDE 开启后,备份体积反而变大
现象:开启 TDE 后第一次全量备份,发现备份文件比加密前大了 10% 到 20%,压缩比例明显下降。
原因:TDE 是数据页级加密,备份压缩发生在加密之后,压缩器面对的是熵很高的密文,压不动。所以备份体积不降反升,这不是故障,是 TDE 的固有代价。
解决:容量规划时给备份预留 15% 到 20% 的上浮。如果备份压缩率是硬指标,先评估威胁模型,是不是所有库都需要 TDE;只对合规要求的核心库开启。TDE 开启后的第一次备份别急着上压缩,先做一次基线验证,确认解密链路没问
本文还有配套的精品资源,点击获取