资讯动态

Sql Server 数据库系统加固规范:账号、网络、审计与备份的六条基线

发布时间:2026/10/14 0:19:03 来源:尧图企业网站定制
简介这份Sql Server数据库系统加固规范文档面向数据库管理员、安全运维人员及等保合规实施者围绕账号管理、认证授权、日志配置、通信协议与设备安全等维度给出可落地的加固要求与配置依据。资源包内含1个doc文档压缩包约1.73MB内容以条目化规范编号组织便于按模块查阅与对照执行。文档从账号最小权限、密码复杂度与有效期、登录失败锁定、双因素认证到日志记录、SSL/TLS加密通信、防火墙与入侵检测再到服务器防毒与定期安全检查逐项列出实施目的、问题影响、当前状态、实施步骤、回退方案、判断依据、实施风险与重要等级并附有具体操作命令示例。目前已有245人学习下载适合需要开展数据库安全加固、合规自查或编写加固方案的技术人员参考使用。1. 一次基线核查暴露的六个配置缺口很多团队第一次做 Sql Server 数据库系统加固规范都是从一次基线核查开始的。某公司内网一台跑了三年多的业务库平时没人动过配置直到安全团队用脚本扫了一遍才发现 sa 账号还开着、远程登录没限制、备份目录权限是 Everyone 完全控制。这类问题不是漏洞是配置债平时不疼不痒一旦被横向利用就是整库沦陷。Sql Server 数据库系统加固规范本质是把「装完能用」的默认状态收敛成「最小权限、最小暴露面、可审计」的受控状态。它解决的不是某个 CVE而是账号、认证、网络、权限、审计、备份这六条线上的系统性风险。适合谁看手上管着几台到几十台 Sql Server 实例的 DBA、运维、安全基线负责人以及需要过等保测评或内部审计的团队。下面按我实际落地的顺序把每一步的命令、参数和判断标准讲清楚。2. 账号与认证面收敛从 sa 到最小权限登录名加固的第一步永远是账号因为绝大多数入侵路径的终点都是拿到一个高权限数据库账号。Sql Server 的账号体系分两层服务器级登录名Login和数据库级用户User两层都要收。2.1 先摸清现状查登录名、角色和认证模式动手之前先做资产盘点别上来就改。下面这段查询把服务器级登录名、是否启用、认证类型、所属服务器角色一次性拉出来。-- 盘点服务器级登录名及其角色归属 SELECT sp.name AS login_name, sp.type_desc AS login_type, sp.is_disabled AS disabled, sp.create_date, sp.modify_date, STRING_AGG(rp.name, ,) AS server_roles FROM sys.server_principals sp LEFT JOIN sys.server_role_members srm ON sp.principal_id srm.member_principal_id LEFT JOIN sys.server_principals rp ON srm.role_principal_id rp.principal_id WHERE sp.type IN (S,U,G) -- SSQL登录, UWindows登录, GWindows组 AND sp.name NOT LIKE ##% -- 排除系统内部主体 GROUP BY sp.name, sp.type_desc, sp.is_disabled, sp.create_date, sp.modify_date ORDER BY sp.is_disabled, sp.name;逻辑说明sys.server_principals是服务器级主体的主表type过滤掉证书、非对称密钥等非登录主体。STRING_AGG把角色拼成一行方便一眼看出谁挂了 sysadmin。参数上注意sp.name NOT LIKE ##%##开头的是复制、CDC 等内部主体误删会出问题。认证模式用这条查-- 查看当前认证模式1仅Windows, 0混合模式 SELECT SERVERPROPERTY(IsIntegratedSecurityOnly) AS windows_only_auth;返回 0 就是混合模式意味着 SQL 登录名可以密码登录风险面更大。如果业务不依赖 SQL 登录应切到仅 Windows 认证切之前必须确认没有应用在用 SQL 账号否则直接断业务。2.2 禁用 sa 与清理多余 sysadminsa 是内置最高权限账号加固规范里默认要求禁用。但禁用前先确认没有作业、链接服务器、应用连接串在用 sa。-- 禁用 sa先确认无依赖 ALTER LOGIN [sa] DISABLE; -- 重命名 sa 降低可猜测性可选部分合规要求 ALTER LOGIN [sa] WITH NAME [svc_legacy_admin]; -- 查所有 sysadmin 成员逐个确认必要性 SELECT p.name AS sysadmin_member FROM sys.server_role_members m JOIN sys.server_principals r ON m.role_principal_id r.principal_id JOIN sys.server_principals p ON m.member_principal_id p.principal_id WHERE r.name sysadmin;逻辑说明ALTER LOGIN ... DISABLE只禁用不删除保留可回滚的后悔药。重命名 sa 前要评估某些老应用的连接串硬编码了 sa改名会直接连不上。sysadmin 成员控制在 2 个以内多出来的用ALTER SERVER ROLE sysadmin DROP MEMBER [xxx]移除移除前确认该账号没有正在跑的作业。2.3 按业务建最小权限账号应用连接库不应该用 db_owner更不该用 sysadmin。正确做法是按「只读」「读写」「只执行存储过程」三类建账号。-- 建一个只读业务账号 CREATE LOGIN [app_readonly] WITH PASSWORD N强密码, CHECK_POLICY ON, -- 启用密码策略 CHECK_EXPIRATION OFF, -- 服务账号不过期 DEFAULT_DATABASE [BizDB]; USE [BizDB]; CREATE USER [app_readonly] FOR LOGIN [app_readonly]; ALTER ROLE [db_datareader] ADD MEMBER [app_readonly]; -- 显式拒绝写操作双保险 DENY INSERT, UPDATE, DELETE, ALTER ON SCHEMA::dbo TO [app_readonly];逻辑说明CHECK_POLICY ON让密码受 Windows 密码复杂度约束服务账号用CHECK_EXPIRATION OFF避免到期断连。DENY是显式拒绝优先级高于角色授予即使误加了 db_datawriter 也写不进去。参数上DEFAULT_DATABASE要指向业务库避免登录后落到 master。3. 网络与实例暴露面把 1433 关进该在的边界账号收完了下一步是网络。Sql Server 默认监听 1433很多实例直接暴露在内网大网段甚至公网这是最容易被扫到的入口。3.1 确认监听地址与端口先看实例到底监听在哪。-- 查看当前实例的监听端点 SELECT ec.name AS endpoint_name, ec.protocol_desc, ec.is_admin_endpoint, ec.port, ec.is_encryption_enabled, ec.encryption_algorithm_desc FROM sys.tcp_endpoints ec WHERE ec.type_desc TSQL;逻辑说明sys.tcp_endpoints里port是实际监听端口is_encryption_enabled反映是否强制加密。如果port是 1433 且实例在公网可达必须处理。改端口不是安全手段扫描器照样能发现真正的边界是防火墙和网络隔离。3.2 用防火墙规则限定来源Windows 防火墙按来源网段放行比改端口有效得多。# 只允许应用服务器网段访问 1433 New-NetFirewallRule -DisplayName SQL-1433-AppSubnet -Direction Inbound -Protocol TCP -LocalPort 1433 -RemoteAddress 10.20.30.0/24 -Action Allow # 显式拒绝其他来源放在允许规则之后优先级靠拒绝 New-NetFirewallRule -DisplayName SQL-1433-DenyAll -Direction Inbound -Protocol TCP -LocalPort 1433 -RemoteAddress Any -Action Block逻辑说明Windows 防火墙对入站规则是「显式拒绝优先于允许」所以拒绝规则要谨慎正确顺序是先允许特定网段再拒绝其余。RemoteAddress支持 CIDR多个网段用逗号分隔。参数上-LocalPort要和实例实际端口一致命名实例可能是动态端口得先在配置管理器里固定。3.3 强制加密与隐藏实例的取舍传输加密能防内网嗅探但会带来证书维护成本。-- 查看是否强制加密 SELECT SERVERPROPERTY(IsIntegratedSecurityOnly) AS win_auth, CASE WHEN EXISTS ( SELECT 1 FROM sys.dm_exec_connections WHERE encrypt_option TRUE ) THEN 有加密连接 ELSE 无加密连接 END AS enc_status;逻辑说明强制加密要在配置管理器里导入证书并勾选 Force Encryption重启实例生效。自签证书客户端要信任否则连接报证书链错误。隐藏实例Hide Instance只对 SQL Browser 广播有效直连端口照样能连别把它当安全措施。4. 权限、审计与备份把「谁动了什么」留成证据前两章解决「进不来」这一章解决「进来了能干什么、干了什么、出事能不能恢复」。4.1 用服务器审计记录关键操作Sql Server 自带审计Server Audit比触发器轻量比默认 trace 规范。-- 创建服务器审计落到文件 CREATE SERVER AUDIT [Audit_LoginAndDDL] TO FILE ( FILEPATH ND:\SQLAudit\, MAXSIZE 256 MB, MAX_ROLLOVER_FILES 20, RESERVE_DISK_SPACE OFF ) WITH (QUEUE_DELAY 1000, ON_FAILURE CONTINUE); ALTER SERVER AUDIT [Audit_LoginAndDDL] WITH (STATE ON); -- 审计登录失败与权限变更 CREATE SERVER AUDIT SPECIFICATION [AuditSpec_Login] FOR SERVER AUDIT [Audit_LoginAndDDL] ADD (FAILED_LOGIN_GROUP), ADD (SUCCESSFUL_LOGIN_GROUP), ADD (SERVER_ROLE_MEMBER_CHANGE_GROUP), ADD (DATABASE_OBJECT_PERMISSION_CHANGE_GROUP) WITH (STATE ON);逻辑说明QUEUE_DELAY 1000表示最多延迟 1 秒落盘兼顾性能与实时性ON_FAILURE CONTINUE表示审计写不进去也不停库生产环境一般选 CONTINUE合规要求严格的选 SHUTDOWN。FAILED_LOGIN_GROUP是排查暴力破解的关键SERVER_ROLE_MEMBER_CHANGE_GROUP能抓到谁偷偷加了 sysadmin。审计文件目录要给 SQL 服务账号写权限否则审计起不来。4.2 备份加密与权限隔离备份文件是整库数据的副本权限必须比数据库本身更严。-- 创建主密钥和证书用于备份加密 USE master; CREATE MASTER KEY ENCRYPTION BY PASSWORD N强密码; CREATE CERTIFICATE [BackupCert] WITH SUBJECT NBackup Encryption Cert; -- 加密备份 BACKUP DATABASE [BizDB] TO DISK NE:\Backup\BizDB_full.bak WITH INIT, COMPRESSION, ENCRYPTION (ALGORITHM AES_256, SERVER CERTIFICATE [BackupCert]), STATS 10;逻辑说明ENCRYPTION子句要求先有证书证书又依赖主密钥主密钥密码丢了备份就解不开必须单独保管。COMPRESSION减小体积但增加 CPU备份窗口紧张时权衡。备份目录的 NTFS 权限只给 SQL 服务账号和备份管理员去掉 Everyone 和 Users。4.3 权限回收的检查清单加固不是一次性动作下面这张表是我每次复查时逐项过的。检查项期望状态查询入口sa 账号已禁用或已重命名sys.server_principalssysadmin 成员不超过 2 个sys.server_role_members混合认证非必要则关闭SERVERPROPERTY1433 暴露仅限应用网段防火墙规则审计登录失败权限变更已开sys.server_audit_specifications备份加密敏感库已加密备份语句带 ENCRYPTIONpublic 角色权限无多余授予sys.database_permissions5. 加固避坑五条血泪经验这一章全是踩过的坑每条按现象、原因、解决写。现象禁用 sa 后某个夜间批处理作业失败。原因作业的 owner 是 sa禁用后作业执行上下文失效。解决先把作业 owner 改成专用服务账号再禁用 sa。查作业 owner 用SELECT name, SUSER_SNAME(owner_sid) FROM msdb.dbo.sysjobs;。现象开了审计后实例 CPU 明显上升。原因审计规格里加了过多高频事件比如每一条 SELECT 都记。解决只审计登录、DDL、权限变更这类低频高价值事件别审计 DML。QUEUE_DELAY从 0 调到 1000 也能降负载。现象强制加密后老应用连不上报证书链错误。原因自签证书没导入客户端信任库。解决要么把证书链分发到客户端要么对纯内网可信网段暂不强制加密用防火墙隔离替代。别为了加密把业务搞挂。现象备份加密后换服务器恢复失败。原因证书和主密钥没一起迁移新实例没有对应私钥。解决备份证书用BACKUP CERTIFICATE ... TO FILE导出连同主密钥密码一起归档到独立的密钥管理系统恢复前先还原证书。现象改了端口以为安全了结果还是被扫到。原因端口扫描是全端口扫的改端口只是增加一点噪音不构成边界。解决真正的边界是防火墙白名单加网络分区端口改动只作为辅助。6. 用脚本把加固做成可重复的基线手工敲一遍命令只能管一台几十台实例靠人肉迟早翻车。我的习惯是把上面所有检查项写成一个幂等的 PowerShell 加 T-SQL 脚本包每次新实例上线跑一遍定期复查再跑一遍。核心思路是「检测-修复-验证」三段式。检测段只读输出当前状态修复段按参数决定是否执行验证段重新查一遍确认生效。下面是一个检测段的骨架用Invoke-Sqlcmd批量跑。# 批量检测多实例的加固基线状态 $instances (SQLNODE01,SQLNODE02,SQLNODE03) $checkSql SELECT SERVERPROPERTY(ServerName) AS instance_name, SERVERPROPERTY(IsIntegratedSecurityOnly) AS win_only_auth, (SELECT COUNT(*) FROM sys.server_principals WHERE is_disabled 0 AND type S) AS active_sql_logins, (SELECT COUNT(*) FROM sys.server_role_members m JOIN sys.server_principals r ON m.role_principal_id r.principal_id WHERE r.name sysadmin) AS sysadmin_count; foreach ($inst in $instances) { try { $result Invoke-Sqlcmd -ServerInstance $inst -Query $checkSql -TrustServerCertificate -ErrorAction Stop # 判定混合认证或 sysadmin 超 2 个即标记不合规 $status if ($result.win_only_auth -eq 0 -or $result.sysadmin_count -gt 2) { FAIL } else { PASS } [PSCustomObject]{ Instance $inst WinOnlyAuth $result.win_only_auth SysadminCount $result.sysadmin_count Status $status } } catch { [PSCustomObject]{ Instance $inst Status ERROR: $($_.Exception.Message) } } }逻辑说明Invoke-Sqlcmd的-TrustServerCertificate在自签证书环境下必须加否则连不上。try/catch保证单台失败不影响整批。判定逻辑里win_only_auth -eq 0表示混合认证标记 FAIL。这个骨架可以扩展成读配置文件、输出 CSV 报告、对接工单系统。参数上要注意批量跑时用只读账号别用 sysadmin避免脚本本身成为风险点。-Query里的查询要加WITH (NOLOCK)吗系统视图不需要加了反而可能读到不一致的元数据。进阶一点的做法是把基线规则外置成 JSON脚本读规则再执行这样不同业务线可以用不同基线不用改脚本。验证方法很简单故意在一台测试实例上把 sa 启用、加一个 sysadmin跑脚本应该报 FAIL改回去应该报 PASS。这个正反测试是脚本可信的前提别跳过。我自己的教训是第一版脚本只做了检测没做验证结果修复段有个ALTER LOGIN写错了库跑完看着是 PASS 实际没生效过了两个月审计才发现。从那以后我坚持每段修复后面必须跟一段验证查询眼见为实。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑