Se você nunca ouviu falar de DoH além do Homer reclamando que fez alguma bobagem, então não está na Internet tempo o suficiente.  E talvez não esteja protegendo sua privacidade como poderia.

DNS, de Domain Name Service (serviço de nomes de domíno), é o que traduz um nome de domínio como helio.loureiro.eng.br pra um endereço IP.  No caso de helio.loureiro.eng.br o nome é resolvido tanto pra IPv4 quanto pra IPv6.

Por mais inocente que seja essa tradução, esse dado não tem criptografia ou qualquer outro tipo de proteção.  Pode e provavelmente é usado por seu provedor de Internet pra conhecer seus hábitos de navegação e até vender esse dado pra alguém.

Pra coibir tal uso de sua informação pessoal foi criado o protocolo DoH, ou DNS over HTTPS, que é a requisição de DNS enviada por HTTPS.  A vantagem desse método é que ninguém consegue diferenciar seu tráfego HTTPS como sendo uma requisição DNS ou acesso a uma página web, que é protegida por uma camada de SSL de criptografia. O firefox permite a configuração de forma bastante fácil.

Mas claro que em alguns lugares o acesso pode ser barrado pra dificultar seu acesso ao DoH e forçar o uso de um serviço de DNS local.  Por padrão o firefox permite usar o serviço do Cloudflare ou do NextDNS.  O que fazem alguns provedores é bloquear requisições pra esses destinos.  Mesmo o serviço de DoH do OpenDNS é bloqueado.

Pra previnir isso eu habilitei um DoH relay que recebe as requisições e envia para https://doh.opendns.com/dns-query pra resolver.  Então para usar o serviço, basta configurar como fiz acima no Firefox e usar o destino:

https://truta.org/dns-query

E claro que esse artigo não é só pra dizer que esse serviço está habilitado.  É pra mostrar como montar o seu.

Eu usei o binário de um doh-relay escrito em Go e disponível no github aqui:

https://github.com/tinkernels/doh-relay

A compilação foi um simples comando, assumindo que tenha o Go pra fazer a compilação:

macOS in ~
✦ ❯ cd /tmp

macOS in /tmp
✦ ❯ git clone https://github.com/tinkernels/doh-relay.git
Cloning into 'doh-relay'...
remote: Enumerating objects: 461, done.
remote: Counting objects: 100% (192/192), done.
remote: Compressing objects: 100% (136/136), done.
remote: Total 461 (delta 127), reused 117 (delta 56), pack-reused 269
Receiving objects: 100% (461/461), 180.87 KiB | 3.17 MiB/s, done.
Resolving deltas: 100% (307/307), done.

macOS in /tmp
✦ ❯ cd doh-relay

macOS in doh-relay on  master via 🐹 v1.22.0
✦ ❯ make linux-amd64
mkdir -p release
GOOS=linux GOARCH=amd64 go build  -ldflags "-extldflags=-static -w -s" -o release/doh-relay_linux-amd64 .
go: downloading github.com/ReneKroon/ttlcache v1.7.0
go: downloading github.com/miekg/dns v1.1.54
go: downloading github.com/buraksezer/connpool v0.6.0
go: downloading github.com/gin-gonic/gin v1.9.0
go: downloading github.com/oschwald/geoip2-golang v1.8.0
go: downloading github.com/sirupsen/logrus v1.9.1
go: downloading gopkg.in/yaml.v3 v3.0.1
go: downloading golang.org/x/sys v0.8.0
go: downloading golang.org/x/net v0.10.0
go: downloading github.com/gin-contrib/sse v0.1.0
go: downloading github.com/mattn/go-isatty v0.0.18
go: downloading github.com/go-playground/validator/v10 v10.13.0
go: downloading github.com/ugorji/go/codec v1.2.11
go: downloading github.com/pelletier/go-toml/v2 v2.0.7
go: downloading github.com/oschwald/maxminddb-golang v1.10.0
go: downloading github.com/leodido/go-urn v1.2.4
go: downloading golang.org/x/crypto v0.9.0
go: downloading github.com/go-playground/universal-translator v0.18.1
go: downloading golang.org/x/text v0.9.0
go: downloading github.com/go-playground/locales v0.14.1

macOS in doh-relay on  master via 🐹 v1.22.0 took 9s
✦ ❯ mv release/doh-relay_linux-amd64 release/doh-relay

No servidor truta.org, copiei o binário pra /usr/local/bin.  E criei grupo e usuário.

root@truta /u/l/bin# addgroup --system doh-relay
Adding group `doh-relay' (GID 135) ...
Done.
root@truta /u/l/bin# adduser --system --gid 135 doh-relay
Adding system user `doh-relay' (UID 129) ...
Adding new user `doh-relay' (UID 129) with group `doh-relay' ...
Not creating `/nonexistent'.

Em seguida adicionei um serviço ao systemd e habilitei.

root@truta /# cd /etc/systemd/system
root@truta /e/s/system# vim doh-relay.service
root@truta /e/s/system# cat doh-relay.service
[Unit]
Description=Dns-over-HTTPS relay
After=syslog.target network.target

[Service]
User=doh-relay
Group=doh-relay
WorkingDirectory=/tmp
ExecStart=/usr/local/bin/doh-relay --cache=true --doh -doh-upstream=https://doh.opendns.com/dns-query
Type=simple
Restart=always
RestartSec=3

[Install]
WantedBy=default.target

root@truta /e/s/system# systemctl daemon-reload
root@truta /e/s/system# systemctl enable --now doh-relay.service
Created symlink /etc/systemd/system/default.target.wants/doh-relay.service → /etc/systemd/system/doh-relay.service.
root@truta /e/s/system# systemctl  status doh-relay
● doh-relay.service - Dns-over-HTTPS relay
     Loaded: loaded (/etc/systemd/system/doh-relay.service; enabled; preset: enabled)
     Active: active (running) since Thu 2024-03-07 09:47:09 -03; 5s ago
   Main PID: 819347 (doh-relay)
      Tasks: 6 (limit: 3535)
     Memory: 4.0M
        CPU: 15ms
     CGroup: /system.slice/doh-relay.service
             └─819347 /usr/local/bin/doh-relay --cache=true --doh -doh-upstream=https://doh.opendns.com/dns-query

Mar 07 09:47:09 truta.org systemd[1]: Started doh-relay.service - Dns-over-HTTPS relay.
Mar 07 09:47:09 truta.org doh-relay[819347]: *** Starting ***
Mar 07 09:47:09 truta.org doh-relay[819347]: time="2024-03-07T09:47:09" level=info msg="open : no such file or directory" file="geoip.go:41"
Mar 07 09:47:09 truta.org doh-relay[819347]: time="2024-03-07T09:47:09" level=info msg="resolver: [https://doh.opendns.com/dns-query], fallback: []" file="main.go:339"

O último passo foi adicionar a configuração ao apache com proxy interno conectando com a porta 15353 onde roda o doh-relay.

root@truta /e/a/conf-enabled# cat /etc/apache2/conf-enabled/doh-enabled.conf
<IfModule mod_proxy.c>
    ProxyVia On
    ProxyRequests Off
    ProxyPass /dns-query http://localhost:15353/dns-query retry=0 timeout=10
    ProxyPassReverse /dns-query http://localhost:15353/dns-query
    ProxyPreserveHost on
    <Proxy *>
        Options FollowSymLinks MultiViews
       AllowOverride All
       Order allow,deny
        allow from all
   </Proxy>
</IfModule>
    
root@truta /e/a/conf-enabled# a2enmod proxy
Module proxy already enabled
root@truta /e/a/conf-enabled# a2enmod proxy_html
Considering dependency proxy for proxy_html:
Module proxy already enabled
Considering dependency xml2enc for proxy_html:
Enabling module xml2enc.
Enabling module proxy_html.
To activate the new configuration, you need to run:
  systemctl restart apache2
root@truta /e/a/conf-enabled# a2enmod proxy_http
Considering dependency proxy for proxy_http:
Module proxy already enabled
Enabling module proxy_http.
To activate the new configuration, you need to run:
  systemctl restart apache2
root@truta /e/a/conf-enabled# a2enmod proxy_http2
Considering dependency proxy for proxy_http2:
Module proxy already enabled
Considering dependency http2 for proxy_http2:
Enabling module http2.
Enabling module proxy_http2.
To activate the new configuration, you need to run:
  systemctl restart apache2
root@truta /e/a/conf-enabled# apachectl configtest
Syntax OK
root@truta /e/a/conf-enabled# apachectl restart

E pronto.  Um relay de DoH pronto pra servir.