Windows防火墙规则批量管理:bat与netsh/PowerShell实战
上周帮同事处理一台测试机需求是在系统加固脚本里自动下发一批防火墙规则开放几个业务端口给内网、放行某个采集程序、顺手把几个爱偷偷联网的工具的出站通道掐掉。手工点界面二三十条规则点完还得截图存档换台机器又要重来一遍。这种活儿交给 bat 批处理最合适——写好一份脚本双击运行规则全部落地还能带日志和回滚。这篇就把我用 netsh 和 PowerShell 两套方式管理 Windows 防火墙出入站规则的完整经验拆开讲从字段设计、命名规范到批量下发、幂等处理、排障思路都会覆盖。不管你是刚接触批处理的新手还是天天写运维脚本的老手都能直接抄走一套能跑的东西。1. 从点鼠标到敲命令为什么我坚持用 bat 管防火墙规则1.1 界面操作的三个高频翻车现场先说清楚场景。Windows 自带的高级安全 Windows Defender 防火墙wf.msc当然能用鼠标点几下新建入站规则、选程序、选端口、选允许向导走完就完事。问题在于一旦规则数量超过十条界面的效率就断崖式下跌。第一个坑是重复劳动。同一个系统交付给十个客户每个客户的环境都要开同样的端口、放行同样的程序界面点十遍每遍都可能点错一格。第二个坑是不可追溯。三个月后领导问这台机器上为什么开了 3306你翻不出任何记录界面上只有一条冷冰冰的规则名。第三个坑是易漏项。向导里的域/专用/公用三个勾选框很多人只勾专用笔记本拿到别的网络环境立刻失效然后被投诉规则没生效。批处理解决的正是这三件事一次编写、多次执行、留痕可查。规则名字怎么写、profile 选哪几档、端口开给谁全部固化在脚本里脚本本身就是文档。我现在的习惯是凡是涉及两台以上机器的防火墙配置一律走脚本界面只用来做最终目视确认。还有一点容易被忽略批处理脚本可以纳入版本管理。规则变更就是一次 commit谁在什么时候加了哪条规则diff 一目了然。这套东西跟代码一样管起来排查问题时省下的时间远超写脚本的成本。1.2 netsh 还是 PowerShell两套方案的取舍Windows 上批量下防火墙规则有两条路老牌的netsh advfirewall和后来居上的New-NetFirewallRule。两者最终写的是同一套底层规则库但用起来差别不小。对比维度netsh advfirewallPowerShell NetFirewall 系列系统覆盖Windows 7 起全支持需 PowerShell 3.0Win8/2012 起语法风格空格分隔的 keyvalue参数化 Cmdlet批量循环依赖 for /f 拼字符串原生管道与数组输出解析纯文本受系统语言影响对象化字段稳定中文系统兼容输出中文字段findstr 易踩坑字段名固定英文单文件依赖无系统自带无系统自带我的实际选择是纯 bat 脚本、需要在老系统上跑、或者要嵌进现成的 .bat 工具箱里用netsh如果逻辑复杂到需要条件判断、结果解析、规则比对用 PowerShell 写主逻辑外面包一层 bat 做入口和提权。特别提醒netsh的一个隐性成本它的show rule输出是本地化文本。中文系统打印的是规则名称已启用方向英文系统打印的是 Rule Name、Enabled、Direction。如果你在脚本里用findstr Rule Name去抓字段换到中文机器上直接抓不到。想跨语言环境稳要么统一改用 PowerShell 的Get-NetFirewallRule要么用dirin这类参数化查询而不是去 grep 输出文本。注意netsh advfirewall firewall add rule是对当前运行的系统实时生效的没有预览这一步。脚本写错一个actionblock可能当场把远程桌面掐断。所有涉及 RDP、SSH、数据库端口的脚本先在本地虚拟机跑一遍。2. 动手之前先立规矩规则字段与命名体系2.1 一条规则由哪些字段决定生死写脚本之前得先把规则的组织方式想清楚。一条防火墙规则决定它行为的就是下面这几个字段任何一个写错结果都不是有点偏差而是完全不通或者完全敞开。方向dirin是入站out是出站。注意方向是相对本机而言的——别人连你的 3389 是入站你的程序去连别人是出站。动作actionallow放行、block阻止、bypass绕过用于 IPSec 场景日常基本用不到。协议protocolTCP、UDP、ICMPv4、ICMPv6、any也可以写数字协议号。开了 TCP 端口别忘了 UDPDNS、部分游戏联机、流媒体都走 UDP只开 TCP 经常出现能连上但卡的怪现象。端口localport / remoteport本机监听的口用localport主动去连对端的口用remoteport。写多个用逗号分隔写范围用连字符比如localport8000-8010。程序program指定具体 exe 路径。一旦指定了 program这条规则就跟路径绑死了。地址localip / remoteip限制通信双方的 IP。可以写单个地址、CIDR 网段、localsubnet本地子网、any。配置文件profiledomain、private、public、any。这是最容易出错的一个。启用状态enableyes/no。no的规则是存着但不生效做灰度切换很有用。一个典型的流媒体端口开放写成这样netsh advfirewall firewall add rule nameApp-Live-TCP-8080-In dirin actionallow protocolTCP localport8080 profileanyprofileany是重点。它的意思是这条规则在域、专用、公用三种网络配置下都生效。对固定机房里的服务器来说写any没多大风险但对笔记本写any就意味着插到咖啡厅的公共网络上这条规则照样开门安全边界要自己掂量。2.2 命名与分组三个月后你还认得它吗规则名name是这个脚本体系里最不起眼、但最影响长期维护的字段。我见过太多机器上散落着 New Rule 1、端口规则、test 这种名字半年后谁也不敢删因为不知道删掉会断什么业务。我的命名约定是三段式业务模块-协议-端口-方向。比如OA-Web-TCP-443-In、Collector-Agent-Out、Block-AutoUpdate-Out。一眼能看出是谁的、干什么的、什么方向。对批量生成的规则用统一的模块前缀比如全部以Deploy2024-打头后续要整体清理一条findstr或者按前缀删除就能收尾。比名字更好用的是分组group。netsh和 PowerShell 都支持给规则打 group 标记同一组规则可以整组启停netsh advfirewall firewall add rule nameOA-Web-TCP-443-In dirin actionallow protocolTCP localport443 profileany groupOA-System这样后续想临时关掉整套 OA 的放行规则不用一条条找netsh advfirewall firewall set rule groupOA-System new enableno规则命名里还有个小细节尽量别用中文和空格。中文在某些代码页下会变成乱码空格会让后续按名字查询、删除时到处加引号。真要用中文名在 PowerShell 里操作会比 netsh 稳一些netsh 在 GBK 环境下对中文名的处理偶尔会出现匹配不上的情况。提示给规则打 group 的成本几乎为零但收益是后期运维效率的成倍提升。哪怕只写五条规则也建议顺手加个 group。3. 入站规则实操开端口、放行程序、限来源网段3.1 开端口的最小可用写法与 profile 选择入站规则最常见的形态就是开端口。最精简的写法前面已经给过这里把容易忽略的参数补全。第一个是enableyes。不加也能生效因为默认就是启用但如果脚本要兼顾预置但不启用的场景显式写出来更清楚。第二个是edgeyes。这个参数专治从外网访问内网服务器不通的情况。当你的机器处在 NAT 设备后面外部流量要穿过 NAT 才能到达Windows 防火墙默认会丢弃这类边缘遍历流量。开了edgeyes才允许。注意开edge是有安全代价的它等于把这台机器的端口暴露给 NAT 外侧公共网络上不要随手开。第三个是interfacetype。如果你的服务器有多个网卡一个对内一个对外可以用interfacetypelan把规则限制在局域网网卡上避免规则在对外网卡上意外生效。可选值有lan、wireless、ras、any。关于 profile我给一套自己的判断标准机房固定服务器、多网卡、网络类型稳定写profileany省得因为网络类型漂移导致规则失效。办公笔记本、会移动的设备优先domain,private只在确实需要时加public。对外发布的测试服务明确写public让规则的作用域在脚本里可见。写多档 profile 的语法是逗号分隔netsh advfirewall firewall add rule nameDev-Service-TCP-8080-In dirin actionallow protocolTCP localport8080 profiledomain,private3.2 程序放行与来源 IP 白名单按程序放行比按端口放行更精确。端口是被所有程序共用的你开了 8080任何程序在 8080 上监听都会自动获得放行而按 program 指定只有那个 exe 能用。netsh advfirewall firewall add rule nameCollector-Agent-In dirin actionallow programC:\Tools\Collector\agent.exe enableyes profileany不加protocol参数时默认是any也就是这个程序的 TCP、UDP、ICMP 全放行。如果只想放 TCP就补上protocolTCP。来源 IP 限制是入站规则里性价比最高的加固手段。运维平台上那些只有跳板机能访问的管理端口靠的就是这个netsh advfirewall firewall add rule nameMgmt-SSH-TCP-22-In dirin actionallow protocolTCP localport22 remoteip192.168.10.0/24,10.20.30.15 profileanyremoteip支持单个地址、CIDR 网段、逗号分隔的列表也支持localsubnet关键字代表本地子网。这里有个必须知道的坑当你指定了 IPv4 格式的 remoteip这条规则通常只匹配 IPv4 流量IPv6 方向可能出现规则外的空隙。对 allow 规则来说就是别人走 IPv6 连不上对 block 规则来说就是对方走 IPv6 依然能连出去。屏蔽类规则千万不要加 remoteip 限制。3.3 按服务名放行的适用场景还有一种少用但偶尔救命的写法service。某些系统服务以共享进程方式运行典型的是 svchost 承载的一堆服务按 exe 放行会把整个 svchost 都放出去粒度太粗。这时候可以按服务短名放行netsh advfirewall firewall add rule nameWinRM-Service-In dirin actionallow serviceWinRM protocolTCP localport5985 profileany服务短名可以用sc query type service state all或者Get-Service | Select-Object Name查。这个参数的坑在于服务名拼错时规则能加进去但永远不生效而且不报错。加完记得用show rule确认一下或者直接实测。在实际项目里我一般不建议用service除非确认该服务的宿主进程是独占的。粒度控制可以用程序放行 来源网段限制组合来替代更直观也更容易排查。实操心得写 allow 规则前先跑一遍netsh advfirewall firewall show rule nameall | findstr /i 8080确认没有历史遗留的同类规则。Windows 防火墙里重复的 allow 规则不会报错但会让你搞不清哪条在起作用。4. 出站规则实操把某个 exe 的联网通道掐掉4.1 出站默认放行所以 block 规则天生有优势Windows 防火墙的默认策略是阻止入站、允许出站。很多人第一次做出站限制时会困惑我加了一条 block怎么程序还能联网原因在于规则的优先级判定大致有这么几条更具体的规则优先于更宽泛的规则同样是具体规则时block 优先于 allow。所以一条针对某 exe 的 block 出站规则会压过系统内置的全部出站 allow默认策略直接把它按住。这也是为什么出站拦截能生效不需要去改默认策略。顺便纠正一个流传很广的做法不要为了屏蔽一个程序去把所有出站连接改成阻止。那条命令是netsh advfirewall set allprofiles firewallpolicy blockinbound,allowoutbound第二个参数一旦改成blockoutbound本机所有出站流量都得靠白名单放行DNS、时间同步、系统更新全部跟着挂。除非你在做严格的终端白名单管控否则不要碰。4.2 屏蔽一个程序的完整两条规则回到正题。要真正把一个 exe 的联网通道掐干净一条规则不够得两条netsh advfirewall firewall add rule nameBlock-Acrobat-Out-TCP dirout actionblock programC:\Program Files\Adobe\Acrobat\Acrobat.exe protocolTCP profileany netsh advfirewall firewall add rule nameBlock-Acrobat-Out-UDP dirout actionblock programC:\Program Files\Adobe\Acrobat\Acrobat.exe protocolUDP profileany为什么必须分开写 TCP 和 UDP因为protocolany的 block 规则在一些较早的 Windows 版本上对 UDP 的处理并不一致实测下来分两条最稳妥。如果你的环境比较新也可以试试protocolany合一条然后用netstat -ano | findstr PID验证是否还有残留连接。写这种规则有三个注意点。第一路径必须和实际运行的 exe 完全一致。程序被更新到新版本后安装目录变了尤其是带版本号子目录的软件规则会静默失效——规则还在但绑的是旧路径。所以脚本里最好把路径抽成变量升级后改一处。第二不要加 remoteip 限制前面说过加了之后 IPv6 方向可能漏。屏蔽讲究的是全封任何限定条件都是漏洞。第三UDP 的 53 端口DNS也要封。很多程序联网的第一步是解析域名封了 TCP/UDP 之后如果 DNS 查询还能出去程序会卡在域名解析阶段而不是立刻报错表现出来是界面转圈十几秒而不是网络不可用体验反而更差。真要干净就把 TCP 和 UDP 都按住。4.3 白名单思路与其风险边界有人会问能不能反过来做只让指定程序联网可以但代价很大。你得先把出站默认策略改成阻止然后逐个放行系统必需组件DNS 客户端、时间同步、更新服务、证书吊销检查等漏一个就会出各种诡异问题。这套方案我只在做受控终端时用过普通业务机器不推荐。比较务实的折中是按需封禁保持出站放行只把明确要管的程序加 block 规则。脚本里维护一个黑名单文件一行一个 exe 路径批量下发。这样日常新增软件不受影响管控目标又很清楚。另外提醒一句很多第三方安全软件会接管 Windows 防火墙的一部分能力。装了这类软件之后你在 Windows 防火墙里加的规则可能不会被实际执行或者被它自己的策略覆盖。排查规则加了不生效时先确认当前防火墙的实际控制方是谁别在错的地方使劲。5. 一套能直接抄的完整 bat 脚本5.1 骨架自提权、时间戳、日志、幂等改防火墙必须有管理员权限否则 netsh 会返回拒绝访问。脚本第一步就做权限检查把后面所有的坑挡在前面。echo off setlocal enabledelayedexpansion chcp 936 nul net session nul 21 if %errorlevel% neq 0 ( echo [ERROR] 需要管理员权限请右键以管理员身份运行。 pause exit /b 1 ) set LOG%~dp0firewall_task.log for /f %%i in (powershell -NoProfile -Command Get-Date -Format yyyy-MM-dd_HH-mm-ss) do set TS%%i echo [%TS%] 任务开始 %LOG%几个细节值得说。chcp 936是为了让中文输出不乱码配合脚本文件本身保存为 ANSI 编码。如果你把脚本存成 UTF-8中文注释和 echo 出来的字会变成乱码netsh 读到的路径也可能出问题。net session是判断管理员权限最省事的办法它需要一个只有管理员才能建立的服务会话。时间戳这里用了 PowerShell 的Get-Date而不是%date%。原因是%date%的输出格式完全跟随系统区域设置中文系统是2024/06/11 周一英文系统是Mon 06/11/2024用 for 去切分很容易在不同机器上崩掉。用 PowerShell 一行拿到固定格式稳得多。幂等是自动化脚本的生命线。同一份脚本跑第二遍不应该报错也不应该产生重复规则。做法很简单先删后加。call :AddInRule OA-Web-TCP-443-In TCP 443 call :AddInRule OA-Web-TCP-8080-In TCP 8080 goto :Done :AddInRule set R_NAME%~1 set R_PROTO%~2 set R_PORT%~3 netsh advfirewall firewall delete rule name%R_NAME% nul 21 netsh advfirewall firewall add rule name%R_NAME% dirin actionallow protocol%R_PROTO% localport%R_PORT% profileany groupOA-System %LOG% 21 if !errorlevel! neq 0 ( echo [!] 添加失败: %R_NAME% %LOG% ) else ( echo [] 已添加: %R_NAME% %LOG% ) exit /b 0echo [%TS%] ...这类写法里日志文件用追加模式别用否则每次运行前一次记录就被冲掉了。所有 netsh 的输出都重定向进日志这样出问题时不用靠猜直接翻日志看 netsh 返回了什么。有个小坑call :label里如果用了setlocal enabledelayedexpansion!errorlevel!才是实时的退出码%errorlevel%在同一个代码块里展开的是旧值。这个区别在循环里尤其致命脚本跑起来永远成功其实一直在失败。5.2 从列表批量下发规则把规则硬编码在脚本里适合固定场景规则一多就不方便了。更灵活的方式是外挂一个规则清单文件脚本负责解析。规则文件rules.txt放在脚本同目录格式这样设计OA-Web-TCP-443-In|in|allow|TCP|443 OA-Web-TCP-8080-In|in|allow|TCP|8080 OA-DB-TCP-3306-In|in|allow|TCP|3306|192.168.10.0/24解析脚本for /f usebackq tokens1-7 delims| %%A in (%~dp0rules.txt) do ( set NAME%%A set DIR%%B set ACT%%C set PROTO%%D set PORT%%E set SRC%%F netsh advfirewall firewall delete rule name!NAME! nul 21 if !SRC! ( netsh advfirewall firewall add rule name!NAME! dir!DIR! action!ACT! protocol!PROTO! localport!PORT! profileany groupBatch-Deploy %LOG% 21 ) else ( netsh advfirewall firewall add rule name!NAME! dir!DIR! action!ACT! protocol!PROTO! localport!PORT! remoteip!SRC! profileany groupBatch-Deploy %LOG% 21 ) echo [] %%A 处理完成 %LOG% )这样改规则只需要改文本文件脚本本身不动。第六列留空表示不限制来源 IP填了就走 remoteip 分支。这个模式我已经在好几个项目里用了规则从五条涨到五十条脚本一行不用改。如果要屏蔽一批程序另开一个blocklist.txt一行一个 exe 全路径路径含空格没关系用delims整行读取for /f usebackq delims %%P in (%~dp0blocklist.txt) do ( set EXE%%P for %%F in (!EXE!) do set BASE%%~nF netsh advfirewall firewall delete rule nameBlock-!BASE!-Out-TCP nul 21 netsh advfirewall firewall delete rule nameBlock-!BASE!-Out-UDP nul 21 netsh advfirewall firewall add rule nameBlock-!BASE!-Out-TCP dirout actionblock program!EXE! protocolTCP profileany groupBatch-Block %LOG% 21 netsh advfirewall firewall add rule nameBlock-!BASE!-Out-UDP dirout actionblock program!EXE! protocolUDP profileany groupBatch-Block %LOG% 21 echo [] 已拦截 !BASE! %LOG% )%%~nF是取文件名不带扩展名用它拼规则名可以避免规则名里出现路径分隔符。规则名统一带Block-前缀后续清理方便。5.3 回滚脚本把改动一键撤干净写自动化的人一定要留后路。规则下发脚本配套一份回滚把本次新增的规则按名字逐条删除echo off chcp 936 nul net session nul 21 || (echo 需要管理员权限 pause exit /b 1) for /f usebackq tokens1 delims| %%A in (%~dp0rules.txt) do ( netsh advfirewall firewall delete rule name%%A nul 21 echo [-] 已删除 %%A ) for /f usebackq delims %%P in (%~dp0blocklist.txt) do ( for %%F in (%%P) do set BASE%%~nF netsh advfirewall firewall delete rule nameBlock-!BASE!-Out-TCP nul 21 netsh advfirewall firewall delete rule nameBlock-!BASE!-Out-UDP nul 21 ) echo 回滚完成 pause这里要注意必须先setlocal enabledelayedexpansion否则循环里的!BASE!取不到值。这个 bug 我踩过一次脚本跑完成功规则一条没删——因为拼出来的规则名是空的delete rule name静默失败。更省事的备选方案是按 group 删。如果所有规则都打了统一 groupnetsh advfirewall firewall delete rule groupBatch-Deploy这一条就把整组清掉了比逐条删快得多也不容易漏。所以我前面反复强调 group 的价值——它不只是用来启停的更是用来批量清理的。6. 批量运维导出导入、批量筛选与批量启停6.1 用 .wfw 做规则备份与迁移规则写好之后备份这一步别省。Windows 防火墙支持把当前全部规则导出成一个.wfw文件netsh advfirewall export %~dp0fw_backup_%TS%.wfw恢复的时候netsh advfirewall import %~dp0fw_backup.wfw注意import是覆盖式的导入之后当前规则集会被文件里的内容整体替换。这个特性既好用又危险批量部署新机器时把标准机的规则导出在目标机上导入一套配置瞬间复制过去比逐条添加快得多但如果误在业务机上执行本机原有的自定义规则全没了。所以我的习惯是导入前先自动导出一份当前配置作为保险netsh advfirewall export %~dp0fw_before_import_%TS%.wfw netsh advfirewall import %~dp0fw_standard.wfw两份文件按时间戳命名%~dp0保证落在脚本所在目录不管从哪里双击运行都不会跑到别的地方去。还有一条命令要单独警告netsh advfirewall reset。它会恢复防火墙到出厂默认状态所有自定义规则全部清空。这条命令我只在重装环境的场景下用过日常脚本里绝不出现。6.2 按分组批量启停和查看规则上线之后日常运维最多的动作是临时关掉一组。比如测试阶段要临时停掉某组放行验证是不是防火墙的问题。用 set rule 改状态netsh advfirewall firewall set rule groupOA-System new enableno改回来把no换成yes。注意这条命令是整组生效不会删规则随时可逆比删了再加优雅得多。查看规则我推荐用 PowerShell 而不是findstr尤其在需要输出到文件的时候Get-NetFirewallRule -Group OA-System | Select-Object DisplayName, Direction, Action, Enabled, Profile | Format-Table -AutoSizeGet-NetFirewallRule返回的是对象字段名固定是英文不受系统语言影响也方便后续用Where-Object过滤、用Export-Csv存档。要查规则绑定的端口再串一层Get-NetFirewallRule -DisplayName OA-Web-* | Get-NetFirewallPortFilter用 netsh 查的话命令是netsh advfirewall firewall show rule nameall verbose输出很长中文系统下对着一屏中文找关键字效率不高。真要用加个findstr过滤但要记住前面说的语言差异问题——中文环境下字段是规则名称英文环境是 Rule Name写死一个字符串换台机器就失灵。提示如果你需要把规则清单交给别人核对用 PowerShell 输出 CSV比截图和复制 netsh 文本强太多。7. 踩坑实录与排查清单7.1 权限、编码、引号这三关这三个问题占了我在实际使用中遇到故障的绝大多数。权限。症状是 netsh 返回请求的操作需要提升或者直接拒绝访问。检查方式就是脚本开头的net session。如果你是通过计划任务、远程管理工具触发脚本的要注意那些通道通常默认不是管理员上下文得在任务配置里勾使用最高权限运行。编码。症状是规则名变成问号或者乱码程序路径带中文时规则加不上。处理办法bat 文件用 ANSI/GBK 保存脚本里chcp 936路径尽量避开中文和空格非要用就在 netsh 参数里给整段路径加引号形如programC:\工具\采集器.exe。引号。netsh 的参数是空格分隔的 keyvalue只要 value 里有空格就必须加引号否则 netsh 会把空格后的内容当成下一个参数。典型翻车是nameMy Rulenetsh 会把Rule当成一个不认识的参数报参数错误但错误信息不一定指向真正的原因。规则名统一不用空格能省掉这类问题。另外还有一个字面陷阱profile千万别拼成profiles。netsh 对这类拼写错误有时不会明确报错只是规则落不到你想要的作用域上然后你花半小时怀疑人生。所有 netsh 命令执行后养成看一眼退出码和日志的习惯。7.2 规则明明加了却不通的排查顺序碰到规则加了但连不上我固定按这个顺序走基本五步之内定位。第一步确认规则真的存在且启用。netsh advfirewall firewall show rule name规则名看输出里已启用是不是是方向对不对。第二步确认当前网络配置文件的类型。powershell -Command Get-NetConnectionProfile会告诉你当前连的网络是 Domain、Private 还是 Public。如果规则只写了private而机器现在被判成public规则就是不生效的。第三步确认防火墙服务本身在跑。sc query MpsSvc状态不是 RUNNING 的话所有规则都是摆设。同时确认没有第三方安全软件接管了防火墙控制权。第四步确认没有更高优先级的 block 规则在拦。用Get-NetFirewallRule -Action Block -Enabled True列一遍所有启用的阻止规则看有没有误伤。我遇到过一次同事为了封某个下载工具加了条protocolany的 block结果把同网段的业务流量一起封了因为规则里没限定 program。第五步确认协议和 IPv6。开了 TCP 没开 UDP或者来源限制只写了 IPv4 导致 IPv6 流量走了别的路径。用netstat -ano看实际连接状态配合findstr定位进程 PID比在防火墙界面里瞎猜高效得多。7.3 问题速查表现象可能原因处理方式netsh 报拒绝访问非管理员上下文右键以管理员运行或计划任务勾最高权限规则名显示为乱码脚本编码与代码页不匹配存为 ANSI脚本首行 chcp 936规则存在但连接不通profile 与当前网络类型不符改 profileany 或补上对应档位规则加不上、报参数错误value 里含空格未加引号规则名去掉空格路径整段加引号屏蔽程序后仍能联网只封了 TCPUDP 未封补齐 UDP 规则不加 remoteip 限制屏蔽后程序卡顿而非报错DNS 查询仍可出去一并封 UDP规则不设 remoteip程序更新后拦截失效exe 路径变化规则绑旧路径路径抽成变量更新后同步修改规则加了但完全无效果第三方安全软件接管防火墙确认实际控制方在其控制台配置导入 .wfw 后原有规则消失import 是覆盖式导入前先自动导出一份当前配置批量删除时规则一条没删未开延迟展开变量为空加 setlocal enabledelayedexpansion用 !变量!7.4 几个我踩过才会说的细节先查再改。脚本执行前把当前规则导出成.wfw存一份。成本一条命令收益是任何时候都能回到修改前。别在远程会话里裸奔。改防火墙规则时如果你正通过远程桌面连过去先在本地开一个带超时的任务计划把规则改回来或者干脆在虚拟机上验证完再上生产。我见过一次把远程桌面端口封掉的操作最后只能让机房的人重启到安全模式。规则数量要控制。防火墙规则越多匹配开销越大而且越难维护。同一个端口给多个来源的场景优先写成一条带多个 remoteip 的规则而不是复制五条。同理能用 group 归纳的一律归纳。日志留痕。脚本每次运行都往日志文件追加时间戳和结果规则清单本身放版本管理里。半年后有人问这个 3306 是谁开的你能直接把日志和 commit 记录甩出来这种时刻还是挺爽的。最后一个复用的小技巧把这套东西做成模板 数据的结构。脚本本体提权、日志、解析、幂等是完全通用的不同项目只换rules.txt和blocklist.txt。我现在手上有三四个这样的模板部署新环境就是复制模板、改清单、跑一遍、翻日志确认整套动作五分钟之内完成比在界面上点半小时靠谱得多。后续要扩展也很自然比如把规则清单换成从配置管理平台拉取脚本只负责解析和下发思路是一致的。
上一篇/下一篇内容由系统自动关联
返回资讯列表 →