-
Notifications
You must be signed in to change notification settings - Fork 124
Network-25535 : Outbound traffic from VNET integrated workloads is routed through Azure Firewall #746
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Network-25535 : Outbound traffic from VNET integrated workloads is routed through Azure Firewall #746
Changes from 9 commits
Commits
Show all changes
202 commits
Select commit
Hold shift + click to select a range
1beb554
Feature-25403
Manoj-Kesana 395f293
Fixed Naming Convention
Manoj-Kesana 001c8f2
Moved Variables to assessment logic
Manoj-Kesana 8548042
35001 - Add test for Conditional Access RMS exclusions
alexandair 37680c1
35002 - Add test for Cross-Tenant Access Policy (XTAP) RMS settings
alexandair 9cc8c87
35003 - Add test for sensitivity label configuration and reporting
alexandair 4da6083
Change Pillar from 'Devices' to 'Data'
alexandair 59df975
35004 - Add test for Published Label Policies assessment
alexandair 5fb4b57
35005 - Add test for sensitivity labels in SharePoint Online assessment
alexandair fa99b68
35006- Add tests for PDF labeling support in SharePoint Online
alexandair 4511f3e
35007 - Add test for Information Rights Management (IRM) in SharePoin…
alexandair dc05324
35008 - Add test for SPO Default Site Label (Tenant-Wide)
alexandair f0f20f1
Merge branch 'main' of https://github.com/microsoft/zerotrustassessme…
Manoj-Kesana 1102a8e
Update src/powershell/tests/Test-Assessment.35008.md
alexandair d0aa4dc
Fix policy link to be consistent to other tests
alexandair a5605a2
Update MinimumLicense to Microsoft 365 E5 based on new spec
alexandair a41c2ef
Update Conditional Access policy instructions for RMS exclusion
alexandair db458f0
Remove unnecessary module imports from Test-Assessment-35001 setup
alexandair 06f6bd9
Refactor Test-Assessment-35001 for improved readability and consisten…
alexandair e03c9ee
added test file
ashwinikarke 478fddd
Initial commit for 25535
kshitiz-prog cba56d8
updated code with updated SPEC
Manoj-Kesana ddba135
Update MinimumLicense to Microsoft 365 E5
alexandair 007c208
Inconsistency in checking which location properties indicate "All Use…
alexandair 59b81b1
Update MinimumLicense from 'MIP_P1' to 'Microsoft 365 E3'
alexandair 28d6cda
Update MinimumLicense from MIP_P1 to Microsoft 365 E3
alexandair cf693a5
Fix typo in Test-Assessment.35005.md
alexandair c3d96e8
Add a null check ensuring that $spoTenant cannot be null
alexandair cb76b24
Fix a typo in Test-Assessment.35006.ps1
alexandair 56b7eb2
Add test case for handling null response from Get-SPOTenant
alexandair 0a35e24
Rename $testResultDetail to $params for consistency with other test f…
alexandair 0a507c5
Refactor assessment logic and result reporting
alexandair 65f0d97
Fix a typo in Test-Assessment.35006.ps1
alexandair cf4751c
Fix a typo in Test-Assessment.35007.md
alexandair 16672f0
Fix a typo in Test-Assessment.35007.ps1
alexandair b9e09cb
Fix typo in Test-Assessment.35007.md
alexandair 0b48e04
Update MinimumLicense and simplify assessment logic in Test-Assessmen…
alexandair 63621e6
Fix IRM status check and update result reporting
alexandair df640e0
Fix terminology in Test-Assessment.35008.ps1 for clarity on document …
alexandair d86491d
Enhance Test-Assessment.35008.Tests.ps1: Clarify failure message and …
alexandair 3e041d0
requested changes completed
Manoj-Kesana cc5e48a
initial commit
sandeepjha000 3ef923b
draft 25411
komalp2025 59b14c1
Adding network 25411
komalp2025 6f2d5b7
Adding new property and md formatting
komalp2025 05affd2
add ZtTest info
komalp2025 6453606
refactor 25411
komalp2025 50c3739
refactor 25411
komalp2025 da5f02a
refine spec
komalp2025 9ca20d4
draft changes
komalp2025 ec51c34
draft
komalp2025 bf28353
refined spec
komalp2025 cec730e
updated user facing messages
komalp2025 7c5b06c
Test 25396
praneeth-0000 58952a5
fix variable case-optimize code for ca policy iteration
komalp2025 9c9c0c5
fix variable case for baselineprofilefound
komalp2025 7c34420
added Test file
ashwinikarke a730098
added Test file
ashwinikarke 94018b5
taken pull
ashwinikarke 9afd381
Changed user facing messages and beautified code
praneeth-0000 9a81ac6
fixed casing in table headers
praneeth-0000 3ffa3e8
fixed user facing messages
praneeth-0000 c0cf2e5
Update- Remediation action
kshitiz-prog 5a88c1c
fix CA policy seperator
komalp2025 a1bb11d
Merge pull request #720 from alexandair/alex-35002
SagarSathe b3f3b3c
Merge pull request #719 from alexandair/alex-35001
SagarSathe d7678e3
Merge pull request #721 from alexandair/alex-35003
SagarSathe 0887b00
Merge pull request #728 from alexandair/alex-35004
SagarSathe 286f839
Merge pull request #729 from alexandair/alex-35005
SagarSathe c94eab2
Adding test for assessment 25395
aahmed-spec c7c7398
Feature-35009
Manoj-Kesana 56b7637
Updated region markers and app conditional check
aahmed-spec 4e0014e
added test file
ashwinikarke 4cf5067
taken pull
ashwinikarke b1f861f
removed extra lines
aahmed-spec eb41d25
Merge pull request #730 from alexandair/alex-35006
SagarSathe fbf8aec
Merge pull request #731 from alexandair/alex-35007
SagarSathe 1bfa643
Merge pull request #732 from alexandair/alex-35008
SagarSathe a9869ae
Merge pull request #711 from microsoft/Feature-25403
SagarSathe 408cd8e
Update src/powershell/tests/Test-Assessment.35009.ps1
Manoj-Kesana 608ceef
Update src/powershell/tests/Test-Assessment.35009.ps1
Manoj-Kesana 7cee52b
Merge pull request #709 from microsoft/Network-25411-TLS-inspection-i…
SagarSathe c7f977e
Fixed the evaluation logic
Manoj-Kesana fd0029e
refactored report table
sandeepjha000 6708695
adding blade links to profiles and policies
sandeepjha000 ae8e049
updated comments and word capitalization
sandeepjha000 21fd120
moved portal links to bottom
praneeth-0000 e81de1c
Code fixed as per Co-Pilot assessment
kshitiz-prog f6bee36
added test file
ashwinikarke b4eb371
taken pull
ashwinikarke 9684145
Merge pull request #749 from microsoft/Feature-35009
SagarSathe 0a648d9
Initial plan
Copilot 6a0065d
Extract AD ports to constant $AD_WELL_KNOWN_PORTS
Copilot 4bdf259
Merge pull request #752 from microsoft/copilot/sub-pr-747
aahmed-spec 1d168ed
Update src/powershell/tests/Test-Assessment.25395.ps1
aahmed-spec 003cabc
Update src/powershell/tests/Test-Assessment.25395.ps1
aahmed-spec b0e888d
Update src/powershell/tests/Test-Assessment.25395.ps1
aahmed-spec cdc6a56
updated test
ashwinikarke eca61d6
taken pull
ashwinikarke a621f44
"url" capitalized as "URL"
sandeepjha000 802dfa6
corrected grammar
sandeepjha000 1ea5d16
simplified priority check
sandeepjha000 e8203c6
Merge branch 'feature-25408' of https://github.com/microsoft/zerotrus…
sandeepjha000 da4d1fd
Added comments for Test-IsBroadCidr function
aahmed-spec cc80027
Added BroadPortRangeThreshold variable for src/powershell/tests/Test-…
aahmed-spec 6244d6b
Update line no: 69 src/powershell/tests/Test-Assessment.25395.ps1
aahmed-spec 0349d5a
Initial plan
Copilot 6b15741
Fix off-by-one errors in IP and port range calculations
Copilot f4bb78f
Merge pull request #754 from microsoft/copilot/sub-pr-747-another-one
aahmed-spec 3e80636
Merge pull request #750 from microsoft/feature-25408
SagarSathe 184a79c
Update test logic for assessment 25395
aahmed-spec c1fdf84
Refine segment evaluation logic for assessment 25395
aahmed-spec 0cfa271
updated test
ashwinikarke 3535ca1
taken pull
ashwinikarke 8c9c78d
add test 35030
komalp2025 b340228
updated output table
ashwinikarke 20d428a
Refine segment scope column logic for assessment 25395
aahmed-spec 5349e01
remove duplicate link
komalp2025 3164c97
Fix formatting of DLP policy links in Test-Assessment.35030.md
alexandair e65ba67
Update DLP policy title and optimize enabled policies count query
alexandair 8f8a6f6
added test
ashwinikarke a7740b8
updated endpoint
ashwinikarke 943356d
combined q1 and q4 queries and simplified logic
praneeth-0000 21d7674
Merge pull request #756 from microsoft/Data-35030-DLP-Policies-Cloud-…
SagarSathe 56e4c8d
added test
ashwinikarke 1685849
updated test
ashwinikarke 5c8ab65
taken pull
ashwinikarke a4a0ce7
Merge pull request #747 from microsoft/test-25395
SagarSathe 92428bc
added portal link
ashwinikarke a020439
taken pull
ashwinikarke c7ada61
added logic to handle empty csa
praneeth-0000 961251f
fixed Copilot PR comments
ashwinikarke 9a536c2
draft 35031
komalp2025 4fcf99f
integrate Find-ZtProfileLinkedToPolicy
komalp2025 b841097
Revert draft 35031
komalp2025 296e3cd
updated code
ashwinikarke 5775669
updated portal link
ashwinikarke 6fdd459
Add Find-ZtProfilesLinkedToPolicy function to evaluate linked filteri…
alexandair ffa05a4
Feature-35019
Manoj-Kesana aababe0
Merge pull request #765 from microsoft/add-ZTProfilesLinkedToPolicy-2…
SagarSathe 190ffc4
Merge pull request #763 from microsoft/Feature-35025
SagarSathe 7258fa5
Merge pull request #767 from alexandair/alex-Find-ZtProfilesLinkedToP…
alexandair 77caabb
taken pull
ashwinikarke 7f1279d
Fix missing sentence
alexandair 0f3ba7a
updated to use helper function
ashwinikarke 05fbd80
updated code
ashwinikarke 8b3eeaa
taken pull
ashwinikarke 5c3ee1b
updated code to use helper function
sandeepjha000 774f001
initial commit Test 35038
praneeth-0000 439d78f
Fix missing sentence
Manoj-Kesana e10e564
Merge branch 'Feature-35019' of https://github.com/microsoft/zerotrus…
Manoj-Kesana 99284da
Updated wrong error message
praneeth-0000 67bf009
removed redundant variable assignment
praneeth-0000 e4c9469
Merge pull request #745 from microsoft/Feature-25409
SagarSathe 7a18237
Merge pull request #769 from microsoft/feature-25408
SagarSathe a8662d6
Feature-35021
Manoj-Kesana 9a6532f
Update src/powershell/tests/Test-Assessment.35021.md
Manoj-Kesana e787e73
Add missing line break before "Remediation action" in Test-Assessment…
alexandair 434e5be
Merge pull request #773 from microsoft/Feature-35021
SagarSathe f404c25
Remove Markdown to bold one list entry
alexandair 6b2c5d9
adjusted portal link to header
praneeth-0000 9de9b61
Merge pull request #771 from microsoft/Feature-35033
SagarSathe 9ae3fe2
Changed logic for checking auth strength
praneeth-0000 d0c9deb
moved portal link to table header
praneeth-0000 1a4dc87
Updated phishing resistant logic according to docx
praneeth-0000 4136445
added and removed spaces as suggested by copilot
praneeth-0000 bf8edc2
Merge pull request #770 from microsoft/Feature-35038
SagarSathe 6aef9c4
Merge pull request #768 from microsoft/Feature-35019
SagarSathe 5ef46ea
updated sfipillar and q1 with count
praneeth-0000 a3d65b2
fixed SFI Pillar
praneeth-0000 77adaa5
25535-code update
77e8358
25535 update
64f500d
Merge pull request #744 from microsoft/Feature-25396
SagarSathe c3d1bbf
add support for aipservice module
komalp2025 a5fc605
add 35011
komalp2025 332f905
reworked 35011
komalp2025 d853e47
Update src/powershell/tests/Test-Assessment.25535.ps1
kshitiz-prog afe6dc8
Feature-25535 : Update as per alex review
e22a436
Merge branch 'Feature-25535' of https://github.com/microsoft/zerotrus…
eea3ea3
Code fix - Query Parameter change
c082b34
Refactor documentation for clarity and readability in Test-Assessment…
alexandair cb8ad0c
Update video link in Advanced Analytics documentation
jfdyer13 ad51f6b
Merge pull request #783 from jfdyer13/patch-2
Clay-Microsoft e9bf151
Replace old YouTube video with a new one
Clay-Microsoft b0091e1
Add video walkthrough to RMD_117.md
Clay-Microsoft 31b3a72
Modify iframe for video walkthrough
Clay-Microsoft 832ba3c
Merge pull request #784 from microsoft/Clay-Microsoft-patch-73
Clay-Microsoft bfafd1f
code fix 25535
876f30d
Merge branch 'Feature-25535' of https://github.com/microsoft/zerotrus…
d98dd13
Merge pull request #772 from microsoft/Data-35011-Super-User-Membersh…
SagarSathe e519b56
code fix
27ddf31
Initial commit for 25535
kshitiz-prog c554a91
Update- Remediation action
kshitiz-prog d131ca7
Code fixed as per Co-Pilot assessment
kshitiz-prog 02c8c9f
25535-code update
31dfb45
Feature-25535 : Update as per alex review
d4eb297
Code fix - Query Parameter change
5608fb7
code fix 25535
ca95fe8
Refactor documentation for clarity and readability in Test-Assessment…
alexandair d44ce7e
code fix
0916711
Merge branch 'Feature-25535' of https://github.com/microsoft/zerotrus…
593274b
mg context to az context switch
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| Azure Firewall is a cloud-native network security service that provides centralized inspection, logging, and enforcement for network traffic flowing between application workloads and external destinations. Routing outbound traffic through Azure Firewall enables organizations to apply consistent security controls such as threat intelligence filtering, intrusion detection and prevention, TLS inspection, and egress policy enforcement. In a secure network architecture, outbound traffic from workloads hosted in Azure virtual networks should be explicitly routed through Azure Firewall before reaching the internet or external services. VNET integrated workloads include VMs, AKS Node Pools, AKS Pods, App Service (VNet Integration Route All), Functions in VNet. This is typically achieved by configuring routing so that outbound traffic from workload subnets uses Azure Firewall as the next hop. Without this routing in place, outbound traffic may bypass the firewall entirely, reducing visibility and allowing traffic to leave the environment without inspection or policy enforcement.This check verifies that outbound traffic from in-scope workloads is routed through Azure Firewall by validating that the effective network routes direct outbound traffic to the firewall’s private IP address. If outbound traffic is not routed through Azure Firewall, the check fails because traffic may bypass centralized security controls, increasing the risk of data exfiltration, command-and-control communication, and undetected malicious activity. | ||
|
|
||
| **Remediation action** | ||
|
|
||
| - [Deploy and configure Azure Firewall using the Azure portal](https://learn.microsoft.com/en-us/azure/firewall/tutorial-firewall-deploy-portal#configure-routing) | ||
| - [Control outbound traffic with Azure Firewall ](https://learn.microsoft.com/en-us/azure/app-service/network-secure-outbound-traffic-azure-firewall) | ||
|
|
||
| <!--- Results ---> | ||
| %TestResult% | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,317 @@ | ||
| <# | ||
| .SYNOPSIS | ||
| Test to check if outbound traffic from VNET integrated workloads is routed through Azure Firewall | ||
|
|
||
| .NOTES | ||
| Some Azure Firewall documentation links may return 404 errors. | ||
| This test uses the Azure REST API version 2025-03-01. | ||
| #> | ||
|
|
||
| function Test-Assessment-25535 { | ||
| [ZtTest( | ||
| Category = 'Azure Network Security', | ||
| ImplementationCost = 'Medium', | ||
| MinimumLicense = ('Azure_Firewall_Basic', 'Azure_Firewall_Standard', 'Azure_Firewall_Premium'), | ||
| Pillar = 'Network', | ||
| RiskLevel = 'High', | ||
| SfiPillar = 'Protect networks', | ||
| TenantType = ('Workforce', 'External'), | ||
| TestId = 25535, | ||
| Title = 'Outbound traffic from VNET integrated workloads is routed through Azure Firewall', | ||
| UserImpact = 'Low' | ||
| )] | ||
| [CmdletBinding()] | ||
| param() | ||
|
|
||
| Write-PSFMessage '🟦 Start' -Tag Test -Level VeryVerbose | ||
|
|
||
| if ((Get-MgContext).Environment -ne 'Global') { | ||
kshitiz-prog marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
kshitiz-prog marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| Write-PSFMessage "This test is only applicable to the Global environment." -Tag Test -Level VeryVerbose | ||
| return | ||
| } | ||
|
|
||
| #region Data Collection | ||
| try { | ||
| $accessToken = Get-AzAccessToken -AsSecureString -ErrorAction SilentlyContinue -WarningAction SilentlyContinue | ||
| } | ||
| catch { | ||
| Write-PSFMessage $_.Exception.Message -Tag Test -Level Error | ||
| } | ||
|
|
||
| if (-not $accessToken) { | ||
| Write-PSFMessage "Azure authentication token not found." -Tag Test -Level Warning | ||
| Add-ZtTestResultDetail -SkippedBecause NoAzureAccess | ||
kshitiz-prog marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| return | ||
| } | ||
|
|
||
| # Query 1: List all subscriptions | ||
| $subscriptions = Get-AzSubscription | ||
|
|
||
| $firewalls = @() | ||
| $nicFindings = @() | ||
|
|
||
| foreach ($sub in $subscriptions) { | ||
|
|
||
| Set-AzContext -SubscriptionId $sub.Id | Out-Null | ||
| $subId = $sub.Id | ||
|
|
||
| # Query 2: List Azure Firewalls | ||
| $fwListUri = "/subscriptions/$subId/providers/Microsoft.Network/azureFirewalls?api-version=2025-03-01" | ||
|
|
||
| try { | ||
| $fwResp = Invoke-AzRestMethod -Path $fwListUri -Method GET | ||
| } | ||
| catch { | ||
| Write-PSFMessage "Unable to list Azure Firewalls in subscription $($sub.Name)." -Tag Test -Level Warning | ||
| continue | ||
| } | ||
|
|
||
| $fwItems = ($fwResp.Content | ConvertFrom-Json).value | ||
| if (-not $fwItems) { continue } | ||
|
|
||
| # Query 3: Get Firewall Details (resolve private IPs) | ||
| foreach ($fw in $fwItems) { | ||
|
|
||
| $fwDetailUri = "$($fw.id)?api-version=2025-03-01" | ||
|
|
||
| try { | ||
| $fwDetailResp = Invoke-AzRestMethod -Path $fwDetailUri -Method GET | ||
| $fwDetail = $fwDetailResp.Content | ConvertFrom-Json | ||
| } | ||
| catch { continue } | ||
|
|
||
| foreach ($ipconfig in $fwDetail.properties.ipConfigurations) { | ||
| if ($ipconfig.properties.privateIPAddress) { | ||
| $firewalls += [PSCustomObject]@{ | ||
| FirewallName = $fwDetail.name | ||
| FirewallId = $fwDetail.id | ||
| PrivateIP = $ipconfig.properties.privateIPAddress | ||
| SubscriptionId = $subId | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| if ($firewalls.Count -eq 0) { continue } | ||
|
|
||
| # Query 4: List NICs | ||
| $nicListUri = "/subscriptions/$subId/providers/Microsoft.Network/networkInterfaces?api-version=2025-03-01" | ||
|
|
||
| try { | ||
| $nicResp = Invoke-AzRestMethod -Path $nicListUri -Method GET | ||
| } | ||
| catch { | ||
| Write-PSFMessage "Unable to list network interfaces in subscription $($sub.Name)." -Tag Test -Level Warning | ||
| continue | ||
| } | ||
|
|
||
| $nics = ($nicResp.Content | ConvertFrom-Json).value | ||
|
|
||
| # Query 5: Stage 1 - Launch all async effectiveRouteTable requests | ||
| $asyncOperations = @() | ||
|
|
||
| foreach ($nic in $nics) { | ||
| foreach ($ipconfig in $nic.properties.ipConfigurations) { | ||
|
|
||
| if (-not $ipconfig.properties.subnet?.id) { continue } | ||
|
|
||
| $subnetId = $ipconfig.properties.subnet.id | ||
| if ($subnetId -match 'AzureFirewallSubnet|GatewaySubnet|AzureBastionSubnet') { | ||
kshitiz-prog marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| continue | ||
| } | ||
|
|
||
| $rg = ($nic.id -split '/')[4] | ||
| $nicName = $nic.name | ||
|
|
||
| $ertUri = "/subscriptions/$subId/resourceGroups/$rg/providers/Microsoft.Network/networkInterfaces/$nicName/effectiveRouteTable?api-version=2025-03-01" | ||
|
|
||
| try { | ||
| $ertStart = Invoke-AzRestMethod -Path $ertUri -Method POST | ||
| $operationUri = $ertStart.Headers.Location[0] | ||
|
|
||
| $retryAfter = if ($ertStart.Headers.'Retry-After') { | ||
| [int]$ertStart.Headers.'Retry-After'[0] | ||
| } else { 5 } | ||
|
|
||
| $asyncOperations += @{ | ||
| OperationUri = $operationUri | ||
| Nic = $nic | ||
| RetryAfter = $retryAfter | ||
| Timestamp = Get-Date | ||
| SubnetId = $subnetId | ||
| SubscriptionId = $sub.Id | ||
| SubscriptionName = $sub.Name | ||
| } | ||
| } | ||
| catch { | ||
| Write-PSFMessage "Failed to initiate effectiveRouteTable request for NIC $nicName : $($_.Exception.Message)" -Tag Test -Level Warning | ||
| } | ||
| } | ||
| } | ||
|
|
||
| if ($asyncOperations.Count -eq 0) { continue } | ||
|
|
||
| Write-PSFMessage "Launched $($asyncOperations.Count) async effectiveRouteTable requests for subscription $($sub.Name)" -Tag Test -Level Verbose | ||
|
|
||
| # Query 5: Stage 2 - Poll all operations in parallel | ||
| $completedOperations = @() | ||
| $maxRetries = 120 # ~10 minutes with 5 second intervals | ||
|
|
||
| do { | ||
| $stillPending = @() | ||
|
|
||
| foreach ($op in $asyncOperations) { | ||
| if ($op.Completed) { | ||
| $completedOperations += $op | ||
| continue | ||
| } | ||
|
|
||
| try { | ||
| $ertPoll = Invoke-AzRestMethod -Uri $op.OperationUri -Method GET | ||
|
|
||
| if ($ertPoll.StatusCode -ne 202) { | ||
| $op.Routes = ($ertPoll.Content | ConvertFrom-Json).value | ||
| $op.Completed = $true | ||
| $completedOperations += $op | ||
| } else { | ||
| $stillPending += $op | ||
| } | ||
| } | ||
| catch { | ||
| Write-PSFMessage "Error polling operation for NIC $($op.Nic.name) : $($_.Exception.Message)" -Tag Test -Level Warning | ||
| $op.Completed = $true | ||
| $op.Error = $true | ||
| $completedOperations += $op | ||
| } | ||
| } | ||
|
|
||
| $asyncOperations = $stillPending | ||
|
|
||
| if ($asyncOperations.Count -gt 0) { | ||
| $maxRetries-- | ||
| if ($maxRetries -le 0) { | ||
| Write-PSFMessage "Timeout polling effectiveRouteTable operations. Processing $($asyncOperations.Count) incomplete operations." -Tag Test -Level Warning | ||
| $completedOperations += $asyncOperations | ||
| break | ||
| } | ||
|
|
||
| $retryAfter = ($asyncOperations | Select-Object -First 1).RetryAfter | ||
| Write-PSFMessage "Polling $($asyncOperations.Count) pending operations..." -Tag Test -Level Verbose | ||
| Start-Sleep -Seconds $retryAfter | ||
| } | ||
|
|
||
| } while ($asyncOperations.Count -gt 0) | ||
|
|
||
| # Query 5: Stage 3 - Process completed operations | ||
| foreach ($op in $completedOperations) { | ||
| if ($op.Error -or -not $op.Routes) { | ||
| $nicFindings += [PSCustomObject]@{ | ||
| NicName = $op.Nic.name | ||
| NicId = $op.Nic.id | ||
| NextHopType = 'Unknown' | ||
| NextHopIp = '' | ||
| IsCompliant = $false | ||
| SubscriptionId = $op.SubscriptionId | ||
| SubscriptionName = $op.SubscriptionName | ||
| SubnetId = $op.SubnetId | ||
| FirewallPrivateIp = 'N/A' | ||
| NextHopIpAddress = '' | ||
| } | ||
| continue | ||
| } | ||
|
|
||
| $defaultRoute = $op.Routes | Where-Object { | ||
| $_.state -eq 'Active' -and | ||
| $_.source -eq 'User' -and | ||
| ($_.addressPrefix -contains '0.0.0.0/0') | ||
kshitiz-prog marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | Select-Object -First 1 | ||
kshitiz-prog marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| if (-not $defaultRoute) { | ||
| $nicFindings += [PSCustomObject]@{ | ||
| NicName = $op.Nic.name | ||
| NicId = $op.Nic.id | ||
| NextHopType = 'Internet' | ||
| NextHopIp = '' | ||
| IsCompliant = $false | ||
| SubscriptionId = $op.SubscriptionId | ||
| SubscriptionName = $op.SubscriptionName | ||
| SubnetId = $op.SubnetId | ||
| FirewallPrivateIp = 'N/A' | ||
| NextHopIpAddress = '' | ||
| } | ||
| continue | ||
| } | ||
|
|
||
| $fwMatch = $firewalls | Where-Object { | ||
| # Handle nextHopIpAddress being either a string or an array | ||
| $nextHop = $defaultRoute.nextHopIpAddress | ||
| ( ($nextHop -eq $_.PrivateIP) -or ($nextHop -contains $_.PrivateIP) ) | ||
| } | Select-Object -First 1 | ||
|
|
||
| $nicFindings += [PSCustomObject]@{ | ||
| FirewallName = if ($fwMatch) { $fwMatch.FirewallName } else { 'N/A' } | ||
| FirewallId = if ($fwMatch) { $fwMatch.FirewallId } else { 'N/A' } | ||
| FirewallPrivateIp = if ($fwMatch) { $fwMatch.PrivateIP } else { 'N/A' } | ||
| NicName = $op.Nic.name | ||
| NicId = $op.Nic.id | ||
| RouteSource = $defaultRoute.source | ||
| RouteState = $defaultRoute.state | ||
| AddressPrefix = ($defaultRoute.addressPrefix -join ',') | ||
| NextHopType = $defaultRoute.nextHopType | ||
| NextHopIpAddress = ($defaultRoute.nextHopIpAddress -join ',') | ||
| IsCompliant = ($fwMatch -ne $null) | ||
kshitiz-prog marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| SubscriptionId = $op.SubscriptionId | ||
| SubscriptionName = $op.SubscriptionName | ||
| SubnetId = $op.SubnetId | ||
| } | ||
| } | ||
| } | ||
| #endregion Data Collection | ||
|
|
||
| #region Assessment Logic | ||
| if ($nicFindings.Count -eq 0) { | ||
| Add-ZtTestResultDetail -SkippedBecause NoResults | ||
kshitiz-prog marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| return | ||
| } | ||
|
|
||
| $passed = ($nicFindings | Where-Object { -not $_.IsCompliant }).Count -eq 0 | ||
|
|
||
| $testResultMarkdown = if ($passed) { | ||
| "Outbound traffic is routed through Azure Firewall.`n`n%TestResult%" | ||
| } else { | ||
| "Outbound traffic is not routed through Azure Firewall.`n`n%TestResult%" | ||
| } | ||
| #endregion Assessment Logic | ||
|
|
||
| #region Report Generation | ||
| $mdInfo = "## Outbound traffic routing evidence`n`n" | ||
| $mdInfo += "| Subscription | Network interface | Subnet | Azure firewall private IP | Default route next hop type | Next hop IP address | Result |`n" | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The specification is asking for
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| $mdInfo += "| :--- | :--- | :--- | :--- | :--- | :--- | :--- |`n" | ||
|
|
||
| foreach ($item in $nicFindings | Sort-Object SubscriptionName, NicName) { | ||
| $icon = if ($item.IsCompliant) { '✅' } else { '❌' } | ||
|
|
||
| $subName = if ($item.SubscriptionName) { $item.SubscriptionName } else { 'N/A' } | ||
| $subLink = "https://portal.azure.com/#resource/subscriptions/$($item.SubscriptionId)" | ||
| $subMd = "[$(Get-SafeMarkdown -Text $subName)]($subLink)" | ||
|
|
||
| $nicName = if ($item.NicName) { $item.NicName } else { 'N/A' } | ||
| $nicLink = "https://portal.azure.com/#resource$($item.NicId)" | ||
| $nicMd = "[$(Get-SafeMarkdown -Text $nicName)]($nicLink)" | ||
|
|
||
| $subnetName = if ($item.SubnetId) { ($item.SubnetId -split '/')[-1] } else { 'N/A' } | ||
| $subnetLink = "https://portal.azure.com/#resource$($item.SubnetId)" | ||
| $subnetMd = "[$(Get-SafeMarkdown -Text $subnetName)]($subnetLink)" | ||
|
|
||
| $fwIp = if ($item.FirewallPrivateIp) { $item.FirewallPrivateIp } else { 'N/A' } | ||
| $nextHopType = if ($item.NextHopType) { $item.NextHopType } else { 'None' } | ||
| $nextHopIp = if ($item.NextHopIpAddress) { $item.NextHopIpAddress } else { '' } | ||
|
|
||
| $mdInfo += "| $subMd | $nicMd | $subnetMd | $fwIp | $nextHopType | $nextHopIp | $icon |`n" | ||
| } | ||
|
|
||
| $testResultMarkdown = $testResultMarkdown -replace "%TestResult%", $mdInfo | ||
| #endregion Report Generation | ||
|
|
||
| Add-ZtTestResultDetail -TestId '25535' -Status $passed -Result $testResultMarkdown | ||
kshitiz-prog marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.

Uh oh!
There was an error while loading. Please reload this page.