PowerShell防火墙国家IP封禁脚本更换GeoIP库后失效问题排查
Windows防火墙GeoIP拦截规则修复方案
故障根因
原脚本替换IP库后无响应、无法生成规则的核心原因有两点:
- 新旧GeoIP库格式不兼容:旧Maxmind库为6字段结构,直接提供点分十进制IP段;新IP2LOCATION LITE库仅4字段,仅存储整数格式IP段,原脚本
Import-Csv定义的6列表头和新库完全错位,无法正确读取国家代码、IP地址信息 - 原脚本未实现指定内网段、公共DNS、韩国本土IP段的排除逻辑,直接运行会阻断正常网络访问
适配修复后的完整脚本
#############配置项################# $blockCountryCode = "CN", "RU", "KP" # 需要拦截的国家代码 $geoIPcvsPath = ".\IP2LOCATION-LITE-DB1.CSV" # IP2LOCATION库文件路径 $krIPListPath = ".\kr.netset" # 韩国IP段列表文件路径 $ruleName = "blockCountry" $excludeIPPrefix = @( "0.0.0.", "192.168.", "224.0.", "172.30.", "168.126.", "210.220.", "219.250.", "61.41.", "1.214.", "164.124.", "203.248.", "180.182.", "94.140.", "208.67.", "1.1.", "1.0.", "8.8.", "9.9.", "149.112.", "194.242.", "185.222.", "45.11.", "10.0.", "172.162." ) $excludeIPRange = @("192.168.0.0/16", "224.0.0.0/16") #############配置项################# # 整数IP转点分十进制IP工具函数 function IntToIP($intIP) { $bytes = [BitConverter]::GetBytes([uint32]$intIP) [Array]::Reverse($bytes) return ([IPAddress]$bytes).IPAddressToString } # 加载所有需要排除的IP段 # 加载韩国IP段 if (Test-Path $krIPListPath) { $krIPs = Get-Content $krIPListPath | Where-Object { $_ -notmatch "^#" -and $_ -ne "" } $excludeIPRange += $krIPs } # 加载自定义排除前缀对应的IP段 foreach ($prefix in $excludeIPPrefix) { $excludeIPRange += $prefix + "0/24" } # 导入IP2LOCATION库,适配4字段格式 $geoData = Import-Csv $geoIPcvsPath -Header startInt, endInt, cc, cn | Where-Object { $_.cc -in $blockCountryCode } | ForEach-Object { # 转换整数IP为点分十进制格式 $sIP = IntToIP $_.startInt $eIP = IntToIP $_.endInt # 过滤掉属于排除列表的IP段 $isExcluded = $false foreach ($exIP in $excludeIPRange) { if ($sIP.StartsWith($exIP.Split('/')[0]) -or $eIP.StartsWith($exIP.Split('/')[0])) { $isExcluded = $true break } } if (-not $isExcluded) { [PSCustomObject]@{ sIP = $sIP eIP = $eIP } } } $geoDataTotal = $geoData.Count $remoteIP = "" # 防火墙规则存在性检查函数 function ruleExistsChk ($ruleName) { $fw = New-Object -comObject HNetCfg.FwPolicy2 $RuleCHK = $fw.rules | Where-Object { $_.name -eq $ruleName } if (-not $RuleCHK) { netsh advfirewall firewall add rule name="$ruleName" localip=any dir=in action=block profile="any" interfacetype="any" | Out-Null } } # 批量生成拦截规则 $count = 1 foreach ($geoIP in $geoData) { $remoteIP += $geoIP.sIP + "-" + $geoIP.eIP + "," # 单条规则最多存放200个IP段,避免超过Windows防火墙上限失效 if (($count % 200) -eq 0) { $makeRuleName = $ruleName + "_" + $count ruleExistsChk $makeRuleName netsh advfirewall firewall set rule name=$makeRuleName new remoteip="$remoteIP" | Out-Null $remoteIP = "" } elseif ($geoDataTotal -eq $count) { $makeRuleName = $ruleName + "_" + $count ruleExistsChk $makeRuleName netsh advfirewall firewall set rule name=$makeRuleName new remoteip="$remoteIP" | Out-Null $remoteIP = "" } $count++ } Write-Host "拦截规则生成完成,共处理 $($geoDataTotal) 个IP段"
使用说明
- 运行脚本前,将IP2LOCATION-LITE-DB1.CSV、韩国IP段列表文件重命名为
kr.netset后放在脚本同一目录 - 右键点击PowerShell,选择以管理员身份运行后执行脚本,否则无权限修改防火墙规则
- 脚本自动拆分每200个IP段为一条独立防火墙规则,避免单条规则地址过多失效
- 所有排除的IP段不会加入拦截列表,不会影响内网、公共DNS、韩国本土IP的正常访问
- 如需新增放行IP段,直接在配置项的
$excludeIPPrefix或$excludeIPRange中添加即可
内容的提问来源于stack exchange,提问作者krdondon
相关产品推荐
相关产品推荐

