Skip to content

Instantly share code, notes, and snippets.

@jikuja
Last active October 12, 2024 16:12
Show Gist options
  • Save jikuja/a8dc455f7a3e1158fc1bb1ccb63ef6f1 to your computer and use it in GitHub Desktop.
Save jikuja/a8dc455f7a3e1158fc1bb1ccb63ef6f1 to your computer and use it in GitHub Desktop.
Azure ServiceTags_Public

Virtual network service tags

Helpers for Microsoft provided Virtual network service tags.

Revision 2 functions and tests are from ChatGPT.

TODO

  • Add function to download file from REST API
  • Add transparent caching to persist and re-use downloaded data
    • Done with default parameter values. Update must be done manually.

How to run the tool

Load functions

. ./ServiceTags-Helpers.ps1 

Download data

Download-ServiTagsData

Run the tool

Find-AzureServiceByIP -ipAddress "4.149.115.15"

How to run tests

Install Pester

Install-Module -Name Pester -Force -SkipPublisherCheck

Run tests:

Invoke-Pester -Path "Test-IpInRange.Tests.ps1"
$config = New-PesterConfiguration
$config.Run.Path = "./Test-IpInRange.Tests.ps1"
$config.CodeCoverage.Enabled = $true
$config.Output.Verbosity = "Detailed"
# Optional to scope the coverage to the list of files or directories in this path
$config.CodeCoverage.Path = "./ServiceTags-Helpers.ps1"
Invoke-Pester -Configuration $config
# Function to find Azure services by IP address
function Find-AzureServiceByIP {
param (
[string]$ipAddress,
[string]$jsonFilePath = ".data.json"
)
# Load the JSON file into a PowerShell object
$serviceTags = Get-Content $jsonFilePath | ConvertFrom-Json
# Loop through each service tag in the file
foreach ($serviceTag in $serviceTags.values) {
foreach ($addressPrefix in $serviceTag.properties.addressPrefixes) {
# TODO: extract and add IPv6 support
# Check if the addressPrefix is an IP range in CIDR format
if ($addressPrefix -match "\d+\.\d+\.\d+\.\d+\/\d+") {
# Use the 'IPAddress' class to check if the given IP is within the CIDR block
if (Test-IpInRange -IpAddress $ipAddress -CIDR $addressPrefix) {
# If IP is found, output the service tag details
Write-Output ([pscustomobject]@{
Service = $serviceTag.name
Region = $serviceTag.properties.region
IPRange = $addressPrefix
})
}
}
}
}
}
# Helper function to check if an IP address is within a CIDR block
function Test-IpInRange {
param (
[string]$IpAddress,
[string]$CIDR
)
# Split CIDR into base IP and subnet mask bits
$cidrParts = $CIDR -split "/"
$baseIP = $cidrParts[0]
$subnetBits = [int]$cidrParts[1]
# Convert IP addresses to byte arrays
$ipBytes = [System.Net.IPAddress]::Parse($IpAddress).GetAddressBytes()
$baseIpBytes = [System.Net.IPAddress]::Parse($baseIP).GetAddressBytes()
# Calculate the number of full bytes and partial bits in the subnet mask
$fullBytes = [math]::Floor($subnetBits / 8)
$remainingBits = $subnetBits % 8
# Compare full bytes of the IP and base IP
for ($i = 0; $i -lt $fullBytes; $i++) {
if ($ipBytes[$i] -ne $baseIpBytes[$i]) {
return $false
}
}
# Compare the remaining bits in the last byte, if any
if ($remainingBits -gt 0) {
$mask = 0xFF -bxor (0xFF -shr $remainingBits)
if (($ipBytes[$fullBytes] -band $mask) -ne ($baseIpBytes[$fullBytes] -band $mask)) {
return $false
}
}
return $true
}
function Download-ServiTagsData {
param(
[string]$jsonFilePath = ".data.json"
)
$url = 'https://www.microsoft.com/en-us/download/confirmation.aspx?id=56519'
$pageContent = Invoke-WebRequest -Uri $url
if ($pageContent.Content -match 'data-bi-id="downloadretry" href="(?<url>.*\.json?)"') {
$jsonUrl = $matches['url']
}
Write-Host "Downloading file from $jsonUrl"
Invoke-RestMethod -Uri $jsonUrl -OutFile $jsonFilePath
}
# Example usage:
# Find-AzureServiceByIP -IpAddress "X.X.X.X" -jsonFilePath "C:\path\to\ServiceTags_Public_20240909.json"
BeforeAll {
. ./"ServiceTags-Helpers.ps1"
}
# Describe block is the Pester test group
Describe 'Test-IpInRange' {
# Test case: IP is within the range
It 'Should return $true when IP is within the CIDR range' {
$ip = "192.168.1.10"
$cidr = "192.168.1.0/24"
# Call the function and check the result
$result = Test-IpInRange -IpAddress $ip -CIDR $cidr
# The result should be $true
$result | Should -Be $true
}
# Test case: IP is outside the range
It 'Should return $false when IP is outside the CIDR range' {
$ip = "192.168.2.10"
$cidr = "192.168.1.0/24"
# Call the function and check the result
$result = Test-IpInRange -IpAddress $ip -CIDR $cidr
# The result should be $false
$result | Should -Be $false
}
# Test case: Exact match at the boundary of the CIDR range
It 'Should return $true for the lowest IP in the CIDR range' {
$ip = "192.168.1.0"
$cidr = "192.168.1.0/24"
# Call the function and check the result
$result = Test-IpInRange -IpAddress $ip -CIDR $cidr
# The result should be $true
$result | Should -Be $true
}
# Test case: Highest IP in the range
It 'Should return $true for the highest IP in the CIDR range' {
$ip = "192.168.1.255"
$cidr = "192.168.1.0/24"
# Call the function and check the result
$result = Test-IpInRange -IpAddress $ip -CIDR $cidr
# The result should be $true
$result | Should -Be $true
}
# Test case: Edge case with large CIDR range
It 'Should return $true when IP is within a large CIDR range' {
$ip = "10.0.0.5"
$cidr = "10.0.0.0/8"
# Call the function and check the result
$result = Test-IpInRange -IpAddress $ip -CIDR $cidr
# The result should be $true
$result | Should -Be $true
}
# Test case: First IP outside the range (just below the range)
It 'Should return $false for the first IP outside the CIDR range (below)' {
$ip = "192.168.0.255"
$cidr = "192.168.1.0/24"
# Call the function and check the result
$result = Test-IpInRange -IpAddress $ip -CIDR $cidr
# The result should be $false
$result | Should -Be $false
}
# Test case: Last IP outside the range (just above the range)
It 'Should return $false for the first IP outside the CIDR range (above)' {
$ip = "192.168.2.0"
$cidr = "192.168.1.0/24"
# Call the function and check the result
$result = Test-IpInRange -IpAddress $ip -CIDR $cidr
# The result should be $false
$result | Should -Be $false
}
}
Describe 'Test-IpInRange with non-byte-aligned CIDR masks' {
# Test case: IP is within the /19 CIDR range
It 'Should return $true when IP is within the /19 CIDR range' {
$ip = "192.168.32.15"
$cidr = "192.168.32.0/19"
# Call the function and check the result
$result = Test-IpInRange -IpAddress $ip -CIDR $cidr
# The result should be $true
$result | Should -Be $true
}
# Test case: IP is outside the /19 CIDR range
It 'Should return $false when IP is outside the /19 CIDR range' {
$ip = "192.168.64.1"
$cidr = "192.168.32.0/19"
# Call the function and check the result
$result = Test-IpInRange -IpAddress $ip -CIDR $cidr
# The result should be $false
$result | Should -Be $false
}
# Test case: IP is within the /23 CIDR range
It 'Should return $true when IP is within the /23 CIDR range' {
$ip = "10.0.1.5"
$cidr = "10.0.0.0/23"
# Call the function and check the result
$result = Test-IpInRange -IpAddress $ip -CIDR $cidr
# The result should be $true
$result | Should -Be $true
}
# Test case: IP is outside the /23 CIDR range
It 'Should return $false when IP is outside the /23 CIDR range' {
$ip = "10.0.2.1"
$cidr = "10.0.0.0/23"
# Call the function and check the result
$result = Test-IpInRange -IpAddress $ip -CIDR $cidr
# The result should be $false
$result | Should -Be $false
}
# Test case: IP is within the /21 CIDR range
It 'Should return $true when IP is within the /21 CIDR range' {
$ip = "172.16.4.1"
$cidr = "172.16.0.0/21"
# Call the function and check the result
$result = Test-IpInRange -IpAddress $ip -CIDR $cidr
# The result should be $true
$result | Should -Be $true
}
# Test case: IP is outside the /21 CIDR range
It 'Should return $false when IP is outside the /21 CIDR range' {
$ip = "172.16.8.1"
$cidr = "172.16.0.0/21"
# Call the function and check the result
$result = Test-IpInRange -IpAddress $ip -CIDR $cidr
# The result should be $false
$result | Should -Be $false
}
}
Describe 'Test-IpInRange with first and last IP outside non-byte-aligned CIDR masks' {
# Test case: First IP outside the /19 CIDR range (just below)
It 'Should return $false for the first IP outside the /19 CIDR range (below)' {
$ip = "192.168.31.255"
$cidr = "192.168.32.0/19"
# Call the function and check the result
$result = Test-IpInRange -IpAddress $ip -CIDR $cidr
# The result should be $false
$result | Should -Be $false
}
# Test case: Last IP outside the /19 CIDR range (just above)
It 'Should return $false for the last IP outside the /19 CIDR range (above)' {
$ip = "192.168.64.0"
$cidr = "192.168.32.0/19"
# Call the function and check the result
$result = Test-IpInRange -IpAddress $ip -CIDR $cidr
# The result should be $false
$result | Should -Be $false
}
# Test case: First IP outside the /23 CIDR range (just below)
It 'Should return $false for the first IP outside the /23 CIDR range (below)' {
$ip = "10.0.2.1"
$cidr = "10.0.0.0/23"
# Call the function and check the result
$result = Test-IpInRange -IpAddress $ip -CIDR $cidr
# The result should be $false
$result | Should -Be $false
}
# Test case: Last IP outside the /23 CIDR range (just above)
It 'Should return $false for the last IP outside the /23 CIDR range (above)' {
$ip = "10.0.2.0"
$cidr = "10.0.0.0/23"
# Call the function and check the result
$result = Test-IpInRange -IpAddress $ip -CIDR $cidr
# The result should be $false
$result | Should -Be $false
}
# Test case: First IP outside the /21 CIDR range (just below)
It 'Should return $false for the first IP outside the /21 CIDR range (below)' {
$ip = "172.15.255.255"
$cidr = "172.16.0.0/21"
# Call the function and check the result
$result = Test-IpInRange -IpAddress $ip -CIDR $cidr
# The result should be $false
$result | Should -Be $false
}
# Test case: Last IP outside the /21 CIDR range (just above)
It 'Should return $false for the last IP outside the /21 CIDR range (above)' {
$ip = "172.16.8.0"
$cidr = "172.16.0.0/21"
# Call the function and check the result
$result = Test-IpInRange -IpAddress $ip -CIDR $cidr
# The result should be $false
$result | Should -Be $false
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment