Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/Network/Network.Test/ScenarioTests/AzureFirewallTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,5 +74,12 @@ public void TestAzureFirewallThreatIntelWhitelistCRUD()
TestRunner.RunTestScript("Test-AzureFirewallThreatIntelWhitelistCRUD");
}

[Fact]
[Trait(Category.AcceptanceType, Category.CheckIn)]
[Trait(Category.Owner, NrpTeamAlias.azurefirewall)]
public void TestAzureFirewallPrivateRangeCRUD()
{
TestRunner.RunTestScript("Test-AzureFirewallPrivateRangeCRUD");
}
}
}
53 changes: 50 additions & 3 deletions src/Network/Network.Test/ScenarioTests/AzureFirewallTests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ function Test-AzureFirewallCRUD {
$networkRule1Protocol3 = "ICMP"
$networkRule1DestinationPort1 = "90"

# AzureFirewallNetworkRule 2
# AzureFirewallNetworkRule 2
$networkRule2Name = "networkRule2"
$networkRule2Desc = "desc2"
$networkRule2SourceAddress1 = "10.0.0.0"
Expand All @@ -107,7 +107,7 @@ function Test-AzureFirewallCRUD {
$natRule1TranslatedAddress = "10.1.2.3"
$natRule1TranslatedPort = "91"

# AzureFirewallNatRule 2
# AzureFirewallNatRule 2
$natRule2Name = "natRule2"
$natRule2Desc = "desc2"
$natRule2SourceAddress1 = "10.0.0.0"
Expand Down Expand Up @@ -1172,7 +1172,7 @@ function Test-AzureFirewallThreatIntelWhitelistCRUD {
$publicIpName = Get-ResourceName

$threatIntelWhitelist1 = New-AzFirewallThreatIntelWhitelist -FQDN @("*.microsoft.com", "microsoft.com") -IpAddress @("8.8.8.8", "1.1.1.1")
$threatIntelWhitelist2 = New-AzFirewallThreatIntelWhitelist -IpAddress @(" 2.2.2.2 "," 3.3.3.3 ") -FQDN @(" bing.com ", "yammer.com ")
$threatIntelWhitelist2 = New-AzFirewallThreatIntelWhitelist -IpAddress @(" 2.2.2.2 ", " 3.3.3.3 ") -FQDN @(" bing.com ", "yammer.com ")

try {
# Create the resource group
Expand Down Expand Up @@ -1205,3 +1205,50 @@ function Test-AzureFirewallThreatIntelWhitelistCRUD {
Clean-ResourceGroup $rgname
}
}

<#
.SYNOPSIS
Tests AzureFirewall PrivateRange
#>
function Test-AzureFirewallPrivateRangeCRUD {
$rgname = Get-ResourceGroupName
$azureFirewallName = Get-ResourceName
$resourceTypeParent = "Microsoft.Network/AzureFirewalls"
$location = Get-ProviderLocation $resourceTypeParent "eastus"

$vnetName = Get-ResourceName
$subnetName = "AzureFirewallSubnet"
$publicIpName = Get-ResourceName

$privateRange1 = @("IANAPrivateRanges", "0.0.0.0/0", "66.92.0.0/16")
$privateRange2 = @("3.3.0.0/24", "98.0.0.0/8")

try {
# Create the resource group
$resourceGroup = New-AzResourceGroup -Name $rgname -Location $location

# Create the Virtual Network
$subnet = New-AzVirtualNetworkSubnetConfig -Name $subnetName -AddressPrefix 10.0.0.0/24
$vnet = New-AzVirtualNetwork -Name $vnetName -ResourceGroupName $rgname -Location $location -AddressPrefix 10.0.0.0/16 -Subnet $subnet

# Create public ip
$publicip = New-AzPublicIpAddress -ResourceGroupName $rgname -name $publicIpName -location $location -AllocationMethod Static -Sku Standard

# Create AzureFirewall
$azureFirewall = New-AzFirewall -Name $azureFirewallName -ResourceGroupName $rgname -Location $location -PrivateRange $privateRange1

# Verify
$getAzureFirewall = Get-AzFirewall -Name $azureFirewallName -ResourceGroupName $rgname
Assert-AreEqualArray $privateRange1 $getAzureFirewall.PrivateRange

# Modify
$azureFirewall.PrivateRange = $privateRange2
Set-AzFirewall -AzureFirewall $azureFirewall
$getAzureFirewall = Get-AzFirewall -Name $azureFirewallName -ResourceGroupName $rgname
Assert-AreEqualArray $privateRange2 $getAzureFirewall.PrivateRange
}
finally {
# Cleanup
Clean-ResourceGroup $rgname
}
}

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions src/Network/Network/AzureFirewall/NewAzureFirewallCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,12 @@ public class NewAzureFirewallCommand : AzureFirewallBaseCmdlet
HelpMessage = "The whitelist for Threat Intelligence")]
public PSAzureFirewallThreatIntelWhitelist ThreatIntelWhitelist { get; set; }

[Parameter(
Mandatory = false,
HelpMessage = "The private IP ranges to which traffic won't be SNAT'ed"
)]
public string[] PrivateRange { get; set; }

[Parameter(
Mandatory = false,
ValueFromPipelineByPropertyName = true,
Expand Down Expand Up @@ -262,6 +268,7 @@ private PSAzureFirewall CreateAzureFirewall()
NetworkRuleCollections = this.NetworkRuleCollection?.ToList(),
ThreatIntelMode = this.ThreatIntelMode ?? MNM.AzureFirewallThreatIntelMode.Alert,
ThreatIntelWhitelist = this.ThreatIntelWhitelist,
PrivateRange = this.PrivateRange,
Sku = sku
};

Expand Down
3 changes: 3 additions & 0 deletions src/Network/Network/ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@

## Upcoming Release
* Change `Start-AzVirtualNetworkGatewayConnectionPacketCapture.md` and `Start-AzVirtualnetworkGatewayPacketCapture.md` FilterData option examples.
* Add `PrivateRange` parameter to `AzureFirewall`
- Updated cmdlet:
- New-AzFirewall

## Version 2.0.0
* Change all cmdlets for PrivateEndpointConnection to support generic service provider.
Expand Down
9 changes: 9 additions & 0 deletions src/Network/Network/Common/NetworkResourceManagerProfile.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1160,6 +1160,7 @@ private static void Initialize()
{
{ "ThreatIntel.Whitelist.FQDNs", src.ThreatIntelWhitelist?.FQDNs?.Aggregate((result, item) => result + "," + item) },
{ "ThreatIntel.Whitelist.IpAddresses", src.ThreatIntelWhitelist?.IpAddresses?.Aggregate((result, item) => result + "," + item) },
{ "Network.SNAT.PrivateRanges", src.PrivateRange?.Aggregate((result, item) => result + "," + item) }
}.Where(kvp => kvp.Value != null).ToDictionary(key => key.Key, val => val.Value); // TODO: remove after backend code is refactored
});
cfg.CreateMap<CNM.PSAzureFirewallSku, MNM.AzureFirewallSku>();
Expand Down Expand Up @@ -1195,6 +1196,14 @@ private static void Initialize()
{
dest.ThreatIntelWhitelist.IpAddresses = null;
}
try
{
dest.PrivateRange = src.AdditionalProperties?.SingleOrDefault(kvp => kvp.Key.Equals("Network.SNAT.PrivateRanges", StringComparison.OrdinalIgnoreCase)).Value?.Split(',').Select(str => str.Trim()).ToArray();
}
catch (PSArgumentException)
{
dest.ThreatIntelWhitelist.IpAddresses = null;
}
});
cfg.CreateMap<MNM.AzureFirewallSku, CNM.PSAzureFirewallSku>();
cfg.CreateMap<MNM.AzureFirewallIPConfiguration, CNM.PSAzureFirewallIpConfiguration>();
Expand Down
73 changes: 72 additions & 1 deletion src/Network/Network/Models/AzureFirewall/PSAzureFirewall.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Management.Automation;
using System.Net;
using Microsoft.Rest;
using Newtonsoft.Json;

namespace Microsoft.Azure.Commands.Network.Models
Expand All @@ -24,7 +27,9 @@ public class PSAzureFirewall : PSTopLevelResource
{
private const string AzureFirewallSubnetName = "AzureFirewallSubnet";
private const string AzureFirewallIpConfigurationName = "AzureFirewallIpConfiguration";
private const string IANAPrivateRanges = "IANAPrivateRanges";

private string[] privateRange;

public List<PSAzureFirewallIpConfiguration> IpConfigurations { get; set; }

Expand All @@ -44,6 +49,19 @@ public class PSAzureFirewall : PSTopLevelResource

public PSAzureFirewallThreatIntelWhitelist ThreatIntelWhitelist { get; set; }

public string[] PrivateRange {
get
{
return this.privateRange;
}
set
{
if (value != null)
ValidatePrivateRange(value);
privateRange = value;
}
}

public string ProvisioningState { get; set; }

public List<string> Zones { get; set; }
Expand Down Expand Up @@ -78,6 +96,12 @@ public string ThreatIntelWhitelistText
get { return JsonConvert.SerializeObject(ThreatIntelWhitelist, Formatting.Indented); }
}

[JsonIgnore]
public string PrivateRangeText
{
get { return JsonConvert.SerializeObject(PrivateRange, Formatting.Indented); }
}

#region Ip Configuration Operations

public void Allocate(PSVirtualNetwork virtualNetwork, PSPublicIpAddress[] publicIpAddresses)
Expand Down Expand Up @@ -272,6 +296,54 @@ public void RemoveNetworkRuleCollectionByPriority(uint priority)

#endregion // Application Rule Collections Operations

#region Private Range Validation
private void ValidatePrivateRange(string[] privateRange)
{
foreach (var ip in privateRange)
{
if (ip.Equals(IANAPrivateRanges, StringComparison.OrdinalIgnoreCase))
continue;

if (ip.Contains("/"))
ValidateMaskedIpAddress(ip);
else
ValidateSingleIpAddress(ip);
}
}

private void ValidateSingleIpAddress(string ipAddress)
{
IPAddress ipVal;
if (!IPAddress.TryParse(ipAddress, out ipVal) || ipVal.AddressFamily != System.Net.Sockets.AddressFamily.InterNetwork)
{
throw new PSArgumentException(String.Format("\'{0}\' is not a valid private range ip address", ipAddress));
}
}

private void ValidateMaskedIpAddress(string ipAddress)
{
var split = ipAddress.Split('/');
if (split.Length != 2)
throw new PSArgumentException(String.Format("\'{0}\' is not a valid private range ip address", ipAddress));

// validate the ip
ValidateSingleIpAddress(split[0]);

// validate mask
var bit = 0;
if (!Int32.TryParse(split[1], out bit) || bit < 0 || bit > 32)
throw new PSArgumentException(String.Format("\'{0}\' is not a valid private range ip address, subnet mask should between 0 and 32", ipAddress));

// validated that unmasked bits are 0
var splittedIp = split[0].Split('.');
var ip = Int32.Parse(splittedIp[0]) << 24;
ip = ip + Int32.Parse(splittedIp[1]) << 16 + Int32.Parse(splittedIp[2]) << 8 + Int32.Parse(splittedIp[3]);
if (ip << bit != 0)
throw new PSArgumentException(String.Format("\'{0}\' is not a valid private range ip address, bits not covered by subnet mask should be all 0", ipAddress));
}

#endregion

#region Private Methods

private List<BaseRuleCollection> AddRuleCollection<BaseRuleCollection>(BaseRuleCollection ruleCollection, List<BaseRuleCollection> existingRuleCollections) where BaseRuleCollection : PSAzureFirewallBaseRuleCollection
Expand Down Expand Up @@ -301,7 +373,6 @@ private BaseRuleCollection GetRuleCollectionByName<BaseRuleCollection>(string ru

return ruleCollection;
}

#endregion // Private Methods
}
}
4 changes: 4 additions & 0 deletions src/Network/Network/Network.format.ps1xml
Original file line number Diff line number Diff line change
Expand Up @@ -3298,6 +3298,10 @@
<Label>ThreatIntelWhitelist</Label>
<PropertyName>ThreatIntelWhitelistText</PropertyName>
</ListItem>
<ListItem>
<Label>PrivateRange</Label>
<PropertyName>PrivateRangeText</PropertyName>
</ListItem>
<ListItem>
<Label>Sku</Label>
<PropertyName>Sku</PropertyName>
Expand Down
38 changes: 32 additions & 6 deletions src/Network/Network/help/New-AzFirewall.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ New-AzFirewall -Name <String> -ResourceGroupName <String> -Location <String>
[-ApplicationRuleCollection <PSAzureFirewallApplicationRuleCollection[]>]
[-NatRuleCollection <PSAzureFirewallNatRuleCollection[]>]
[-NetworkRuleCollection <PSAzureFirewallNetworkRuleCollection[]>] [-ThreatIntelMode <String>]
[-ThreatIntelWhitelist <PSAzureFirewallThreatIntelWhitelist>] [-Tag <Hashtable>] [-Force] [-AsJob]
[-Zone <String[]>] [-Sku <String>] [-VirtualHubId <String>] [-FirewallPolicyId <String>]
[-ThreatIntelWhitelist <PSAzureFirewallThreatIntelWhitelist>] [-PrivateRange <String[]>] [-Tag <Hashtable>]
[-Force] [-AsJob] [-Zone <String[]>] [-Sku <String>] [-VirtualHubId <String>] [-FirewallPolicyId <String>]
[-DefaultProfile <IAzureContextContainer>] [-WhatIf] [-Confirm] [<CommonParameters>]
```

Expand All @@ -30,8 +30,8 @@ New-AzFirewall -Name <String> -ResourceGroupName <String> -Location <String> -Vi
-PublicIpName <String> [-ApplicationRuleCollection <PSAzureFirewallApplicationRuleCollection[]>]
[-NatRuleCollection <PSAzureFirewallNatRuleCollection[]>]
[-NetworkRuleCollection <PSAzureFirewallNetworkRuleCollection[]>] [-ThreatIntelMode <String>]
[-ThreatIntelWhitelist <PSAzureFirewallThreatIntelWhitelist>] [-Tag <Hashtable>] [-Force] [-AsJob]
[-Zone <String[]>] [-Sku <String>] [-VirtualHubId <String>] [-FirewallPolicyId <String>]
[-ThreatIntelWhitelist <PSAzureFirewallThreatIntelWhitelist>] [-PrivateRange <String[]>] [-Tag <Hashtable>]
[-Force] [-AsJob] [-Zone <String[]>] [-Sku <String>] [-VirtualHubId <String>] [-FirewallPolicyId <String>]
[-DefaultProfile <IAzureContextContainer>] [-WhatIf] [-Confirm] [<CommonParameters>]
```

Expand All @@ -42,8 +42,8 @@ New-AzFirewall -Name <String> -ResourceGroupName <String> -Location <String> -Vi
[-ApplicationRuleCollection <PSAzureFirewallApplicationRuleCollection[]>]
[-NatRuleCollection <PSAzureFirewallNatRuleCollection[]>]
[-NetworkRuleCollection <PSAzureFirewallNetworkRuleCollection[]>] [-ThreatIntelMode <String>]
[-ThreatIntelWhitelist <PSAzureFirewallThreatIntelWhitelist>] [-Tag <Hashtable>] [-Force] [-AsJob]
[-Zone <String[]>] [-Sku <String>] [-VirtualHubId <String>] [-FirewallPolicyId <String>]
[-ThreatIntelWhitelist <PSAzureFirewallThreatIntelWhitelist>] [-PrivateRange <String[]>] [-Tag <Hashtable>]
[-Force] [-AsJob] [-Zone <String[]>] [-Sku <String>] [-VirtualHubId <String>] [-FirewallPolicyId <String>]
[-DefaultProfile <IAzureContextContainer>] [-WhatIf] [-Confirm] [<CommonParameters>]
```

Expand Down Expand Up @@ -172,6 +172,17 @@ New-AzFirewall -Name "azFw" -ResourceGroupName $rgName -Location centralus -Virt

This example creates a Firewall that whitelist "www.microsoft.com" and "8.8.8.8" from threat intelligence

### 11: Create a Firewall with customized private range setup
```
$rgName = "resourceGroupName"
$vnet = Get-AzVirtualNetwork -ResourceGroupName $rgName -Name "vnet"
$pip = Get-AzPublicIpAddress -ResourceGroupName $rgName -Name "publicIpName"

New-AzFirewall -Name "azFw" -ResourceGroupName $rgName -Location centralus -VirtualNetwork $vnet -PublicIpAddress $pip -PrivateRange @("99.99.99.0/24", "66.66.0.0/16")
```

This example creates a Firewall that treats "99.99.99.0/24" and "66.66.0.0/16" as private ip ranges and won't snat traffic to those addresses

## PARAMETERS

### -ApplicationRuleCollection
Expand Down Expand Up @@ -309,6 +320,21 @@ Accept pipeline input: True (ByPropertyName)
Accept wildcard characters: False
```

### -PrivateRange
The private IP ranges to which traffic won't be SNAT'ed

```yaml
Type: System.String[]
Parameter Sets: (All)
Aliases:

Required: False
Position: Named
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```

### -PublicIpAddress
One or more Public IP Addresses. The Public IP addresses must use Standard SKU and must belong to the same resource group as the Firewall.

Expand Down