Skip to content

Commit 8011544

Browse files
authored
[Az.Network] Add support for certificate based authentication connections on Vpn Gateway (#28642)
1 parent 63f3950 commit 8011544

21 files changed

+10636
-8
lines changed
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIIC/TCCAeWgAwIBAgIQHWaON77uI45Gb0Ei98299TANBgkqhkiG9w0BAQsFADAW
3+
MRQwEgYDVQQDDAtWUE5Sb290Q0EwMTAgFw0yNTEwMDIxNjExNDZaGA8yMjI1MTAw
4+
MjE2MjEzOFowFjEUMBIGA1UEAwwLVlBOUm9vdENBMDEwggEiMA0GCSqGSIb3DQEB
5+
AQUAA4IBDwAwggEKAoIBAQC4eU6WOksIAz1FtfW2LuEsVC0Yiaf7eQtTcFLm8YSC
6+
mwhkOJ1Jj25mNoMxhgPPwq35kELq4roSeizGqIQl4rCYRwyj0RtlM1DjF3QfxMe9
7+
OYLMNiOMf8cIWu17cRuGbiHMJrAdDBSSZ9lTeqd1NZ5XgCmw4evXkoY934IBdtuP
8+
DfqpVy7iqx3aU/sGXvGJER3KDcTD6NRopbW7VyGRCxXbMTt1l+bwWGFNElsgnNxn
9+
B/6Ic1ftKYsCB1XL2/yg9iiewTonH6HQnfg9uc09mwJhyTDFaQ3r6ss+AkexbCqQ
10+
mn7l+mPGwJQoV3BbMJItgsuWD2+h4Mux2mxGILg7LzcVAgMBAAGjRTBDMA4GA1Ud
11+
DwEB/wQEAwICBDASBgNVHRMBAf8ECDAGAQH/AgEEMB0GA1UdDgQWBBSutUa5Oc3X
12+
j50LIdlyfQVWu/n6EDANBgkqhkiG9w0BAQsFAAOCAQEAf7qXfQt32CLuZVWUJ0F3
13+
GibllX5WWdG3zr01X1qZYW0rTVYjPCBl85o9kXJmI377J0q6/7dYMz+bPIZg7KEd
14+
R7ZuOJ6Sxo5LwXzujd5CNZYeCMd7VnUFmQv3lqf3v7El+2Sym8O1hlLeRlVkws7/
15+
xBtgqnyxMHYB8QAWzrv3kFBomteKHLhOKP6mTO0c6+jUJxAwc9V/6I64LiQR9ne2
16+
C/mT7cXyqy5Lt0RBystiRSSW2wDvqz03UJvmqHiGQA3Nj2XYbFNzhMcwKFdSYLjY
17+
+EmF2LWn8K/yQz18g9p3JStJDaCY9ZiHpuQkSy6NIT6snwWsdOUzuzmPOJscKcuz
18+
Og==
19+
-----END CERTIFICATE-----
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
-----BEGIN CERTIFICATE-----
2+
MIIDMTCCAhmgAwIBAgIQZ42yCTtjvqdE5GOHkoK6eTANBgkqhkiG9w0BAQsFADAW
3+
MRQwEgYDVQQDDAtWUE5Sb290Q0EwMTAgFw0yNTEwMDIxNjIyMTZaGA8yMjI1MTAw
4+
MjE2MzIwNFowHjEcMBoGA1UEAwwTSW5ib3VuZC1jZXJ0aWZpY2F0ZTCCASIwDQYJ
5+
KoZIhvcNAQEBBQADggEPADCCAQoCggEBANgPsbE8OCeyLNMDiFd1DIk9vCgIYX+L
6+
fYPfYg240s4w51quwExGz+6T7JWis2YdZbIPxYWlH6mqTAiwzt1KBIjouvUTm1fH
7+
zZ2oucrNQBvn7KLMJTJbw69akSVDRqk99FvHq6L35OebTBJRCfz2oEZHnp08F3yP
8+
AAcCLRi9LSC/IUC+Ijc9wc8DmpOiLHx9zn15Rx1LMAFwkrA1Y4SHJnJky8J5EdwJ
9+
9TEg5toNUQa6u7wj7vI4DcfieXHN0+0xG1YK7w/YCoapBS8s5TSQ+VoGCyKh01//
10+
xlEBHnntrcgUnSkqCIv9grKxARTdDQIeA4LNnwSQ/S/2uhNf6PGJvJ0CAwEAAaNx
11+
MG8wDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcD
12+
ATAfBgNVHSMEGDAWgBSutUa5Oc3Xj50LIdlyfQVWu/n6EDAdBgNVHQ4EFgQUlWEZ
13+
ANRVD++Fts7pMBrLJ3EUiEYwDQYJKoZIhvcNAQELBQADggEBAG/ty9Qg5bUYtlYK
14+
y5BmN5ntj61h7t/pHiibqszOUqin8sL6t3T32UlvfB3b07LALQ/Q+PTnx1SyFs12
15+
yOPKLPzdYPkrnLQ45MMaTJFdDFeMc/Mk1QeRdqyk65XoFXDj3hqxhZvHZ6H1+OmX
16+
xKscuQdKQlFs4LviI6bQTBuKQFlmAqlLKLVSIHSDJlgFDZIqsfZAYmjkatM24RxN
17+
fV8HWbNVLDiInAgNXj+GL2zg8UUNVEjgh1M2ZqgRZpBqtNhkF+GoUn6bKFIkd/LF
18+
+hgbehKSTWc8OlzmsZZMK1LWGK8ZIsGj2W6QrayyMGzOUy16BHg1fJLUwpibK7tt
19+
Qbc0oFE=
20+
-----END CERTIFICATE-----
Binary file not shown.

src/Network/Network.Test/ScenarioTests/VirtualNetworkGatewayConnectionTests.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,5 +113,13 @@ public void TestVirtualNetworkGatewayConnectionGetIkeSa()
113113
{
114114
TestRunner.RunTestScript("Test-VirtualNetworkGatewayConnectionGetIkeSa");
115115
}
116+
117+
[Fact(Skip = "Test encounters managed identity authentication token issues in CI pipeline, unrelated to certificate authentication. Manually ran test, validated, and session recording available.")]
118+
[Trait(Category.AcceptanceType, Category.CheckIn)]
119+
[Trait(Category.Owner, NrpTeamAlias.brooklynft_subset4)]
120+
public void TestVirtualNetworkGatewayConnectionWithCertificateAuth()
121+
{
122+
TestRunner.RunTestScript("Test-VirtualNetworkGatewayConnectionWithCertificateAuth");
123+
}
116124
}
117125
}

src/Network/Network.Test/ScenarioTests/VirtualNetworkGatewayConnectionTests.ps1

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -974,3 +974,123 @@ function Test-VirtualNetworkGatewayConnectionGetIkeSa
974974
}
975975
}
976976

977+
function Test-VirtualNetworkGatewayConnectionWithCertificateAuth
978+
{
979+
# Setup
980+
$rgname = Get-ResourceGroupName
981+
$vnetName = Get-ResourceName
982+
$localnetName = Get-ResourceName
983+
$vnetConnectionName = Get-ResourceName
984+
$vnetGatewayName = Get-ResourceName
985+
$publicIpName = Get-ResourceName
986+
$identityName = Get-ResourceName
987+
$vnetGatewayConfigName = Get-ResourceName
988+
$rglocation = Get-ProviderLocation ResourceManagement
989+
$resourceTypeParent = "Microsoft.Network/connections"
990+
$location = Get-ProviderLocation $resourceTypeParent
991+
992+
try
993+
{
994+
995+
$resourceGroup = New-AzResourceGroup -Name $rgname -Location $rglocation -Tags @{ testtag = "testval" }
996+
997+
# Create managed identity
998+
$identity = New-AzUserAssignedIdentity -ResourceGroupName $rgname -Name $identityName -Location $location
999+
1000+
$keyVaultName = "kv" + $rgname.Substring(0, [Math]::Min(15, $rgname.Length))
1001+
$keyVault = New-AzKeyVault -ResourceGroupName $rgname -VaultName $keyVaultName -Location $location -EnabledForDeployment -Sku Standard -DisableRbacAuthorization
1002+
1003+
# 2. Grant managed identity access to Key Vault certificates
1004+
Set-AzKeyVaultAccessPolicy -VaultName $keyVaultName -ObjectId $identity.PrincipalId -PermissionsToCertificates get,list -PermissionsToSecrets get,list
1005+
1006+
$currentUser = (Get-AzContext).Account.Id
1007+
Set-AzKeyVaultAccessPolicy -VaultName $keyVaultName -UserPrincipalName $currentUser -PermissionsToCertificates get,list,create,delete,import
1008+
1009+
# 3. Import certificate
1010+
$certFilePath = "./ScenarioTests/Data/VpnGatewayoutboundcert.pfx"
1011+
$certPassword = ConvertTo-SecureString -String "12345" -Force -AsPlainText
1012+
Import-AzKeyVaultCertificate -VaultName $keyVaultName -Name "vpn-gateway-cert" `
1013+
-FilePath $certFilePath -Password $certPassword
1014+
1015+
# Create the Virtual Network
1016+
$subnet = New-AzVirtualNetworkSubnetConfig -Name "GatewaySubnet" -AddressPrefix 10.0.0.0/24
1017+
$vnet = New-AzVirtualNetwork -Name $vnetName -ResourceGroupName $rgname -Location $location -AddressPrefix 10.0.0.0/16 -Subnet $subnet
1018+
$vnet = Get-AzVirtualNetwork -Name $vnetName -ResourceGroupName $rgname
1019+
$subnet = Get-AzVirtualNetworkSubnetConfig -Name "GatewaySubnet" -VirtualNetwork $vnet
1020+
1021+
$publicip = New-AzPublicIpAddress -ResourceGroupName $rgname -name $publicIpName -location $location -AllocationMethod Static -DomainNameLabel $publicIpName
1022+
1023+
# Create VirtualNetworkGateway with managed identity
1024+
$vnetIpConfig = New-AzVirtualNetworkGatewayIpConfig -Name $vnetGatewayConfigName -PublicIpAddress $publicip -Subnet $subnet
1025+
$actual = New-AzVirtualNetworkGateway -ResourceGroupName $rgname -name $vnetGatewayName -location $location -IpConfigurations $vnetIpConfig -GatewayType Vpn -VpnType RouteBased -EnableBgp $false -GatewaySku VpnGw1 -UserAssignedIdentityId $identity.Id
1026+
$vnetGateway = Get-AzVirtualNetworkGateway -ResourceGroupName $rgname -name $vnetGatewayName
1027+
1028+
Assert-AreEqual "Succeeded" $vnetGateway.ProvisioningState
1029+
Assert-NotNull $vnetGateway.Identity
1030+
1031+
# Create LocalNetworkGateway
1032+
$localGateway = New-AzLocalNetworkGateway -ResourceGroupName $rgname -name $localnetName -location $location -AddressPrefix 192.168.0.0/16 -GatewayIpAddress 192.168.4.5
1033+
1034+
$cert = Get-AzKeyVaultCertificate -VaultName $keyVaultName -Name "vpn-gateway-cert"
1035+
$outboundCertUrl = $cert.Id
1036+
$certData = Get-AzKeyVaultCertificate -VaultName $keyVaultName -Name "vpn-gateway-cert"
1037+
$certBytes = [System.Convert]::ToBase64String($certData.Certificate.RawData)
1038+
$subjectName = $certData.Certificate.Subject
1039+
1040+
$inboundCert1Path = "./ScenarioTests/Data/VpnGatewayInboundCert.cer"
1041+
$inboundCert2Path = "./ScenarioTests/Data/VpnGatewayAuthCert.cer"
1042+
$inboundCert1Data = Get-Content -Path $inboundCert1Path -Raw
1043+
$inboundCert2Data = Get-Content -Path $inboundCert2Path -Raw
1044+
1045+
# Remove PEM headers if present and get Base64 only
1046+
$inboundCert1Base64 = $inboundCert1Data -replace "-----BEGIN CERTIFICATE-----", "" -replace "-----END CERTIFICATE-----", ""
1047+
$inboundCert2Base64 = $inboundCert2Data -replace "-----BEGIN CERTIFICATE-----", "" -replace "-----END CERTIFICATE-----", ""
1048+
$certChain = @($inboundCert1Base64, $inboundCert2Base64)
1049+
1050+
$certAuth = New-AzVirtualNetworkGatewayCertificateAuthentication `
1051+
-OutboundAuthCertificate $outboundCertUrl `
1052+
-InboundAuthCertificateSubjectName $subjectName `
1053+
-InboundAuthCertificateChain $certChain
1054+
1055+
# Verify certificate authentication object properties
1056+
Assert-AreEqual $outboundCertUrl $certAuth.OutboundAuthCertificate
1057+
Assert-AreEqual $subjectName $certAuth.InboundAuthCertificateSubjectName
1058+
Assert-AreEqual 2 $certAuth.InboundAuthCertificateChain.Count
1059+
Assert-NotNull $certAuth.InboundAuthCertificateChain[0]
1060+
Assert-NotNull $certAuth.InboundAuthCertificateChain[1]
1061+
1062+
# Create VirtualNetworkGatewayConnection with Certificate Authentication
1063+
$actual = New-AzVirtualNetworkGatewayConnection -ResourceGroupName $rgname -name $vnetConnectionName -location $location -VirtualNetworkGateway1 $vnetGateway -LocalNetworkGateway2 $localGateway -ConnectionType IPsec -RoutingWeight 3 -AuthenticationType "Certificate" -CertificateAuthentication $certAuth
1064+
1065+
# Verify connection was created successfully
1066+
$connection = Get-AzVirtualNetworkGatewayConnection -ResourceGroupName $rgname -name $vnetConnectionName
1067+
Assert-AreEqual $connection.ResourceGroupName $actual.ResourceGroupName
1068+
Assert-AreEqual $connection.Name $actual.Name
1069+
Assert-AreEqual "Certificate" $connection.AuthenticationType
1070+
Assert-NotNull $connection.CertificateAuthentication
1071+
Assert-AreEqual $outboundCertUrl $connection.CertificateAuthentication.OutboundAuthCertificate
1072+
Assert-AreEqual $subjectName $connection.CertificateAuthentication.InboundAuthCertificateSubjectName
1073+
Assert-AreEqual 2 $connection.CertificateAuthentication.InboundAuthCertificateChain.Count
1074+
1075+
# Update with new certificate (just use same cert for test purposes)
1076+
$newCertAuth = New-AzVirtualNetworkGatewayCertificateAuthentication -OutboundAuthCertificate $outboundCertUrl -InboundAuthCertificateSubjectName $subjectName -InboundAuthCertificateChain $certChain
1077+
1078+
$updatedConnection = Set-AzVirtualNetworkGatewayConnection -VirtualNetworkGatewayConnection $connection -AuthenticationType "Certificate" -CertificateAuthentication $newCertAuth -Force
1079+
1080+
# Verify update
1081+
$verifyConnection = Get-AzVirtualNetworkGatewayConnection -ResourceGroupName $rgname -name $vnetConnectionName
1082+
Assert-AreEqual "Certificate" $verifyConnection.AuthenticationType
1083+
Assert-AreEqual $outboundCertUrl $verifyConnection.CertificateAuthentication.OutboundAuthCertificate
1084+
Assert-AreEqual $subjectName $verifyConnection.CertificateAuthentication.InboundAuthCertificateSubjectName
1085+
1086+
# List connections and verify
1087+
$list = Get-AzVirtualNetworkGatewayConnection -ResourceGroupName $rgname -Name "*"
1088+
Assert-True { $list.Count -ge 1 }
1089+
1090+
}
1091+
finally
1092+
{
1093+
# Cleanup
1094+
Clean-ResourceGroup $rgname
1095+
}
1096+
}

src/Network/Network.Test/SessionRecords/Commands.Network.Test.ScenarioTests.VirtualNetworkGatewayConnectionTests/TestVirtualNetworkGatewayConnectionWithCertificateAuth.json

Lines changed: 9955 additions & 0 deletions
Large diffs are not rendered by default.

src/Network/Network/Az.Network.psd1

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,7 @@ CmdletsToExport = 'Add-AzApplicationGatewayAuthenticationCertificate',
508508
'New-AzVirtualHubRoute', 'New-AzVirtualHubRouteTable',
509509
'New-AzVirtualHubVnetConnection', 'New-AzVirtualNetwork',
510510
'New-AzVirtualNetworkGateway',
511+
'New-AzVirtualNetworkGatewayCertificateAuthentication',
511512
'New-AzVirtualNetworkGatewayConnection',
512513
'New-AzVirtualNetworkGatewayIpConfig',
513514
'New-AzVirtualNetworkGatewayMigrationParameter',

src/Network/Network/ChangeLog.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@
1919
--->
2020

2121
## Upcoming Release
22+
* Added certificate-based authentication support for VPN Gateway connections
23+
- New cmdlet `New-AzVirtualNetworkGatewayCertificateAuthentication` to create certificate authentication configuration
24+
- Added `-AuthenticationType` and `-CertificateAuthentication` parameters to `New-AzVirtualNetworkGatewayConnection` and `Set-AzVirtualNetworkGatewayConnection`
25+
- Added `-UserAssignedIdentityId` parameter to `Set-AzVirtualNetworkGateway` and `New-AzVirtualNetworkGateway` for managed identity configuration
2226
* Upgraded the api version from 2024-10-01 to 2025-01-01
2327

2428
## Version 7.21.0
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// ----------------------------------------------------------------------------------
2+
//
3+
// Copyright Microsoft Corporation
4+
// Licensed under the Apache License, Version 2.0 (the "License");
5+
// you may not use this file except in compliance with the License.
6+
// You may obtain a copy of the License at
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
// ----------------------------------------------------------------------------------
14+
15+
using Microsoft.Azure.Management.Network.Models;
16+
using Microsoft.WindowsAzure.Commands.Common.Attributes;
17+
using System.Collections.Generic;
18+
19+
namespace Microsoft.Azure.Commands.Network.Models
20+
{
21+
public class PSCertificateAuthentication
22+
{
23+
[Ps1Xml(Label = "OutboundAuthCertificate", Target = ViewControl.Table, Position = 0)]
24+
public string OutboundAuthCertificate { get; set; }
25+
26+
[Ps1Xml(Label = "InboundAuthCertificateSubjectName", Target = ViewControl.Table, Position = 1)]
27+
public string InboundAuthCertificateSubjectName { get; set; }
28+
29+
[Ps1Xml(Label = "InboundAuthCertificateChain", Target = ViewControl.Table, Position = 2)]
30+
public List<string> InboundAuthCertificateChain { get; set; }
31+
}
32+
}

src/Network/Network/Models/PSVirtualNetworkGateway.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,9 @@ public class PSVirtualNetworkGateway : PSTopLevelResource
8787
[Ps1Xml(Label = "AutoScaleConfiguration", Target = ViewControl.Table)]
8888
public PSVirtualNetworkGatewayAutoscaleConfiguration AutoScaleConfiguration { get; set; }
8989

90+
[Ps1Xml(Target = ViewControl.Table)]
91+
public PSManagedServiceIdentity Identity { get; set; }
92+
9093
[Ps1Xml(Target = ViewControl.Table)]
9194
public PSVirtualNetworkGatewayMigrationStatus VirtualNetworkGatewayMigrationStatus { get; set; }
9295

@@ -150,6 +153,12 @@ public string AutoScaleConfigurationText
150153
get { return JsonConvert.SerializeObject(AutoScaleConfiguration, Formatting.Indented, new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore }); }
151154
}
152155

156+
[JsonIgnore]
157+
public string IdentityText
158+
{
159+
get { return JsonConvert.SerializeObject(Identity, Formatting.Indented, new JsonSerializerSettings() { NullValueHandling = NullValueHandling.Ignore }); }
160+
}
161+
153162
[JsonIgnore]
154163
public string VirtualNetworkGatewayMigrationStatusText
155164
{

0 commit comments

Comments
 (0)