Azure / Azure/Azure-Network-Security

Get-DanglingDnsRecords uses a Resource Graph query that is partially wrong and incomplete

Open
#394 2 comments 1 reaction 2 assignees Claimed by @abhijeetgaiha View on GitHub
Dominant language
PowerShell
Stars
942
Forks
360
PR merge metrics
No merged PRs in 30d

Description

**Describe the bug**
The Azure Resource Graph query used in Get-DanglingDnsRecords.ps1 (at line 822: $interestedResourcesQuery = ...) has the following shortcomings:

- the FQDNs for the microsoft.apimanagement/service are not retrieved correctly
- for microsoft.network/frontdoors it should also take into consideration the afdverify subdomain (see [link](https://learn.microsoft.com/en-us/azure/frontdoor/front-door-custom-domain#map-the-temporary-afdverify-subdomain))
- for microsoft.cdn/profiles/endpoints it should also take into consideration the cdnverify subdomain (see [link](https://learn.microsoft.com/en-us/azure/cdn/cdn-map-content-to-custom-domain?tabs=dns-provider%2Cazure-portal%2Cazure-portal-cleanup#map-the-temporary-cdnverify-subdomain))
- it does not handle microsoft.web/staticsites
- it does not handle microsoft.containerregistry/registries
- it does not handle microsoft.app/containerapps

Please compare the original query used in the script to the query below.

**Reproduce**
Steps to reproduce the behavior:
1. create a DNS records for one of the missed services above and it will be reported as dangling
2. apimanagement endpoints are not recognized correctly
3. afdverify and cdnverify subdomains are reported as dangling

**Expected behavior**
All Azure resources that provide an "fqdn" should be handled by the Azure Resource Graph query

**Screenshots**
See query below

**Environment- if applicable**
n.a.

**Desktop (please complete the following information if applicable):**
n.a. - Azure Resource Graph query can be executed in the browser

**Logs- if applicable**
n.a.

**Additional context**
Please see below the query that we are currently using in our custom script.

```
resources
| where subscriptionId matches regex '(?i)'
| where type in (
'microsoft.network/frontdoors',
'microsoft.storage/storageaccounts',
'microsoft.cdn/profiles/endpoints',
'microsoft.cdn/profiles/afdendpoints',
'microsoft.network/publicipaddresses',
'microsoft.containerinstance/containergroups',
'microsoft.apimanagement/service',
'microsoft.web/sites',
'microsoft.web/sites/slots',
'microsoft.classiccompute/domainnames',
'microsoft.classicstorage/storageaccounts',
'microsoft.containerregistry/registries',
'microsoft.app/containerapps',
'microsoft.web/staticsites',
"microsoft.network/trafficmanagerprofiles"
)
| extend dnsEndpoint = case
(
type =~ 'microsoft.network/frontdoors', pack_array(properties.cName, strcat("afdverify.",properties.cName)),
type =~ 'microsoft.cdn/profiles/endpoints', pack_array(properties.hostName, strcat("cdnverify.",properties.hostName)),
type =~ 'microsoft.storage/storageaccounts', iff(properties['primaryEndpoints']['blob'] matches regex '(?i)(http|https)://',
pack_array(parse_url(tostring(properties['primaryEndpoints']['blob'])).Host), pack_array(tostring(properties['primaryEndpoints']['blob']))),
type =~ 'microsoft.cdn/profiles/afdendpoints', pack_array(properties.hostName),
type =~ 'microsoft.network/publicipaddresses', pack_array(properties.dnsSettings.fqdn),
type =~ 'microsoft.network/trafficmanagerprofiles', pack_array(properties.dnsConfig.fqdn),
type =~ 'microsoft.containerinstance/containergroups', pack_array(properties.ipAddress.fqdn),
type =~ 'microsoft.apimanagement/service', pack_array(
parse_url(tostring(properties.gatewayRegionalUrl)).Host,
parse_url(tostring(properties.developerPortalUrl)).Host,
parse_url(tostring(properties.managementApiUrl)).Host,
parse_url(tostring(properties.portalUrl)).Host,
parse_url(tostring(properties.scmUrl)).Host,
parse_url(tostring(properties.gatewayUrl)).Host),
type =~ 'microsoft.web/sites', pack_array(properties.defaultHostName),
type =~ 'microsoft.web/sites/slots', pack_array(properties.defaultHostName),
type =~ 'microsoft.classiccompute/domainnames',pack_array(properties.hostName),
type =~ 'microsoft.app/containerapps',pack_array(properties.configuration.ingress.fqdn),
type =~ 'microsoft.containerregistry/registries',array_concat(properties.dataEndpointHostNames, pack_array(properties.loginServer)),
type =~ 'microsoft.web/staticsites', pack_array(properties.defaultHostname),
pack_array('')
)
| mv-expand (dnsEndpoint)
| extend dnsEndpoint = tostring(dnsEndpoint)
| where isnotempty(dnsEndpoint)
| extend resourceProvider = case
(
dnsEndpoint endswith 'azure-api.net', 'azure-api.net',
dnsEndpoint endswith 'azurecontainer.io', 'azurecontainer.io',
dnsEndpoint endswith 'azurecr.io', 'azurecr.io',
dnsEndpoint endswith 'azureedge.net', 'azureedge.net',
dnsEndpoint endswith 'azurefd.net', 'azurefd.net',
dnsEndpoint endswith 'azurewebsites.net', 'azurewebsites.net',
dnsEndpoint endswith 'blob.core.windows.net', 'blob.core.windows.net',
dnsEndpoint endswith 'cloudapp.azure.com', 'cloudapp.azure.com',
dnsEndpoint endswith 'cloudapp.net', 'cloudapp.net',
dnsEndpoint endswith 'trafficmanager.net', 'trafficmanager.net',
dnsEndpoint endswith 'azurecontainerapps.io', 'azurecontainerapps.io',
dnsEndpoint endswith 'azurestaticapps.net', 'azurestaticapps.net',
''
)
| project id, tenantId, subscriptionId, type, resourceGroup, name, dnsEndpoint, properties, resourceProvider
| order by dnsEndpoint asc, name asc, id asc
| order by ['type'] asc
```

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.