Skip to content

DoH: como funciona a consulta DNS no Clear Address?

Published at

🇧🇷 TabNews on 2024-07-06
🇧🇷 Dev.to on 2024-08-08

Olá, pessoal!

Recentemente, o valterpatrick sugeriu que mostrasse como as consultas DNS são realizadas no site clear-address.rda.run. Agradeço muito pela pergunta, pois ela abre espaço para discutirmos um tema que considero fascinante e muito útil: DNS over HTTPS (DoH).

Em vez de usar o protocolo DNS tradicional, que geralmente opera de forma não criptografada na porta 53, o site utiliza as APIs públicas de resolvedores DNS que suportam HTTPS. Na prática, isso significa que uma consulta DNS se transforma em uma simples chamada HTTP. Isso traz uma camada extra de privacidade e segurança, pois a consulta se camufla como tráfego HTTPS comum.

A Mágica por Trás da Cortina: As APIs

O backend do Clear Address faz chamadas para resolvedores DoH, como os oferecidos pela Cloudflare e pelo Google. A escolha entre eles pode variar, mas o princípio é exatamente o mesmo.

A ideia é enviar uma requisição GET para um endpoint específico, passando o domínio e o tipo de registro desejado como parâmetros na URL. O servidor responde com um JSON contendo os resultados da consulta.

DoH via Cloudflare

A Cloudflare é uma das provedoras mais conhecidas de serviços DoH. A documentação completa pode ser encontrada aqui.

Para consultar o registro AAAA (endereço IPv6) do próprio clear-address.rda.run, a URL da API fica assim:

js
https://cloudflare-dns.com/dns-query?name=clear-address.rda.run&type=AAAA

Usando cURL

Você pode testar isso diretamente no seu terminal com o cURL. O header Accept é importante para garantir que a Cloudflare nos devolva uma resposta em JSON.

bash
curl -H 'Accept: application/dns-json' 'https://cloudflare-dns.com/dns-query?name=clear-address.rda.run&type=AAAA'

Usando Go

No backend, o processo é similar. Aqui está um exemplo simples em Go de como fazer essa chamada e processar a resposta.

go
package main

import (
    "encoding/json"
    "fmt"
    "io"
    "net/http"
)

// Estrutura para receber a resposta da API da Cloudflare
type DNSResponse struct {
    Status   int  `json:"Status"`
    TC       bool `json:"TC"`
    RD       bool `json:"RD"`
    RA       bool `json:"RA"`
    AD       bool `json:"AD"`
    CD       bool `json:"CD"`
    Question []struct {
        Name string `json:"name"`
        Type int    `json:"type"`
    } `json:"Question"`
    Answer []struct {
        Name string `json:"name"`
        Type int    `json:"type"`
        TTL  int    `json:"TTL"`
        Data string `json:"data"`
    } `json:"Answer"`
}

func main() {
    // URL da API da Cloudflare para a consulta desejada
    url := "https://cloudflare-dns.com/dns-query?name=clear-address.rda.run&type=AAAA"

    // Cria uma nova requisição
    req, err := http.NewRequest("GET", url, nil)
    if err != nil {
        panic(err)
    }

    // Adiciona o header 'Accept' para especificar o formato da resposta
    req.Header.Add("Accept", "application/dns-json")

    // Executa a requisição
    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()

    // Lê o corpo da resposta
    body, err := io.ReadAll(resp.Body)
    if err != nil {
        panic(err)
    }

    // Decodifica o JSON na nossa struct
    var dnsResp DNSResponse
    if err := json.Unmarshal(body, &dnsResp); err != nil {
        panic(err)
    }

    // Imprime os resultados
    fmt.Println("Resultados da consulta DNS:")
    if len(dnsResp.Answer) > 0 {
        for _, answer := range dnsResp.Answer {
            fmt.Printf(" - Domínio: %s\n", answer.Name)
            fmt.Printf("   Tipo: AAAA\n")
            fmt.Printf("   TTL: %d\n", answer.TTL)
            fmt.Printf("   Endereço IPv6: %s\n", answer.Data)
        }
    } else {
        fmt.Println("Nenhum registro AAAA encontrado.")
    }
}

DoH via Google

O Google oferece um serviço similar, documentado aqui. A lógica é a mesma, mudando apenas a URL.

text
https://dns.google/resolve?name=clear-address.rda.run&type=AAAA

A implementação, seja com cURL ou Go, seguiria o mesmo padrão, adaptando-se apenas à estrutura do JSON de resposta do Google, que pode ter pequenas diferenças.

Backend vs. Frontend

Uma observação importante: no Clear Address, essas chamadas são sempre feitas pelo backend. Nunca tentei fazê-las diretamente pelo frontend (via JavaScript no navegador), então não sei dizer se haveria problemas com CORS (Cross-Origin Resource Sharing) ou a necessidade de algum header específico para que a requisição fosse aceita. Fazer pelo backend simplifica o processo e mantém a lógica de negócio no servidor.

Conclusão

E é isso! Sem grande complexidade, o Clear Address apenas utiliza as APIs públicas e bem documentadas de grandes players para resolver nomes de domínio de forma segura e privada.