windows防火墙入站规则优先级为:拒绝规则优先于允许规则,显式规则优先于默认规则,具体规则优先于宽泛规则;dnat后目标地址端口须被防火墙显式允许,否则丢包。
业务突然中断,查日志没报错、服务进程正常、端口监听也开着,但外网就是连不上——八成是入站规则优先级“卡”住了。关键不是规则有没有,而是哪条先被匹配到。
先搞清匹配顺序:拒绝规则永远在前
Windows防火墙执行的是“先匹配先执行”,且显式拒绝(Block)规则优先于所有允许(Allow)规则。哪怕你有一百条放行某端口的规则,只要上面压着一条“阻止所有IP访问该端口”的规则,流量就直接被拦掉,后续规则根本不会看。
- 检查现有入站规则中是否存在宽泛的拒绝规则,比如“Block all inbound on port 3389”或“Block any IP not in whitelist”
- 用命令快速定位:netsh advfirewall firewall show rule name=all dir=in | findstr /i "3389.*block\|rdp.*block"
- 特别注意组策略下发的规则——它们优先级高于本地手动创建的规则,可能在GUI里看不到却实际生效
精准规则必须排在宽泛规则前面
比如要只允许192.168.10.5通过RDP访问,同时拒绝其他所有IP。不能先建“允许所有IP访问3389”,再建“拒绝除192.168.10.5外的所有IP”——那样后者永远不生效。正确顺序是:
- 第一条:允许 192.168.10.5 → 3389(TCP,入站)
- 第二条:拒绝 * → 3389(TCP,入站)
- 用wf.msc图形界面右键规则→“上移”调整顺序;或用PowerShell:Set-NetFirewallRule -DisplayName "Allow RDP from Admin" -PolicyStore ActiveStore -Profile Domain,Private,Public -Direction Inbound -Priority 1
别只靠端口,绑定程序或服务更可靠
仅按端口写允许规则风险高:一旦服务换端口(如IIS改用8080)、或别的程序占了同一端口,规则就失效或误放行。推荐用程序路径或系统服务名锁定:
- 对IIS:新建入站规则时选“程序”,路径填%SystemRoot%\system32\inetsrv\w3wp.exe
- 对SQL Server:选“服务”,服务名填MSSQLSERVER或自定义实例名
- 这样即使端口变动,只要服务本身没换,规则仍精准生效
和NAT一起配,DNAT后的地址端口必须显式放行
如果用了Windows NAT(如NetNat或RRAS),外网请求进来的流程是:先DNAT转换目标IP+端口 → 再过防火墙入站检查。很多人只映射了端口,却忘了在防火墙里允许DNAT后的新目标地址和端口。
- 例如:外网访问203.0.113.10:8080被DNAT到192.168.1.100:80,那么防火墙必须有规则允许192.168.1.100:80的入站,而不是允许203.0.113.10:8080
- 临时验证是否是防火墙问题:运行Set-NetFirewallProfile -Profile Domain,Private,Public -Enabled False关闭防火墙(测试完务必恢复)
- 避免混用工具:不要同时用netsh portproxy、RRAS和NetNat,统一用NetNat + 高级防火墙规则











