使用 Azure PowerShell 在混合网络中部署和配置 Azure 防火墙

将本地网络连接到 Azure 虚拟网络以创建混合网络时,必须能够控制对 Azure 网络资源的访问,这是整体安全计划的重要部分。

可以使用 Azure 防火墙通过规则来定义允许的和拒绝的网络流量,以便控制混合网络中的网络访问。

在本文中,将创建三个虚拟网络:

  • VNet-Hub:防火墙在此虚拟网络中。
  • VNet-Spoke:分支虚拟网络代表 Azure 中的工作负载。
  • VNet-Onprem:本地虚拟网络代表本地网络。 在实际部署中,可以使用虚拟专用网络 (VPN) 连接或 Azure ExpressRoute 连接来连接到它。 为简单起见,本文使用 VPN 网关连接,并使用 Azure 中的某个虚拟网络来代表本地网络。

显示混合网络中防火墙的关系图。

如果要使用 Azure 门户来完成本文中的过程,请参阅使用 Azure 门户在混合网络中部署和配置 Azure 防火墙

注意

建议使用 Azure Az PowerShell 模块与 Azure 交互。 请参阅安装 Azure PowerShell 以开始使用。 若要了解如何迁移到 Az PowerShell 模块,请参阅 将 Azure PowerShell 从 AzureRM 迁移到 Az

先决条件

本文要求在本地运行 PowerShell。 必须安装 Azure PowerShell 模块。 运行 Get-Module -ListAvailable Az 即可查找版本。 如果需要升级,请参阅安装 Azure PowerShell 模块。 验证 PowerShell 版本以后,请运行 Connect-AzAccount -Environment AzureChinaCloud,以便创建与 Azure 的连接。

若要正常开展此方案,必须符合三项关键要求:

  • 分支子网中有一个指向 Azure 防火墙 IP 地址(用作默认网关)的用户定义的路由 (UDR)。 必须在此路由表上禁用虚拟网络网关路由传播。

  • 中心网关子网中的 UDR 必须指向用作分支网络下一跃点的防火墙 IP 地址。

    Azure 防火墙子网上不需要 UDR,因为它从边界网关协议 (BGP) 探测路由。

  • 请务必将 VNet-Hub 对等互连到 VNet-Spoke 时设置 AllowGatewayTransit。 将 VNet-Spoke 对等互连到 VNet-Hub 时设置 UseRemoteGateways

本文后面的创建路由部分介绍如何创建这些路由。

注意

Azure 防火墙必须具有直接的 Internet 连接。 如果你的 AzureFirewallSubnet 子网通过 BGP 学习本地网络的默认路由,则必须在强制隧道模式下配置 Azure 防火墙。 如果这是无法在强制隧道模式下重新配置的现有 Azure 防火墙实例,建议在 AzureFirewallSubnet 子网中添加 0.0.0.0/0 UDR,其 NextHopType 值设置为 Internet 以保持直接 Internet 连接。

有关详细信息,请参阅 Azure 防火墙强制隧道

即使 UDR 指向作为默认网关的 Azure 防火墙,也会直接路由直接对等互连虚拟网络之间的流量。 若要在此方案中将子网到子网流量发送到防火墙,UDR 必须在这两个子网上显式地包含目标子网网络前缀。

若要查看相关的 Azure PowerShell 参考文档,请访问 New-AzFirewall

如果没有 Azure 订阅,请在开始前创建一个试用版订阅

声明变量

以下示例使用本文中的值来声明变量。 在某些情况下,可能需要根据订阅情况将某些值替换为你自己的值。 根据需要修改变量,并将其复制并粘贴到 PowerShell 控制台中。

$RG1 = "FW-Hybrid-Test"
$Location1 = "China East"

# Variables for the firewall hub virtual network

$VNetnameHub = "VNet-Hub"
$SNnameHub = "AzureFirewallSubnet"
$VNetHubPrefix = "10.5.0.0/16"
$SNHubPrefix = "10.5.0.0/24"
$SNGWHubPrefix = "10.5.1.0/24"
$GWHubName = "GW-hub"
$GWHubpipName = "VNet-Hub-GW-pip"
$GWIPconfNameHub = "GW-ipconf-hub"
$ConnectionNameHub = "hub-to-Onprem"

# Variables for the spoke virtual network

$VnetNameSpoke = "VNet-Spoke"
$SNnameSpoke = "SN-Workload"
$VNetSpokePrefix = "10.6.0.0/16"
$SNSpokePrefix = "10.6.0.0/24"
$SNSpokeGWPrefix = "10.6.1.0/24"

# Variables for the on-premises virtual network

$VNetnameOnprem = "Vnet-Onprem"
$SNNameOnprem = "SN-Corp"
$VNetOnpremPrefix = "192.168.0.0/16"
$SNOnpremPrefix = "192.168.1.0/24"
$SNGWOnpremPrefix = "192.168.2.0/24"
$GWOnpremName = "GW-Onprem"
$GWIPconfNameOnprem = "GW-ipconf-Onprem"
$ConnectionNameOnprem = "Onprem-to-hub"
$GWOnprempipName = "VNet-Onprem-GW-pip"

$SNnameGW = "GatewaySubnet"

创建防火墙中心虚拟网络

首先,创建资源组以包含本文的资源:

  New-AzResourceGroup -Name $RG1 -Location $Location1

定义要包含在虚拟网络中的子网:

$FWsub = New-AzVirtualNetworkSubnetConfig -Name $SNnameHub -AddressPrefix $SNHubPrefix
$GWsub = New-AzVirtualNetworkSubnetConfig -Name $SNnameGW -AddressPrefix $SNGWHubPrefix

创建防火墙中心虚拟网络:

$VNetHub = New-AzVirtualNetwork -Name $VNetnameHub -ResourceGroupName $RG1 `
-Location $Location1 -AddressPrefix $VNetHubPrefix -Subnet $FWsub,$GWsub

请求一个要分配到为虚拟网络创建的 VPN 网关的公共 IP 地址。 请注意,AllocationMethod 值为 Dynamic。 无法指定要使用的 IP 地址。 该 IP 地址会动态分配到 VPN 网关。

$gwpip1 = New-AzPublicIpAddress -Name $GWHubpipName -ResourceGroupName $RG1 `
-Location $Location1 -AllocationMethod Dynamic

创建分支虚拟网络

定义要包含在分支虚拟网络中的子网:

$Spokesub = New-AzVirtualNetworkSubnetConfig -Name $SNnameSpoke -AddressPrefix $SNSpokePrefix
$GWsubSpoke = New-AzVirtualNetworkSubnetConfig -Name $SNnameGW -AddressPrefix $SNSpokeGWPrefix

创建分支虚拟网络:

$VNetSpoke = New-AzVirtualNetwork -Name $VnetNameSpoke -ResourceGroupName $RG1 `
-Location $Location1 -AddressPrefix $VNetSpokePrefix -Subnet $Spokesub,$GWsubSpoke

创建本地虚拟网络

定义要包含在虚拟网络中的子网:

$Onpremsub = New-AzVirtualNetworkSubnetConfig -Name $SNNameOnprem -AddressPrefix $SNOnpremPrefix
$GWOnpremsub = New-AzVirtualNetworkSubnetConfig -Name $SNnameGW -AddressPrefix $SNGWOnpremPrefix

创建本地虚拟网络:

$VNetOnprem = New-AzVirtualNetwork -Name $VNetnameOnprem -ResourceGroupName $RG1 `
-Location $Location1 -AddressPrefix $VNetOnpremPrefix -Subnet $Onpremsub,$GWOnpremsub

请求一个要分配到为虚拟网络创建的网关的公共 IP 地址。 请注意,AllocationMethod 值为 Dynamic。 无法指定要使用的 IP 地址。 它会动态分配到网关。

$gwOnprempip = New-AzPublicIpAddress -Name $GWOnprempipName -ResourceGroupName $RG1 `
-Location $Location1 -AllocationMethod Dynamic

配置和部署防火墙

现在,将防火墙部署到中心虚拟网络:

# Get a public IP for the firewall
$FWpip = New-AzPublicIpAddress -Name "fw-pip" -ResourceGroupName $RG1 `
  -Location $Location1 -AllocationMethod Static -Sku Standard
# Create the firewall
$Azfw = New-AzFirewall -Name AzFW01 -ResourceGroupName $RG1 -Location $Location1 -VirtualNetworkName $VNetnameHub -PublicIpName fw-pip

#Save the firewall private IP address for future use

$AzfwPrivateIP = $Azfw.IpConfigurations.privateipaddress
$AzfwPrivateIP

配置网络规则:

$Rule1 = New-AzFirewallNetworkRule -Name "AllowWeb" -Protocol TCP -SourceAddress $SNOnpremPrefix `
   -DestinationAddress $VNetSpokePrefix -DestinationPort 80

$Rule2 = New-AzFirewallNetworkRule -Name "AllowRDP" -Protocol TCP -SourceAddress $SNOnpremPrefix `
   -DestinationAddress $VNetSpokePrefix -DestinationPort 3389

$Rule3 = New-AzFirewallNetworkRule -Name "AllowPing" -Protocol ICMP -SourceAddress $SNOnpremPrefix `
   -DestinationAddress $VNetSpokePrefix -DestinationPort

$NetRuleCollection = New-AzFirewallNetworkRuleCollection -Name RCNet01 -Priority 100 `
   -Rule $Rule1,$Rule2 -ActionType "Allow"
$Azfw.NetworkRuleCollections = $NetRuleCollection
Set-AzFirewall -AzureFirewall $Azfw

创建并连接 VPN 网关

通过 VPN 网关连接中心和本地虚拟网络。

为中心虚拟网络创建 VPN 网关

为中心虚拟网络创建 VPN 网关配置。 VPN 网关配置定义要使用的子网和公共 IP 地址。

$vnet1 = Get-AzVirtualNetwork -Name $VNetnameHub -ResourceGroupName $RG1
$subnet1 = Get-AzVirtualNetworkSubnetConfig -Name "GatewaySubnet" -VirtualNetwork $vnet1
$gwipconf1 = New-AzVirtualNetworkGatewayIpConfig -Name $GWIPconfNameHub `
-Subnet $subnet1 -PublicIpAddress $gwpip1

现在,为中心虚拟网络创建 VPN 网关。 网络到网络配置需要 RouteBasedVpnType 值。 创建 VPN 网关通常需要 45 分钟或更长的时间,具体取决于所选的 SKU。

New-AzVirtualNetworkGateway -Name $GWHubName -ResourceGroupName $RG1 `
-Location $Location1 -IpConfigurations $gwipconf1 -GatewayType Vpn `
-VpnType RouteBased -GatewaySku basic

为本地虚拟网络创建 VPN 网关

为本地虚拟网络创建 VPN 网关配置。 VPN 网关配置定义要使用的子网和公共 IP 地址。

$vnet2 = Get-AzVirtualNetwork -Name $VNetnameOnprem -ResourceGroupName $RG1
$subnet2 = Get-AzVirtualNetworkSubnetConfig -Name "GatewaySubnet" -VirtualNetwork $vnet2
$gwipconf2 = New-AzVirtualNetworkGatewayIpConfig -Name $GWIPconfNameOnprem `
-Subnet $subnet2 -PublicIpAddress $gwOnprempip

现在,为本地虚拟网络创建 VPN 网关。 网络到网络配置需要 RouteBasedVpnType 值。 创建 VPN 网关通常需要 45 分钟或更长的时间,具体取决于所选的 SKU。

New-AzVirtualNetworkGateway -Name $GWOnpremName -ResourceGroupName $RG1 `
-Location $Location1 -IpConfigurations $gwipconf2 -GatewayType Vpn `
-VpnType RouteBased -GatewaySku basic

创建 VPN 连接

在中心和本地网关之间创建 VPN 连接。

获取 VPN 网关

$vnetHubgw = Get-AzVirtualNetworkGateway -Name $GWHubName -ResourceGroupName $RG1
$vnetOnpremgw = Get-AzVirtualNetworkGateway -Name $GWOnpremName -ResourceGroupName $RG1

创建连接

此步骤创建从中心虚拟网络到本地虚拟网络的连接。 这些示例显示了共享密钥,但可以对共享密钥使用自己的值。 共享密钥必须与两个连接匹配,这一点非常重要。 创建连接可能需要简短的一段时间才能完成。

New-AzVirtualNetworkGatewayConnection -Name $ConnectionNameHub -ResourceGroupName $RG1 `
-VirtualNetworkGateway1 $vnetHubgw -VirtualNetworkGateway2 $vnetOnpremgw -Location $Location1 `
-ConnectionType Vnet2Vnet -SharedKey 'AzureA1b2C3'

创建从本地到中心的虚拟网络连接。 此步骤类似于前一步骤,但这次是创建从 VNet-OnpremVNet-Hub 的连接。 确保共享密钥匹配。 连接在几分钟后建立。

New-AzVirtualNetworkGatewayConnection -Name $ConnectionNameOnprem -ResourceGroupName $RG1 `
-VirtualNetworkGateway1 $vnetOnpremgw -VirtualNetworkGateway2 $vnetHubgw -Location $Location1 `
-ConnectionType Vnet2Vnet -SharedKey 'AzureA1b2C3'

验证连接

可以使用 Get-AzVirtualNetworkGatewayConnection cmdlet(无论是否具有 -Debug)来验证连接是否成功。

使用以下 cmdlet 示例,但配置值以匹配自己的值。 如果系统提示,请选择 A 以运行 All。 在此示例中,-Name 是指要测试的连接的名称。

Get-AzVirtualNetworkGatewayConnection -Name $ConnectionNameHub -ResourceGroupName $RG1

cmdlet 运行完毕后,查看值。 以下示例显示了 Connected 的连接状态以及流入量和流出量字节:

"connectionStatus": "Connected",
"ingressBytesTransferred": 33509044,
"egressBytesTransferred": 4142431

将中心和分支虚拟网络对等互连

现在,对等互连中心和分支虚拟网络:

# Peer hub to spoke
Add-AzVirtualNetworkPeering -Name HubtoSpoke -VirtualNetwork $VNetHub -RemoteVirtualNetworkId $VNetSpoke.Id -AllowGatewayTransit

# Peer spoke to hub
Add-AzVirtualNetworkPeering -Name SpoketoHub -VirtualNetwork $VNetSpoke -RemoteVirtualNetworkId $VNetHub.Id -AllowForwardedTraffic -UseRemoteGateways

创建路由

使用以下命令创建以下路由:

  • 通过防火墙 IP 地址从中心网关子网连接到分支子网的路由
  • 通过防火墙 IP 地址从分支子网连接的默认路由
#Create a route table
$routeTableHubSpoke = New-AzRouteTable `
  -Name 'UDR-Hub-Spoke' `
  -ResourceGroupName $RG1 `
  -location $Location1

#Create a route
Get-AzRouteTable `
  -ResourceGroupName $RG1 `
  -Name UDR-Hub-Spoke `
  | Add-AzRouteConfig `
  -Name "ToSpoke" `
  -AddressPrefix $VNetSpokePrefix `
  -NextHopType "VirtualAppliance" `
  -NextHopIpAddress $AzfwPrivateIP `
 | Set-AzRouteTable

#Associate the route table to the subnet

Set-AzVirtualNetworkSubnetConfig `
  -VirtualNetwork $VNetHub `
  -Name $SNnameGW `
  -AddressPrefix $SNGWHubPrefix `
  -RouteTable $routeTableHubSpoke | `
Set-AzVirtualNetwork

#Now, create the default route

#Create a table, with BGP route propagation disabled. The property is now called "Virtual network gateway route propagation," but the API still refers to the parameter as "DisableBgpRoutePropagation."
$routeTableSpokeDG = New-AzRouteTable `
  -Name 'UDR-DG' `
  -ResourceGroupName $RG1 `
  -location $Location1 `
  -DisableBgpRoutePropagation

#Create a route
Get-AzRouteTable `
  -ResourceGroupName $RG1 `
  -Name UDR-DG `
  | Add-AzRouteConfig `
  -Name "ToFirewall" `
  -AddressPrefix 0.0.0.0/0 `
  -NextHopType "VirtualAppliance" `
  -NextHopIpAddress $AzfwPrivateIP `
 | Set-AzRouteTable

#Associate the route table to the subnet

Set-AzVirtualNetworkSubnetConfig `
  -VirtualNetwork $VNetSpoke `
  -Name $SNnameSpoke `
  -AddressPrefix $SNSpokePrefix `
  -RouteTable $routeTableSpokeDG | `
Set-AzVirtualNetwork

创建虚拟机

创建分支工作负载与本地虚拟机,并将其放入相应的子网。

创建工作负荷虚拟机

在分支虚拟网络中创建运行 Internet Information Services (IIS)、没有公共 IP 地址并允许 ping 的虚拟机。 出现提示时,输入虚拟机的用户名和密码。

# Create an inbound network security group rule for ports 3389 and 80
$nsgRuleRDP = New-AzNetworkSecurityRuleConfig -Name Allow-RDP  -Protocol Tcp `
  -Direction Inbound -Priority 200 -SourceAddressPrefix * -SourcePortRange * -DestinationAddressPrefix $SNSpokePrefix -DestinationPortRange 3389 -Access Allow
$nsgRuleWeb = New-AzNetworkSecurityRuleConfig -Name Allow-web  -Protocol Tcp `
  -Direction Inbound -Priority 202 -SourceAddressPrefix * -SourcePortRange * -DestinationAddressPrefix $SNSpokePrefix -DestinationPortRange 80 -Access Allow

# Create a network security group
$nsg = New-AzNetworkSecurityGroup -ResourceGroupName $RG1 -Location $Location1 -Name NSG-Spoke02 -SecurityRules $nsgRuleRDP,$nsgRuleWeb

#Create the NIC
$NIC = New-AzNetworkInterface -Name spoke-01 -ResourceGroupName $RG1 -Location $Location1 -SubnetId $VnetSpoke.Subnets[0].Id -NetworkSecurityGroupId $nsg.Id

#Define the virtual machine
$VirtualMachine = New-AzVMConfig -VMName VM-Spoke-01 -VMSize "Standard_DS2"
$VirtualMachine = Set-AzVMOperatingSystem -VM $VirtualMachine -Windows -ComputerName Spoke-01 -ProvisionVMAgent -EnableAutoUpdate
$VirtualMachine = Add-AzVMNetworkInterface -VM $VirtualMachine -Id $NIC.Id
$VirtualMachine = Set-AzVMSourceImage -VM $VirtualMachine -PublisherName 'MicrosoftWindowsServer' -Offer 'WindowsServer' -Skus '2016-Datacenter' -Version latest

#Create the virtual machine
New-AzVM -ResourceGroupName $RG1 -Location $Location1 -VM $VirtualMachine -Verbose

#Install IIS on the VM
Set-AzVMExtension `
    -ResourceGroupName $RG1 `
    -ExtensionName IIS `
    -VMName VM-Spoke-01 `
    -Publisher Microsoft.Compute `
    -ExtensionType CustomScriptExtension `
    -TypeHandlerVersion 1.4 `
    -SettingString '{"commandToExecute":"powershell Add-WindowsFeature Web-Server"}' `
    -Location $Location1

#Create a host firewall rule to allow pings in
Set-AzVMExtension `
    -ResourceGroupName $RG1 `
    -ExtensionName IIS `
    -VMName VM-Spoke-01 `
    -Publisher Microsoft.Compute `
    -ExtensionType CustomScriptExtension `
    -TypeHandlerVersion 1.4 `
    -SettingString '{"commandToExecute":"powershell New-NetFirewallRule -DisplayName "Allow ICMPv4-In" -Protocol ICMPv4"}' `
    -Location $Location1

创建本地虚拟机

创建一个简单的虚拟机,可用于通过远程访问公共 IP 地址进行连接。 在此处,可以通过防火墙连接到本地服务器。 出现提示时,输入虚拟机的用户名和密码。

New-AzVm `
    -ResourceGroupName $RG1 `
    -Name "VM-Onprem" `
    -Location $Location1 `
    -VirtualNetworkName $VNetnameOnprem `
    -SubnetName $SNNameOnprem `
    -OpenPorts 3389 `
    -Size "Standard_DS2"

注意

Azure 会为未分配公共 IP 地址的 VM 或位于内部基本 Azure 负载均衡器的后端池中的 VM 提供默认出站访问 IP。 默认出站访问 IP 机制会提供不可配置的出站 IP 地址。

发生以下事件之一时,将禁用默认出站访问 IP:

  • 将公共 IP 地址分配给 VM。
  • 虚拟机被放置在标准负载平衡器的后端池中,有无出站规则均可。
  • 向虚拟机的子网分配了 Azure 虚拟网络 NAT 网关 资源。

在灵活业务流程模式下通过使用虚拟机规模集创建的 VM 没有默认的出站访问权限。

有关 Azure 中的出站连接的详细信息,请参阅 Azure 中的默认出站访问使用源网络地址转换 (SNAT) 进行出站连接

测试防火墙

  1. 获取并记下 VM-spoke-01 虚拟机的专用 IP 地址:

    $NIC.IpConfigurations.privateipaddress
    
  2. 在 Azure 门户中,连接到 VM-Onprem 虚拟机。

  3. VM-Onprem 上打开 Windows PowerShell 命令提示符,并 ping VM-spoke-01 的专用 IP。 应会收到回复。

  4. VM-Onprem 上打开 Web 浏览器,并浏览到 http://<VM-spoke-01 private IP>。 IIS 默认页应打开。

  5. VM-Onprem 中,在专用 IP 地址上打开与 VM-spoke-01 的远程访问连接。 连接应会成功,并且应该可以使用所选的用户名和密码登录。

验证防火墙规则是否正常工作后,可以:

  • 对分支虚拟网络上的服务器执行 Ping 操作。
  • 浏览到分支虚拟网络上的 Web 服务器。
  • 使用 RDP 连接到分支虚拟网络上的服务器。

接下来,运行以下脚本,将防火墙网络规则集合的操作更改为 Deny

$rcNet = $azfw.GetNetworkRuleCollectionByName("RCNet01")
$rcNet.action.type = "Deny"

Set-AzFirewall -AzureFirewall $azfw

关闭任何现有的远程访问连接。 再次运行测试以测试更改的规则。 这一次,这些规则应该全部失败。

清理资源

可以在下一教程中保留防火墙资源。 如果不再需要这些资源,请删除 FW-Hybrid-Test 资源组以删除所有与防火墙相关的资源。

后续步骤

监视 Azure 防火墙日志