Tools to work with the Google DNS over HTTPS API in R https://cinc.rud.is/web/packages/gdns/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

209 lines
8.1 KiB

4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
  1. <!-- README.md is generated from README.Rmd. Please edit that file -->
  2. [![Travis-CI Build
  3. Status](https://travis-ci.org/hrbrmstr/gdns.svg?branch=master)](https://travis-ci.org/hrbrmstr/gdns)
  4. `gdns` : Tools to work with the Google DNS over HTTPS API
  5. Traditional DNS queries and responses are sent over UDP or TCP without
  6. encryption. This is vulnerable to eavesdropping and spoofing (including
  7. DNS-based Internet filtering). Responses from recursive resolvers to
  8. clients are the most vulnerable to undesired or malicious changes, while
  9. communications between recursive resolvers and authoritative nameservers
  10. often incorporate additional protection.
  11. To address this problem, Google Public DNS offers DNS resolution over an
  12. encrypted HTTPS connection. DNS-over-HTTPS greatly enhances privacy and
  13. security between a client and a recursive resolver, and complements
  14. DNSSEC to provide end-to-end authenticated DNS lookups.
  15. More info at
  16. <https://developers.google.com/speed/public-dns/docs/dns-over-https>.
  17. The following functions are implemented:
  18. - `bulk_query`: Vectorized query, returning only answers in a data
  19. frame
  20. - `has_spf`: Test for whether a DNS TXT record is an SPF record
  21. - `is_hard_fail`: SPF “all” type test
  22. - `is_soft_fail`: SPF “all” type test
  23. - `passes_all`: SPF “all” type test
  24. - `query`: Perform DNS over HTTPS queries using Google
  25. - `spf_exists`: SPF field extraction functions
  26. - `spf_includes`: SPF field extraction functions
  27. - `spf_ipv4s`: SPF field extraction functions
  28. - `spf_ipv6s`: SPF field extraction functions
  29. - `spf_ptrs`: SPF field extraction functions
  30. - `split_spf`: Split out all SPF records in a domain’s TXT record
  31. ### Installation
  32. ``` r
  33. devtools::install_github("hrbrmstr/gdns")
  34. ```
  35. ### Usage
  36. ``` r
  37. library(gdns)
  38. # current verison
  39. packageVersion("gdns")
  40. #> [1] '0.3.1'
  41. str(query("rud.is"))
  42. #> List of 10
  43. #> $ Status : int 0
  44. #> $ TC : logi FALSE
  45. #> $ RD : logi TRUE
  46. #> $ RA : logi TRUE
  47. #> $ AD : logi FALSE
  48. #> $ CD : logi FALSE
  49. #> $ Question :'data.frame': 1 obs. of 2 variables:
  50. #> ..$ name: chr "rud.is."
  51. #> ..$ type: int 1
  52. #> $ Answer :'data.frame': 1 obs. of 4 variables:
  53. #> ..$ name: chr "rud.is."
  54. #> ..$ type: int 1
  55. #> ..$ TTL : int 3536
  56. #> ..$ data: chr "104.236.112.222"
  57. #> $ Additional : list()
  58. #> $ edns_client_subnet: chr "0.0.0.0/0"
  59. str(query("example.com", "255")) # "ANY" query
  60. #> List of 10
  61. #> $ Status : int 0
  62. #> $ TC : logi FALSE
  63. #> $ RD : logi TRUE
  64. #> $ RA : logi TRUE
  65. #> $ AD : logi TRUE
  66. #> $ CD : logi FALSE
  67. #> $ Question :'data.frame': 1 obs. of 2 variables:
  68. #> ..$ name: chr "example.com."
  69. #> ..$ type: int 255
  70. #> $ Answer :'data.frame': 20 obs. of 4 variables:
  71. #> ..$ name: chr [1:20] "example.com." "example.com." "example.com." "example.com." ...
  72. #> ..$ type: int [1:20] 6 46 47 46 2 2 46 28 46 1 ...
  73. #> ..$ TTL : int [1:20] 3566 3566 3566 21566 21566 21566 21566 21566 21566 21566 ...
  74. #> ..$ data: chr [1:20] "sns.dns.icann.org. noc.dns.icann.org. 2018080123 7200 3600 1209600 3600" "nsec 8 2 3600 1538855995 1537006806 63855 example.com. pFyGCdsJ2uw2FcRlszW1VuM6FRV1rHbBfeBmp/Jaecdth8njienGYt2k"| __truncated__ "www.example.com. A NS SOA TXT AAAA RRSIG NSEC DNSKEY" "ns 8 2 86400 1538826642 1537014006 63855 example.com. U7KJg6I3XylL5aT10B3tHw9MIV8QoHBlmzO3CwghRh4I00ZzF2IgjakMp"| __truncated__ ...
  75. #> $ Additional : list()
  76. #> $ edns_client_subnet: chr "0.0.0.0/0"
  77. str(query("microsoft.com", "MX"))
  78. #> List of 10
  79. #> $ Status : int 0
  80. #> $ TC : logi FALSE
  81. #> $ RD : logi TRUE
  82. #> $ RA : logi TRUE
  83. #> $ AD : logi FALSE
  84. #> $ CD : logi FALSE
  85. #> $ Question :'data.frame': 1 obs. of 2 variables:
  86. #> ..$ name: chr "microsoft.com."
  87. #> ..$ type: int 15
  88. #> $ Answer :'data.frame': 1 obs. of 4 variables:
  89. #> ..$ name: chr "microsoft.com."
  90. #> ..$ type: int 15
  91. #> ..$ TTL : int 3507
  92. #> ..$ data: chr "10 microsoft-com.mail.protection.outlook.com."
  93. #> $ Additional : list()
  94. #> $ edns_client_subnet: chr "0.0.0.0/0"
  95. str(query("google-public-dns-a.google.com", "TXT"))
  96. #> List of 10
  97. #> $ Status : int 0
  98. #> $ TC : logi FALSE
  99. #> $ RD : logi TRUE
  100. #> $ RA : logi TRUE
  101. #> $ AD : logi FALSE
  102. #> $ CD : logi FALSE
  103. #> $ Question :'data.frame': 1 obs. of 2 variables:
  104. #> ..$ name: chr "google-public-dns-a.google.com."
  105. #> ..$ type: int 16
  106. #> $ Answer :'data.frame': 1 obs. of 4 variables:
  107. #> ..$ name: chr "google-public-dns-a.google.com."
  108. #> ..$ type: int 16
  109. #> ..$ TTL : int 21537
  110. #> ..$ data: chr "\"http://xkcd.com/1361/\""
  111. #> $ Additional : list()
  112. #> $ edns_client_subnet: chr "0.0.0.0/0"
  113. str(query("apple.com"))
  114. #> List of 10
  115. #> $ Status : int 0
  116. #> $ TC : logi FALSE
  117. #> $ RD : logi TRUE
  118. #> $ RA : logi TRUE
  119. #> $ AD : logi FALSE
  120. #> $ CD : logi FALSE
  121. #> $ Question :'data.frame': 1 obs. of 2 variables:
  122. #> ..$ name: chr "apple.com."
  123. #> ..$ type: int 1
  124. #> $ Answer :'data.frame': 3 obs. of 4 variables:
  125. #> ..$ name: chr [1:3] "apple.com." "apple.com." "apple.com."
  126. #> ..$ type: int [1:3] 1 1 1
  127. #> ..$ TTL : int [1:3] 3557 3557 3557
  128. #> ..$ data: chr [1:3] "17.172.224.47" "17.178.96.59" "17.142.160.59"
  129. #> $ Additional : list()
  130. #> $ edns_client_subnet: chr "0.0.0.0/0"
  131. str(query("17.142.160.59", "PTR"))
  132. #> List of 10
  133. #> $ Status : int 0
  134. #> $ TC : logi FALSE
  135. #> $ RD : logi TRUE
  136. #> $ RA : logi TRUE
  137. #> $ AD : logi FALSE
  138. #> $ CD : logi FALSE
  139. #> $ Question :'data.frame': 1 obs. of 2 variables:
  140. #> ..$ name: chr "59.160.142.17.in-addr.arpa."
  141. #> ..$ type: int 12
  142. #> $ Answer :'data.frame': 5 obs. of 4 variables:
  143. #> ..$ name: chr [1:5] "59.160.142.17.in-addr.arpa." "59.160.142.17.in-addr.arpa." "59.160.142.17.in-addr.arpa." "59.160.142.17.in-addr.arpa." ...
  144. #> ..$ type: int [1:5] 12 12 12 12 12
  145. #> ..$ TTL : int [1:5] 2733 2733 2733 2733 2733
  146. #> ..$ data: chr [1:5] "apple.by." "apple.com." "pv-apple-com.apple.com." "ipad.host." ...
  147. #> $ Additional : list()
  148. #> $ edns_client_subnet: chr "0.0.0.0/0"
  149. hosts <- c("rud.is", "dds.ec", "r-project.org", "rstudio.com", "apple.com")
  150. gdns::bulk_query(hosts)
  151. #> name type TTL data entity
  152. #> 1 rud.is. 1 806 104.236.112.222 rud.is
  153. #> 2 dds.ec. 1 507 185.53.178.9 dds.ec
  154. #> 3 r-project.org. 1 7199 137.208.57.37 r-project.org
  155. #> 4 rstudio.com. 1 3536 104.196.200.5 rstudio.com
  156. #> 5 apple.com. 1 3082 17.172.224.47 apple.com
  157. #> 6 apple.com. 1 3082 17.178.96.59 apple.com
  158. #> 7 apple.com. 1 3082 17.142.160.59 apple.com
  159. ```
  160. ### Test Results
  161. ``` r
  162. library(gdns)
  163. library(testthat)
  164. date()
  165. #> [1] "Sat Sep 15 14:29:20 2018"
  166. test_dir("tests/")
  167. #> ✔ | OK F W S | Context
  168. #> ══ testthat results ═════════════════════════════════════════════════════════════════════════════════════════
  169. #> OK: 2 SKIPPED: 0 FAILED: 0
  170. #>
  171. #> ══ Results ═══════════════════════════════════════════════════════════════════════════════════════════════════
  172. #> Duration: 0.4 s
  173. #>
  174. #> OK: 0
  175. #> Failed: 0
  176. #> Warnings: 0
  177. #> Skipped: 0
  178. ```
  179. ### Code of Conduct
  180. Please note that this project is released with a [Contributor Code of
  181. Conduct](CONDUCT.md). By participating in this project you agree to
  182. abide by its terms.