我需要在 Windows 防火墙中拒绝访问大约 50,000 个 IP 地址;
netsh advfirewall
只允许我添加大约700个。这如何实现?
看起来您可以使用 C# 应用程序以编程方式将规则添加到 Windows 防火墙。您需要添加对
FirewallAPI.dll
的引用,它位于 c:\windows\system32
做这样的事情:
using NetFwTypeLib; // Located in FirewallAPI.dll
...
INetFwRule firewallRule = (INetFwRule)Activator.CreateInstance(
Type.GetTypeFromProgID("HNetCfg.FWRule"));
firewallRule.Action = NET_FW_ACTION_.NET_FW_ACTION_BLOCK;
firewallRule.Description = "Block this!";
firewallRule.Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN;
firewallRule.Enabled = true;
firewallRule.InterfaceTypes = "All";
firewallRule.RemoteAddresses = "x.x.x.x" //or x.x.x.x,x.x.x.x,... See Note 1
firewallRule.Name = "Block IP x.x.x.x";
INetFwPolicy2 firewallPolicy = (INetFwPolicy2)Activator.CreateInstance(
Type.GetTypeFromProgID("HNetCfg.FwPolicy2"));
firewallPolicy.Rules.Add(firewallRule);
注 1:您可以尝试创建 50,000 个单独的规则(此代码添加 1 条规则)或将 50,000 个远程 IP 添加到 1 条规则。
这是用于入站阻塞,如果你想要出站阻塞,也可以改变方向。
参考资料:改编自有什么方法可以使用c#在Windows中关闭“互联网”吗?和https://msdn.microsoft.com/en-us/library/aa366458(VS.85).aspx
不幸的是,由于控制台的限制,
netsh advfirewall
命令每行只能处理大约8192个字符(每条规则大约550-1k IP)。
要使用此方法添加无限数量的 IP 块,您必须将逗号分隔的 IP 列表分解为不超过 8k 字符的块,或将它们添加为单独的 IP 块(这可能是不可取的,因为它会淹没 -列出您的防火墙规则!)
我已经在 TCL 中完成了此操作,但是如果有人知道如何将 txt 文件拆分为不超过 8k 字符的 DOS 变量块,或者将 IP 添加到不超过 8k 字符长的变量 - 也可以在这里发布:)
这是 TCL 编码...在文件中找到的逗号分隔 IP 列表:comma_seperated_iplist.txt
set readfile [open "comma_seperated_iplist.txt" r]; # Open the comma seperated IP list file
set ip_list [read $out]; # read the whole file into 1 variable
close $readfile; # close the file, no longer needed
catch {exec netsh advfirewall firewall delete rule name=IPBlocks}; # remove any old entries
if {[string length $ip_list] < 8000} {
# if under 8000 characters, just add them directly to 1 firewall entry
catch {exec netsh advfirewall firewall add rule name="IPBlocks" protocol=any dir=in action=block remoteip=$ip_list}
} else {
# if over 8000 characters, break up into 8000 components and add each firewall rule
set startpos 0; # set the search starting position (begining)
set add_ip_range "1"; # set the start range IP list to anything
while {$add_ip_range !=""} {; # loop until the start range IP list is empty
# set the IP range contents to check up to
set compare_ip_range [string range $ip_list 0 [expr $startpos + 8000]]
# set the end position with the last character as comma * remove last comma
set endpos [expr [string last "," $compare_ip_range]-1]
# get the actual text range/chunk from the start position to the end position of the whole list
set add_ip_range [string range $ip_list $startpos $endpos]
# ensure the IP range (chunk) has something in it first
if {$add_ip_range !=""} {
# add the range of IP's (chunk) to a Windows Firewall Rule
if {![catch {exec netsh advfirewall firewall add rule name="IPBlocks" protocol=any dir=in action=block remoteip=$add_ip_range} err]} {
}
set startpos [expr $endpos+2]; # Update new start position for more chunks +2 characters to skip over removed comma from endpos
}
}
我也有类似的问题。起初,通过命令行,我只能使用 346 个 IP 地址(在我此处的特定列表中)。那就是:
netsh advfirewall firewall set rule name="My Rule" remoteip=<growing_list_of_IPs>
到目前为止,IP 列表读起来像
x.x.x.x/32,y.y.y.y/32,z.z.z.z/32
,共 346 次。除此之外,该命令默默失败,没有添加 IP 地址。
下一步是使用 netsh 脚本将其“脚本化”。因此,我创建了一个文本文件(
netsh-script.txt
),其中包含:
advfirewall firewall set rule name="My Rule" remoteip=<growing_list_of_IPs>
然后运行它:
netsh exec netsh-script.txt
令我惊讶的是,我只能将列表增加到 462 个 IP。亲爱的剧本开始打破界限并说
The following command was not found: /32,x.x.x.x/32,y.y.y.y/32.
这些是最后两个 IP 加上进入的第 462 个 IP 的一部分(只是因为它被其
/32
部分右切)。非常不靠谱!..
现在,我可以删除每个 IP 的
/32
部分(当我们列出 netsh
中的规则时由防火墙添加),但这只会给我更多的 IP 地址。我必须继续前进。
C# 并不是一个真正的选择,因为我想避免编译代码,以及进一步的运行时安装/维护。然后的选择是将逻辑封装到我能做到的最简单的 powershell 脚本中。
然后以下
netsh-update.ps1
脚本就诞生了:
Set-NetFirewallRule -DisplayName "HTTP/HTTPS Filter" -RemoteAddress (
"x.x.x.x/32", "y.y.y.y/32", ..., "z.z.z.z/32"
)
...然后从我的脚本中我可以动态“生成”这个 powershell 脚本并使用以下命令调用它:
powershell netsh-update.ps1
我仍在看看我能够将这个列表增长到什么程度,但它至少看起来很有希望!..
最后,我需要将从 netsh 获得的结果转换为:
x.x.x.x/32,y.y.y.y/32,...,z.z.z.z/32
进入
( "x.x.x.x./32", "y.y.y.y/32", ..., "z.z.z.z/32" )
将其转储到临时脚本中,运行,然后我就可以制作不断增长的过滤 IP 列表!
Powershell 没有同样的 8000 个字符限制。
New-NetFirewallRule -DisplayName "Blocked IP address" -Direction Inbound -Action Block -RemoteAddress 101.100.146.147,101.53.147.11...