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.

zgdns.r 4.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. ipv4_regex <-
  2. "^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$"
  3. S_GET <- safely(httr::GET)
  4. #' Perform DNS over HTTPS queries using Google
  5. #'
  6. #' Traditional DNS queries and responses are sent over UDP or TCP without
  7. #' encryption. This is vulnerable to eavesdropping and spoofing (including
  8. #' DNS-based Internet filtering). Responses from recursive resolvers to clients
  9. #' are the most vulnerable to undesired or malicious changes, while
  10. #' communications between recursive resolvers and authoritative nameservers
  11. #' often incorporate additional protection.\cr
  12. #' \cr
  13. #' To address this problem, Google Public DNS offers DNS resolution over an
  14. #' encrypted HTTPS connection. DNS-over-HTTPS greatly enhances privacy and
  15. #' security between a client and a recursive resolver, and complements DNSSEC
  16. #' to provide end-to-end authenticated DNS lookups.
  17. #'
  18. #' To perform vectorized queries with only answers (and no metadata) use
  19. #' \code{bulk_query()}).
  20. #'
  21. #' @param name item to lookup. Valid characters are numbers, letters, hyphen, and dot. Length
  22. #' must be between 1 and 255. Names with escaped or non-ASCII characters
  23. #' are not supported. Internationalized domain names must use the
  24. #' punycode format (e.g. "\code{xn--qxam}").\cr
  25. #' \cr If an IPv4 string is input, it will be transformed into
  26. #' a proper format for reverse lookups.
  27. #' @param type RR type can be represented as a number in [1, 65535] or canonical
  28. #' string (A, aaaa, etc). More information on RR types can be
  29. #' found \href{http://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml#dns-parameters-4}{here}.
  30. #' You can use \code{255} for an \code{ANY} query.
  31. #' @param cd (Checking Disabled) flag. Use `TRUE` to disable DNSSEC validation;
  32. #' Default: `FALSE`.
  33. #' @param do (DNSSEC OK) flag. Use `TRUE` include DNSSEC records (RRSIG, NSEC, NSEC3);
  34. #' Default: `FALSE`.
  35. #' @param random_padding clients concerned about possible side-channel privacy
  36. #' attacks using the packet sizes of HTTPS GET requests can use this to
  37. #' make all requests exactly the same size by padding requests with random data.
  38. #' To prevent misinterpretation of the URL, restrict the padding characters to
  39. #' the unreserved URL characters: upper- and lower-case letters, digits,
  40. #' hyphen, period, underscore and tilde.
  41. #' @param edns_client_subnet The edns0-client-subnet option. Format is an IP
  42. #' address with a subnet mask. Examples: \code{1.2.3.4/24},
  43. #' \code{2001:700:300::/48}.\cr
  44. #' If you are using DNS-over-HTTPS because of privacy concerns, and do
  45. #' not want any part of your IP address to be sent to authoritative
  46. #' nameservers for geographic location accuracy, use
  47. #' \code{edns_client_subnet=0.0.0.0/0}. Google Public DNS normally sends
  48. #' approximate network information (usually replacing the last part of
  49. #' your IPv4 address with zeroes). \code{0.0.0.0/0} is the default.
  50. #' @return a \code{list} with the query result or \code{NULL} if an error occurred
  51. #' @references <https://developers.google.com/speed/public-dns/docs/doh/json>
  52. #' @export
  53. #' @examples
  54. #' query("rud.is")
  55. #' dig("example.com", "255") # ANY query
  56. #' query("microsoft.com", "MX")
  57. #' dig("google-public-dns-a.google.com", "TXT")
  58. #' query("apple.com")
  59. #' dig("17.142.160.59", "PTR")
  60. query <- function(name, type = "1", cd = FALSE, do = FALSE,
  61. edns_client_subnet = "0.0.0.0/0",
  62. random_padding = NULL) {
  63. name <- name[1]
  64. # helper to turn IPv4 addresses in to in-addr.arpa.
  65. if (grepl(ipv4_regex, name)) {
  66. name <- paste0(c(rev(unlist(stringi::stri_split_fixed(name, ".", 4))),
  67. "in-addr.arpa."),
  68. sep="", collapse=".")
  69. }
  70. res <- S_GET(
  71. url = "https://dns.google/resolve",
  72. query = list(
  73. name = name,
  74. type = type,
  75. cd = if (cd) 1 else 0,
  76. do = if (do) 1 else 0,
  77. ct = "application/x-javascript",
  78. edns_client_subnet = edns_client_subnet,
  79. random_padding = random_padding
  80. )
  81. )
  82. if (!is.null(res$result)) {
  83. stop_for_status(res$result)
  84. txt <- httr::content(res$result, as="text")
  85. txt <- stringi::stri_enc_toascii(txt)
  86. txt <- stringi::stri_replace_all_regex(txt, "[[:cntrl:][:blank:]\\n ]+", " ")
  87. out <- jsonlite::fromJSON(txt)
  88. class(out) <- c("gdns_response", "list")
  89. out
  90. } else {
  91. NULL
  92. }
  93. }
  94. #' @rdname query
  95. #' @export
  96. dig <- query