先交代下背景。不管你是跑办公网络的运维,还是自己搭Windows服务器做项目的独立开发者,安全加固这种事都有点像买保险——没出事的时候觉得多余,真被攻击了才后悔当初没做。Windows安全加固策略并不是只有安全公司才需要研究的东西,它其实就是一套可操作的系统配置方法,在不显著影响业务的前提下,把账号、端口、补丁、日志这些暴露面尽量收小。我这几年配合做过不少Windows主机的安全整改,也踩过不少因为加固太猛反而把自己锁在门外的坑,这篇文章就按最常用的实施顺序,把基本策略整理出来,适合刚入门的运维和安全工程师参考,也适合想把手头Windows环境打牢的老手当作清单对照。
不过先说清楚,安全加固没有一劳永逸的做法。下面这些内容面向的是常见的Windows客户端和Server系统,覆盖的是“基础中的基础”,不是把系统搞成保险柜,而是先做到及格线——这及格线一旦做到,你就能挡住大多数扫描器、弱口令爆破和勒索病毒入口。
1. 账号策略与登录入口收敛
绝大多数Windows机器被入侵,绕不开账号密码问题。很多人习惯装完系统就扔在那,密码简单不说,Guest客人账户还开着,Administrator也不改名字,等于把前门钥匙挂在门口。账号这一层如果不处理,后面防火墙规则再漂亮,人家正门一推就进来了。
1.1 密码策略强制落地
Windows默认的密码策略其实很弱,默认情况下连密码长度限制都是跟具体版本走的,有时8位就够,而且很多人喜欢用Admin123、P@ssw0rd这种一眼就能猜出来的组合。我一般建议把密码策略提到至少12到14位,同时启用“密码必须符合复杂性要求”和“强制密码历史”选项。
操作入口有两个地方。一个是图形界面的secpol.msc,依次展开“账户策略 -> 密码策略”,在里面把最小密码长度、密码最长使用期限、强制密码历史都改掉。另一个是命令行,适合批量执行,比如:
net accounts /minpwlen:14 /maxpwage:90 /minpwage:1 /uniquepw:5这几个参数的含义分别是:最小密码长度14位、密码最长使用90天、密码最短使用1天(防止用户立刻改回旧密码)、强制密码历史为5(也就是最近5次用过的密码不能重复)。
这里有个细节容易被忽略:maxpwage如果设置成0,代表密码永不过期,这个一般不建议在生产环境用。除非是特殊情况,比如某些服务账户无法轮换密码,才允许例外。运维人员自己的高权限账户,还是老老实实设90天甚至60天。
1.2 账户锁定策略与暴力破解对抗
暴力破解是Windows远程登录最常见的一类攻击,RDP端口暴露在公网后,短则几小时就可能被脚本扫描出弱口令。账户锁定策略就是为了拖慢这种攻击节奏——连续输错几次就锁账号,攻击者就算字典再大也难继续试。
同样在secpol.msc里,找到“账户锁定策略”。我通常设置为“账户锁定阈值”5次、“锁定时间”30分钟、“重置账户锁定计数器”30分钟。如果用命令行,效果没那么直观,但在PowerShell里可以这样改:
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" -Name "MaximumLockoutThreshold" -Value 5 Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Netlogon\Parameters" -Name "LockoutDuration" -Value 30需要注意,账户锁定策略是把双刃剑。一旦设置不当,正常用户连续输错几次也可能被锁,运维人员又没有备用通道,结果就是把自己锁在外面。所以我的经验是:服务器上阈值可以稍微放宽一点,比如10次,但一定要配合强密码;普通办公电脑可以严格一些,5次比较合理。
提示:不要把内置Administrator账户纳入自动锁定范围,或者至少要保留带外管理手段。攻击者可以通过反复尝试登录触发锁定,造成合法管理员无法登录,这是一种变相的DoS攻击。
1.3 禁用Guest,重命名Administrator,限制空密码远程登录
Guest账户在历史Windows版本里经常成为匿名访问的入口,现在默认虽然是禁用,但装机完最好检查一遍,尤其是一些精简版系统容易把这个账户留开。禁用命令很简单:
net user guest /active:noAdministrator账户更值得处理。改名不能完全防住高手,但能极大减少自动化工具的攻击面。我一般的做法是:把Administrator重命名为一个不长不短、不好猜的名字,比如ADM-Wang,然后再新建一个普通名Administrator的低权限账户并禁用,用来当蜜罐。这样扫描器爆破“Administrator”这个名字时,打的是一个不存在的账户。
同时,建议把“拒绝从网络访问此计算机”这个用户权限里加上Guest和本地账户,尤其是域环境下,防止一台被攻陷的工作站通过本地账号横向访问其他机器。在secpol.msc -> 用户权限分配里可以找到这个策略,默认只有Administrators组,但审计时经常发现Everyone、Users也挂在里面,这种都要踢掉。
2. 系统补丁与内置防护机制
账号策略只是第一步,系统自身有没有漏洞也直接决定能不能被打穿。Windows的安全补丁、Defender、PowerShell日志这些内置机制,如果不利用起来,等于车载安全气囊当成摆设。
2.1 把补丁放到运维流程里
Windows Update是很多人讨厌的东西,因为重启会打断工作。但从安全角度看,不更新补丁比弹窗麻烦一百倍。尤其是可被远程利用的漏洞,补丁一旦发布,攻击者会迅速反编译并制作利用工具,打补丁慢一步就很被动。
所以基本策略是:客户端保持自动安装更新;服务器尽量用WSUS或者手动控制补丁安装时间,但时间最长不要超过一个月一次。每月第二个星期二是微软固定补丁日,之后的三到五天是观察期,等补丁没爆出严重兼容问题,再分批往生产环境推。
查看当前已安装补丁可以用:
Get-HotFix | Sort-Object InstalledOn -Descending | Select-Object -First 10关键漏洞补丁、特别是打了标记为“Critical”的远程代码执行补丁,优先安排。如果线上确实不能重启,至少要确保系统在防火墙层不允许外部直接访问对应服务,同时用网络隔离的手段先兜底。
2.2 Windows Defender不是摆设,ASR规则值得开
说实话,以前我也觉得系统自带杀毒是“够用但不好使”,但这几年Windows Defender的检测能力进步很明显,在日常办公场景下足够当主力。前提是你不要把Defender禁用或者手动装上第三方杀软后又不起作用——两个杀毒软件同时常驻,反而容易冲突,防御效果不见得更好。
检查Defender状态:
Get-MpComputerStatus | Select-Object AntivirusEnabled, RealTimeProtectionEnabled如果状态显示都是True,说明实时保护在跑。接着建议开启云交付保护、自动提交样本等功能。在Windows安全中心里都能设置,也可以在PowerShell里操作:
Set-MpPreference -MAPSReporting Advanced Set-MpPreference -SubmitSamplesConsent Always更进阶一点的是攻击面减少规则(ASR规则),它能在行为层面拦截常见的攻击手法,比如阻止Office程序创建子进程、阻止Excel或PowerPoint调用其他程序、阻止从网络共享中执行不信任的可执行文件。这些规则通过组策略或Intune下发最方便,本地单机也可以修改注册表策略,但需要对规则ID有一点了解。
我实际操作中的建议是:先开“审核模式”跑一到两周,观察业务软件有没有被误拦,再改成“启用”。ASR不是为了给Microsoft Defender用的,它是给攻击者制造障碍的,误报肯定会有,直接全开容易让办公软件没法干活。
2.3 PowerShell安全基线
PowerShell是运维利器,也是攻击者最喜欢用的横向工具。很多勒索病毒和APT攻击的最后一步都是通过PowerShell执行恶意脚本。所以Windows安全加固应该包含PowerShell本身的策略配置。
最基础的是执行策略。很多人直接设成Unrestricted,图省事,但带来的风险是任何脚本都能跑。我建议设成RemoteSigned,本地脚本允许执行,但来自网络的脚本必须有可信签名:
Set-ExecutionPolicy RemoteSigned -Scope LocalMachine只设执行策略还不够,因为攻击者可以用-ExecutionPolicy Bypass之类的参数绕过。真正有价值的是把PowerShell日志打开,尤其是“脚本块日志”和“模块日志”。一旦开启,攻击者执行的每条PowerShell命令,都会在“Microsoft-Windows-PowerShell/Operational”事件日志里留下痕迹。这是应急响应时最重要的线索来源之一。
用注册表开脚本块日志:
reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows\PowerShell\ScriptBlockLogging" /v EnableScriptBlockLogging /t REG_DWORD /d 1 /f再配合用户登录后的PowerShell历史记录、ConsoleHost历史文件等,即使系统已经被入侵,至少能还原出攻击者的操作轨迹,不会两眼一抹黑。
3. 端口、服务与远程接入加固
很多Windows服务器被入侵,不是因为系统密码弱,而是因为暴露了不该暴露的服务。尤其是445端口、3389端口,常年被蠕虫和爆破工具针对。这个环节的核心思路是:减少监听端口、减少开放服务、最小化防火墙放行规则。
3.1 高危端口与服务清单
先用一条命令快速看当前系统开放了哪些端口:
netstat -ano | findstr LISTENING或者用PowerShell看得更清楚:
Get-NetTCPConnection -State Listen | Select-Object LocalAddress, LocalPort, OwningProcess对照这份清单做一轮检查和收敛:
| 端口 | 典型服务 | 风险说明 | 处理建议 |
|---|---|---|---|
| 135 | RPC Endpoint Mapper | 常被用于远程调用和漏洞利用 | 非必要不对外暴露,如需内网使用也要限制来源 |
| 137-139 | NetBIOS Session | 历史遗留协议,蠕虫扩散渠道 | 可禁用,尤其面向公网时 |
| 445 | SMB文件共享 | 勒索病毒重点攻击入口 | 外网坚决封堵,内网按需放行并禁用SMBv1 |
| 3389 | RDP远程桌面 | 弱口令爆破重灾区 | 不直接暴露公网,启用NLA,限制来源IP |
| 1433 | SQL Server | 数据库协议,易被撞库 | 非业务需要不监听公网,使用Windows认证或强口令 |
| 5985/5986 | WinRM | 远程管理通道,配置不当可被滥用 | 仅限受信管理员网络使用 |
实际加固时,一项一项来。最优先处理的是SMBv1。如果你查出来系统里还开着SMBv1,建议直接禁用:
Disable-WindowsOptionalFeature -Online -FeatureName SMB1Protocol禁用后需要重启。这里要提示老人们常用的网络共享、打印机共享,如果旁边还有旧设备依赖SMBv1,会出现无法访问的情况。所以操作前先在测试机验证一下。
3.2 Windows防火墙默认拒绝
防火墙不是装个杀毒软件自带的功能,Windows自带的防火墙完全可以承担主要边界策略。关键在于你有没有把默认入站行为改成“拒绝”,而不是靠一条条添加拒绝规则。
先启用所有配置文件的防火墙:
netsh advfirewall set allprofiles state on默认的入站连接策略应该是“阻止”。在wf.msc里能看到“Windows Defender 防火墙属性”,把“域配置文件”、“专用配置文件”、“公用配置文件”里的入站连接都设为“阻止(默认值)”。这样即便某个服务忘了关,外部也无法直接连进来。
然后添加允许规则,遵循“最小化放行”原则。例如我只允许内网某个管理网段访问这台服务器的RDP:
netsh advfirewall firewall add rule name="RDP-Allow-Office" dir=in action=allow protocol=TCP localport=3389 remoteip=192.168.10.0/24注意:凡是修改防火墙规则,务必先确认有一条放行远程管理流量的规则存在,并且你自己的IP在允许范围内。否则规则一生效,你连当前远程会话都保不住。
图形界面里创建规则更容易理解和维护。我习惯新建一个自定义规则组,专门放“运维管理端口”,例如RDP、SSH、WinRM等,规则名前缀统一,方便排错时一眼认出来。
3.3 远程桌面(RDP)的专门加固
RDP是最常被爆破的服务,所以单独拿出来说。网上很多人建议“修改默认3389端口”来防扫描,这个有一定效果,但记住它只是增加扫描成本,不是真正的安全措施。更重要的其实是下面三件事。
第一,启用网络级别身份验证(NLA)。NLA的意思是在建立完整远程桌面会话之前,先完成用户身份验证,这样可以减少一些中间人攻击和恶意会话建立。
在“系统属性 -> 远程”里勾选“仅允许运行使用网络级别身份验证的远程桌面的计算机连接”。命令行的确认方式:
Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" -Name UserAuthentication | Select-Object UserAuthentication如果值是1,说明NLA已开启。
第二,限制远程桌面用户组。默认情况下,本地Administrators组成员都可以登录RDP。如果不是必要,尽量把运营维护人员都放到“Remote Desktop Users”组,并单独控制管理员账号的登录权限。在组策略里可以设置“允许通过远程桌面服务登录”,只添加指定用户或组。
第三,不要把RDP直接暴露在公网。有条件的话,放到跳板机或堡垒机后面,由运维人员先登录跳板机,再通过内网访问目标服务器。这样攻击者看到的只是跳板机的IP,连真正内网IP都扫不到。这个思路比任何端口修改都更有效。
4. 日志审计与安全基线落地
前几部分都是“提前防守”,日志审计则是打持久战。真出现安全问题,没有日志就全是瞎猜。Windows自己的安全日志如果配置得当,已经能覆盖大多数关键事件,关键是很多人从装完系统就没打开过审核策略。
4.1 开启关键审核策略
Windows默认的审核策略只记录很少的内容,必须手动把关键分类打开。推荐最低限度开启:
- 账户登录事件:记录用户本地或远程登录系统,尤其是失败事件。
- 账户管理:记录创建用户、修改密码、修改组等操作。
- 登录/注销:记录每次登录、注销、RDP连接等。
- 策略更改:记录安全策略改动。
- 系统事件:记录系统关闭、重启、崩溃等。
用PowerShell打开比较方便(子类别名称可能需要按系统语言调整):
auditpol /set /subcategory:"登录/注销" /success:enable /failure:enable auditpol /set /subcategory:"账户管理" /success:enable /failure:enable auditpol /set /subcategory:"策略更改" /success:enable /failure:enable auditpol /set /subcategory:"系统事件" /success:enable /failure:enable如果是图形界面,secpol.msc -> 安全设置 -> 本地策略 -> 审核策略里也可以在“属性”里全勾上。
开启后,登录失败产生的事件ID 4625,账户登录成功对应4624,账户锁定对应4740。这些ID在应急响应时非常常用。Windows安全日志不是只有安全事件,也有应用、系统日志,但安全日志优先级最高。
4.2 日志大小、覆盖策略与集中收集
很多人都漏掉这一步:审核策略开了,但事件日志默认只有20MB大小,很快就被填满,后来的日志直接被丢弃,等于白开。所以我建议把安全日志大小调整到至少1GB,并设为“按需覆盖事件”(也就是覆盖旧事件)。
命令行调整安全日志大小到1GB:
wevtutil sl Security /ms:1073741824顺便也把PowerShell操作日志调大一点:
wevtutil sl "Microsoft-Windows-PowerShell/Operational" /ms:1073741824如果环境允许,尽量把安全日志集中收集起来,比如通过Windows事件转发或商业SIEM。集中收集的意义在于,就算单台机器被格式化或者日志被清掉,远端还有一份完整的原始证据。单机环境下,至少也要做定期导出备份,日志文件放在独立磁盘或异地目录里。
4.3 基础检查脚本与安全基线落地
光说不练不行,安全加固的落地一定要有一个基线清单。建议参考CIS Benchmark里的Windows基线,但不要生搬硬套,按你业务能接受的强度选择。常用的做法是准备一份Excel检查表,每月跑一遍,核对下面这些项目:
| 检查项 | 期望值 |
|---|---|
| 密码策略 | 最小长度>=14,复杂性启用,强制历史>=5 |
| 账户锁定策略 | 阈值<=10次 |
| Guest账户 | 禁用 |
| 防火墙状态 | 所有配置文件开启,入站默认阻止 |
| 自动更新 | 已启用并安装最新补丁 |
| SMBv1 | 已禁用 |
| RDP NLA | 已启用 |
| 安全日志审核策略 | 关键类别已开启 |
| 安全日志大小 | >=1GB |
逐项检查可以用PowerShell写个小函数自动化,但不用一步到位。先把检查清单打印出来,手动对照一遍,你就能对当前环境的安全状态心里有数。后面再逐步把清单脚本化,我这边也是从一个月一次手工核对,慢慢改成每周自动出报告的。
5. 加固后的常见坑与巡检建议
安全加固有一个非常典型的现象:改配置的时候觉得自己很稳,改完业务挂了,然后又急着回滚。这一章专门把常见坑列出来,都是我自己或同事实际踩过的,提前避雷。
5.1 加固把自己“锁在外面”的经典场景
先说最容易翻车的防火墙。很多人先执行了“入站默认拒绝”,然后忘记添加RDP放行规则,手一抖,远程会话断开,再连就连不上。这种问题排查起来也简单,但前提是你还有带外通道,比如物理控制台、IDRAC、IPMI或云平台控制台。所以每次改防火墙前,都得先确认带外通道可用,或者至少保留一条放行规则。
账户锁定阈值设置太严格也是常见坑。有一次同事把阈值设成3次,结果当天下午就有人把管理员密码输错两次,第三个人再输一次错密码,管理员账号直接被锁30分钟,运维电话被打爆。后来我们把阈值改成10次,才平衡了安全和易用性。
修改RDP端口不更新防火墙规则同样会发生,这种一般是在注册表里改了PortNumber,但忘了在防火墙里放行新端口。测试时最好开两个会话,把防火墙规则先加好,再去改注册表,并立刻用新端口测一次连接。
5.2 ASR与杀毒软件误报的处理
Windows Defender的ASR规则误报主要集中在Office宏、脚本执行这类场景。之前给一个财务部门开了“阻止Office创建子进程”的规则,他们用的一个老版Excel插件马上就不能生成PDF了。这种问题不能硬扛,先把对应规则改成“审核模式”,确认是规则问题,再找业务方协调升级插件,或者针对单个进程加白。
处理误报时,不要随便关闭规则本身,最好是添加到排除项。在Set-MpPreference -AttackSurfaceReductionRules_Exclusions里指定进程路径,或者通过组策略推荐的这条规则排除项加白。这样既保留规则覆盖范围,又解决业务兼容性。
5.3 日志越来越大的管理与定期巡检
日志调整到1GB之后,你会发现日志文件膨胀很快,尤其是登录量大的服务器,可能一周就满了。这不是坏事,但要有对应的归档策略。事件查看器自带“日志大小上限”和“保留旧事件”两种模式,我建议保留旧事件但不给过大上限,每周导出一次到指定目录,保留90天。导出命令:
wevtutil epl Security C:\SecurityLogs\security_%date:~0,4%%date:~5,2%%date:~8,2%.evtx日常巡检我一般建议每周看一次。重点看安全日志里有没有大量4625登录失败事件,同一来源IP是不是在扫描,4740账户锁定事件有没有异常频繁出现。如果看到来源IP是外网、源端口很高、数百条失败记录,基本可以确认有人在爆破。这时候第一反应不是去封IP,而是先确认账号有没有真正被突破,再看看防火墙有没有把对应端口暴露出去。
5.4 别忽略系统更新与补丁的兼容性验证
补丁兼容性是另一个高频坑。有些补丁打完之后,老版本数据库驱动、打印机驱动、加密软件会出现异常。我见过最狠的一次是某个安全更新把一台前置机的网络驱动搞挂,业务直接中断两个钟头。
所以即使我前面说补丁很重要,但也不建议拿到更新就闭眼全装。生产环境服务器至少要有一个测试窗口:先在一台预发机器上验证,等一两天确认没问题,再逐台推送。客户端电脑可以通过WSUS分批部署,确保同一批次内最多只有10%到20%的机器同时重启更新,避免业务高峰期大面积断连。
一些实际操作后的体会
我自己经手过几轮Windows安全加固之后,最大的感觉是,基础加固并不需要什么高深工具,大部分策略都是系统自带功能,核心在于“你有没有意识去配置”。账号策略、防火墙默认拒绝、补丁管理、日志审计,这四件事情做完,安全水平就已经超过大多数裸奔主机了。后面再上EDR、蜜罐、态势感知平台,都是在及格线上的加分项。
如果你现在刚开始接触Windows加固,我建议不要一上来就追求把所有安全基线全推下去,那样维护成本太高,也容易引发兼容问题。先从密码策略、账户锁定、防火墙入站默认拒绝、RDP保护、日志审核这几项开始,配完跑一个月,确认业务没受影响,再慢慢扩展到服务最小化、ASR规则、PowerShell日志和集中采集。
最后提醒一句:安全加固永远不是“配完就结束”的静态工作,每过一阵子都要回头看看有没有新增的开放端口、有没有新增的本地管理员、有没有长期不更新的服务。把这当成日常运维的一部分,才能真正让Windows环境长期保持在一个相对安全的状态。