Windows 防火墙出站白名单:PowerShell 脚本 3 步实现 IP 段自动计算与规则部署

Windows 防火墙出站白名单:PowerShell 脚本 3 步实现 IP 段自动计算与规则部署

在企业网络安全管理中,精确控制服务器出站访问是降低攻击面的关键措施。传统手动配置防火墙规则不仅耗时耗力,还容易因人为错误导致安全漏洞。本文将介绍一套基于 PowerShell 的自动化解决方案,只需 3 步即可完成 IP 段智能计算与规则部署,大幅提升运维效率。

1. 环境准备与核心算法设计

1.1 PowerShell 环境配置

确保目标系统已启用 PowerShell 5.1 或更高版本。执行以下命令检查版本并启用脚本执行权限:

# 检查PowerShell版本 $PSVersionTable.PSVersion # 设置执行策略(需管理员权限) Set-ExecutionPolicy RemoteSigned -Force # 加载NetSecurity模块 Import-Module NetSecurity -ErrorAction Stop

1.2 IP 段计算算法原理

核心算法通过将整个 IPv4 地址空间(0.0.0.0 - 255.255.255.255)与允许的 IP/网段进行对比计算,自动生成需要阻止的区间。算法流程如下:

  1. 将允许的 IP 转换为连续的区间对象
  2. 对区间集合进行合并优化(处理重叠和相邻区间)
  3. 计算全地址空间与允许区间的差集
  4. 输出优化的阻止区间列表
class IpRange { [IPAddress]$Start [IPAddress]$End IpRange([string]$start, [string]$end) { $this.Start = [IPAddress]$start $this.End = [IPAddress]$end } [string]ToString() { return "$($this.Start)-$($this.End)" } } function Get-ExcludedRanges { param( [IpRange[]]$AllowedRanges ) # 实现差集计算的核心逻辑 # ... }

2. 自动化脚本实现

2.1 完整脚本代码

以下脚本支持三种输入格式:单个IP、CIDR网段和IP范围:

<# .SYNOPSIS 自动生成Windows防火墙出站阻止规则 .DESCRIPTION 根据允许的IP/网段列表,自动计算需要阻止的IP范围并创建防火墙规则 .PARAMETER AllowedIps 允许访问的IP列表,支持格式:1.1.1.1、192.168.0.0/24、10.0.0.1-10.0.0.50 .PARAMETER RuleName 防火墙规则名称(默认:Block_NonWhitelisted_Outbound) .PARAMETER DeploymentMethod 规则部署方式:Command(命令行)、Script(脚本)、GPO(组策略对象) #> param( [Parameter(Mandatory=$true)] [string[]]$AllowedIps, [string]$RuleName = "Block_NonWhitelisted_Outbound", [ValidateSet('Command','Script','GPO')] [string]$DeploymentMethod = 'Script' ) # IP处理函数 function ConvertTo-IpRange { # 实现不同IP格式的标准化转换 # ... } # 主逻辑 try { $allowedRanges = $AllowedIps | ForEach-Object { ConvertTo-IpRange $_ } $blockRanges = Get-ExcludedRanges -AllowedRanges $allowedRanges switch ($DeploymentMethod) { 'Command' { $remoteIps = $blockRanges -join ',' $cmd = "netsh advfirewall firewall add rule name=`"$RuleName`" dir=out action=block remoteip=`"$remoteIps`"" Write-Output "执行以下命令:`n$cmd" } 'Script' { $blockRanges | ForEach-Object { New-NetFirewallRule -DisplayName $RuleName -Direction Outbound ` -Action Block -RemoteAddress $_.ToString() -Enabled True } } 'GPO' { # 生成组策略部署脚本 # ... } } } catch { Write-Error "执行失败:$_" }

2.2 典型使用案例

场景1:只允许访问9.0.0.3和11.1.1.3,以及私有网络段

.\FirewallWhitelist.ps1 -AllowedIps @( "9.0.0.3", "11.1.1.3", "10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16" ) -DeploymentMethod Script

场景2:通过命令行生成配置

.\FirewallWhitelist.ps1 -AllowedIps "203.0.113.50-203.0.113.100" -DeploymentMethod Command

3. 高级部署与管理

3.1 组策略部署(GPO方法)

对于企业环境,建议通过组策略统一部署:

  1. 将脚本保存到网络共享路径
  2. 创建组策略首选项计划任务
  3. 设置每台计算机启动时自动执行脚本
# GPO部署脚本示例 $gpoScript = @" # 检测域环境 if ((Get-CimInstance Win32_ComputerSystem).PartOfDomain) { $allowed = @("10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16") .\FirewallWhitelist.ps1 -AllowedIps $allowed -DeploymentMethod Script } "@ $gpoScript | Out-File "\\domain\sysvol\scripts\DeployFirewall.ps1"

3.2 规则验证与测试

部署后需验证规则有效性:

# 查看已创建的规则 Get-NetFirewallRule -DisplayName "Block_NonWhitelisted_Outbound" | Get-NetFirewallAddressFilter | Format-Table RemoteAddress # 测试连接(需安装Test-NetConnection模块) Test-OutboundConnection -TargetIp "1.1.1.1" -ExpectedResult Blocked Test-OutboundConnection -TargetIp "10.0.0.1" -ExpectedResult Allowed

3.3 维护与更新

建议创建规则维护脚本:

<# .SYNOPSIS 更新防火墙白名单规则 .NOTES 版本 1.1 新增对IPv6的支持 #> param( [string[]]$NewAllowedIps, [switch]$CleanUp ) if ($CleanUp) { Get-NetFirewallRule -DisplayName "Block_NonWhitelisted_*" | Remove-NetFirewallRule } if ($NewAllowedIps) { .\FirewallWhitelist.ps1 -AllowedIps $NewAllowedIps -DeploymentMethod Script }

4. 性能优化与最佳实践

4.1 规则优化技巧

Windows防火墙对规则数量有限制,建议:

  1. 合并相邻IP段减少规则数量
  2. 优先使用CIDR表示法
  3. 定期清理过期规则
# 规则合并算法示例 function Optimize-Ranges { param( [IpRange[]]$Ranges ) # 实现区间合并优化 # ... }

4.2 监控与日志

启用防火墙日志记录:

# 配置日志 Set-NetFirewallProfile -LogFileName %SystemRoot%\System32\LogFiles\Firewall\pfirewall.log ` -LogMaxSizeKilobytes 32768 -LogAllowed True -LogBlocked True # 分析日志 Get-Content -Path "$env:SystemRoot\System32\LogFiles\Firewall\pfirewall.log" -Tail 100 | Where-Object { $_ -match $RuleName }

4.3 异常处理机制

添加自动告警功能:

# 监控规则状态 $ruleStatus = Get-NetFirewallRule -DisplayName $RuleName | Select-Object DisplayName, Enabled if (-not $ruleStatus.Enabled) { Send-MailMessage -To "admin@example.com" -Subject "防火墙异常" ` -Body "规则 $($ruleStatus.DisplayName) 被禁用" }