Resolve-DNSNameOverHTTP.psm1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
#
# Created by: lucas.cueff[at]lucas-cueff.com
#
# v0.1 :
# - intial release
# - dns lookup needed but DNS is blocked on your network ? easy peasy through a limited internet web access and PowerShell :-)
# - PowerShell interface to DNS-over-HTTPS google API
# Released on: 02/2018
#
#'(c) 2018 lucas-cueff.com - Distributed under Artistic Licence 2.0 (https://opensource.org/licenses/artistic-license-2.0).'

<#
    .SYNOPSIS
    powershell commandline interface to use DNS-over-HTTPS google API web service
 
    .DESCRIPTION
    Resolve-DNSNameOverHTTP.psm1 module provides a commandline interface toDNS-over-HTTPS google API
     
    .EXAMPLE
    C:\PS> import-module Resolve-DNSNameOverHTTP.psm1
#>


function Resolve-DNSNameOverHTTP {
 <#
    .SYNOPSIS
    Get dns information from google dns web service. more info : https://developers.google.com/speed/public-dns/docs/dns-over-https
 
    .DESCRIPTION
    Get dns information from google dns web service. more info : https://developers.google.com/speed/public-dns/docs/dns-over-https
     
    .PARAMETER name
    -name string{domain name or fqdn}
     
    .PARAMETER searchtype
    -searchtype string{'A','AAAA','CNAME','MX','ANY'}
    set your record type to search.
 
    .PARAMETER DNSSEC
    -DNSSEC SWITCH
     enable DNSSEC
 
    .PARAMETER SimpleOutput
    -DNSSEC SWITCH
     enable DNSSEC
     
    .PARAMETER EDNSClientSubnet
    -EDNSClientSubnet string{network subnet in CIDR format}
    set the EDNS Client Subnet.
     
    .OUTPUTS
    TypeName: System.Management.Automation.PSCustomObject
        Name MemberType Definition
        ---- ---------- ----------
        Equals Method bool Equals(System.Object obj)
        GetHashCode Method int GetHashCode()
        GetType Method type GetType()
        ToString Method string ToString()
        AD NoteProperty bool AD=False
        Additional NoteProperty Object[] Additional=System.Object[]
        Answer NoteProperty Object[] Answer=System.Object[]
        CD NoteProperty bool CD=False
        cli-Request_Date NoteProperty datetime cli-Request_Date=09/02/2018 22:20:29
        cli-Request_Padding NoteProperty System.String cli-Request_Padding=e65f7a21-ef78-4394-b185-df4b1cb9ed58
        Comment NoteProperty string Comment=Response from 157.56.81.41.
        edns_client_subnet NoteProperty string edns_client_subnet=0.0.0.0/0
        Question NoteProperty Object[] Question=System.Object[]
        RA NoteProperty bool RA=True
        RD NoteProperty bool RD=True
        Status NoteProperty int Status=0
        TC NoteProperty bool TC=False
     
    Status : 0
    TC : False
    RD : True
    RA : True
    AD : False
    CD : False
    Question : {@{name=www.lucas-cueff.com.; type=1}}
    Answer : {@{name=www.lucas-cueff.com.; type=1; TTL=3599; data=94.23.25.71}}
    Additional : {}
    edns_client_subnet : 0.0.0.0/0
    Comment : Response from 207.46.15.59.
    cli-Request_Padding : 99e913d3-b4ea-430a-8bbc-86e069e251c4
    cli-Request_Date : 09/02/2018 22:19:31
 
    .EXAMPLE
    Request info for lucas-cueff.com domain
    C:\PS> Resolve-DNSNameOverHTTP -name lucas-cueff.com -searchtype ANY
 
    .EXAMPLE
    Request info for lucas-cueff.com domain with DNSSEC option
    C:\PS> Resolve-DNSNameOverHTTP -name lucas-cueff.com -searchtype ANY -DNSSEC
 
    .EXAMPLE
    Request info for lucas-cueff.com domain with DNSSEC option
    C:\PS> Resolve-DNSNameOverHTTP -name lucas-cueff.com -searchtype ANY -DNSSEC
 
    .EXAMPLE
    Request info for lucas-cueff.com domain with DNSSEC option for source subnet 80.92.114.0/23
    C:\PS> Resolve-DNSNameOverHTTP -name lucas-cueff.com -searchtype ANY -DNSSEC -EDNSClientSubnet '80.92.114.0/23'
 
#>

    [cmdletbinding()]
    Param (    
        [parameter(ValueFromPipelineByPropertyName=$true,ValueFromPipeline=$true,Mandatory=$true)]
            [String[]]$name,
        [parameter(Mandatory=$true)] 
            [ValidateSet('A','AAAA','CNAME','MX','ANY')]
            [String[]]$searchtype, 
        [parameter(Mandatory=$false)]
            [switch]$DNSSEC,
        [parameter(Mandatory=$false)]
        [ValidateScript({($_ -match "(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])") -or ($_ -match "s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?")})]
            [string[]]$EDNSClientSubnet,
        [parameter(Mandatory=$false)]
            [switch]$SimpleOutput
    )
    $DateRequest = get-date
    $padding = (new-guid).guid
    $baseurl = "https://dns.google.com/resolve?"
    If (!$EDNSClientSubnet) {
        $EDNSClientSubnet = "0.0.0.0/0"
    }
    If ($DNSSEC.IsPresent) {
        $cd = "true"
    } Else {
        $cd = "false"
    }
    $requesturl = "$($baseurl)name=$($name)&type=$($searchtype)&random_padding=$padding&edns_client_subnet=$($EDNSClientSubnet)&cd=$($cd)"
    try {
        $dnsresult = invoke-webrequest $requesturl
    } catch {
        if ($debug -or $verbose) {
            write-warning "Not able to use Google DNS online API service - KO"
            write-warning "Error Type: $($_.Exception.GetType().FullName)"
            write-warning "Error Message: $($_.Exception.Message)"
            write-warning "HTTP error code:$($_.Exception.Response.StatusCode.Value__)"
            write-warning "HTTP error message:$($_.Exception.Response.StatusDescription)"
        }
        $errorvalue = @()
        $errorvalue += [PSCustomObject]@{
             error = $_.Exception.Response.StatusCode.Value__
             'cli-error_results' = "$($_.Exception.Response.StatusDescription)"
             'cli-Request_Padding' = $padding
             'cli-Request_Date' = $DateRequest
         }
    }
    if (-not $errorvalue) {
        try {
            $temp = $dnsresult.Content | convertfrom-json
            $temp | add-member -MemberType NoteProperty -Name 'cli-Request_Padding' -Value $padding
            $temp | add-member -MemberType NoteProperty -Name 'cli-Request_Date' -Value $DateRequest
        } catch {
            if ($debug -or $verbose) {
                write-warning "unable to convert result into a powershell object - json error"
                write-warning "Error Type: $($_.Exception.GetType().FullName)"
                write-warning "Error Message: $($_.Exception.Message)"
            }
            $errorvalue = @()
            $errorvalue += [PSCustomObject]@{
                'cli-error_results' = "$($_.Exception.GetType().FullName) - $($_.Exception.Message) : $($dnsresult.Content)"
                'cli-Request_Padding' = $padding
                'cli-Request_Date' = $DateRequest
            }
        }
    }
    if ($temp) {
        If (-not $SimpleOutput.IsPresent) {
            return $temp
        } else {
            if ($temp.Answer) {
                return $temp.Answer
            } else {
                return $temp.Authority
            }
        }
    }
    if ($errorvalue) {return $errorvalue}
}

Export-ModuleMember -Function Resolve-DNSNameOverHTTP