Foto por Eran Menashri / Unsplash - discos enfileirados

Como configurar DNS Over HTTPS global no Linux

dns 19 de Dez de 2023

Na minha rede local, tenho um servidor Adguard Home rodando em um Raspberry 1 bem antigo. O Adguard Home é um proxy DNS open source licenciado sob a GPL-3.0 e muito bem desenvolvido em Golang. Estou muito satisfeito com ele, pois consigo monitorar as requisições DNS feitas na rede, uma vez que configurei o roteador para apontar para esse servidor. Além disso, tenho todo tipo de configuração nele, como bloqueio de anúncios e DoH (DNS-Over-HTTPS).

Mas para isso eu preciso estar na minha rede local em casa e ao me hospedar em um Airbnb recentemente, fiquei preocupado com a possibilidade de que o dono da rede pudesse monitorar o que eu estava acessando na conexão. Alguns podem chamar isso de "excesso de zelo", mas se eu posso dar mais um passo para preservar a minha privacidade, prefiro dar esse passo e seguir em frente. Além disso, consegui aprender algumas coisas novas durante o processo.

No meu caso específico, tenho essa necessidade de utilizar o meu servidor DNS dentro da minha rede doméstica e um serviço público de resolução de DNS via HTTPS quando estiver fora de casa.

Minha primeira tentativa foi utilizar o systemd-resolved para configurar um DNS global já que estou usando o systemd como sistema de init. Trata-se de um serviço do systemd o qual é possível utilizá-lo para resolver DNS. Infelizmente, até onde consegui descobrir pela documentação, ele só é compatível com DNS-Over-TLS que, apesar de também ser criptografado, utiliza a porta 853 para as requisições, podendo ser facilmente bloqueada por um administrador de rede mal-intensionado.

Apesar disso não ser muito comum, prefiro utilizar o DoH pelo fato desse utilizar a porta 443 para as requisições, uma vez que esta é a mesma porta utilizada para acessar sites em HTTPS. Dessa forma, é quase impossível que essa porta seja bloqueada em qualquer rede. Caso contrário, boa parte da web ficará inacessível.

A solução foi utilizar uma aplicação chamada dnsproxy (que também é uma aplicação open source desenvolvida pelo time da Adguard) e que funciona como um proxy DNS capaz de resolver DNS através de todos os protocolos disponíveis hoje: DNS-over-TLS, DNS-over-HTTPS, DNSCrypt e DNS-over-QUIC.

A primeira coisa a fazer é instalar o dnsproxy. Não vou me aprofundar aqui, pois a página do projeto no Github tem todas as instruções de como instalar o programa. No meu caso, utilizei o pacote no AUR do Archlinux.

Em seguida, certifique-se de que você não tem nenhum serviço rodando na porta 53 executando o comando ss -lp 'sport = :domain'. Se o resultado for apenas o cabeçalho abaixo, pode seguir em frente.

Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port Process

Vamos configurar o arquivo de configuração do dnsproxy para acessar o meu servidor de DNS local e fazer fallback para outros serviços caso não consiga acessar o servidor local. Para isso editei o seguinte arquivo de configuração em /etc/dnsproxy/dnsproxy.yaml. No meu caso, coloquei o IP do meu servidor DNS no campo upstream e o endereço de serviços DoH no campo fallback:

---
bootstrap:
  - "8.8.8.8:53"
listen-addrs:
  - "0.0.0.0"
listen-ports:
  - 53
max-go-routines: 0
ratelimit: 0
ratelimit-subnet-len-ipv4: 24
ratelimit-subnet-len-ipv6: 64
udp-buf-size: 0
upstream:
  - "192.168.31.10:53"
fallback:
  - "https://dns.nextdns.io"
  - "https://dns.cloudflare.com/dns-query"
  - "https://dns.quad9.net/dns-query"
timeout: '10s'

Agora vamos criar um arquivo de configuração do Systemd para que o sistema sempre inicie o serviço para nós. Vamos criar um arquivo em /etc/systemd/system/dnsproxy.service e editá-lo da seguinte forma:

[Unit]
Description=dnsproxy service
After=network.target
Requires=network.target
 
[Service]
Type=simple
ExecStart=/usr/sbin/dnsproxy --config-path=/etc/dnsproxy/dnsproxy.yaml
Restart=on-failure

[Install]
WantedBy=multi-user.target

No meu caso, estou utilizando o Network Manager, que, por sua vez, configura o DNS para cada rede em que se conecta editando o arquivo /etc/resolv.conf com o DNS fornecido pelo servidor DHCP. Vamos modificar isso editando o arquivo /etc/NetworkManager/NetworkManager.conf:

[main]
# do not use the dhcp-provided dns servers, but rather use the global
# ones specified in /etc/resolv.conf
dns=none
rc-manager=unmanaged

Pronto! Agora tudo que temos que fazer é:

  1. Recarregar as configurações do Network Manager: sudo systemctl reload NetworkManager.service.
  2. Habilitar o dnsproxy no Systemd: sudo systemctl enable dnsproxy.service.
  3. E iniciar o serviço através do comando: sudo systemctl start dnsproxy.service.
  4. Por último, vamos configurar o arquivo /etc/resolv.conf para utilizar o dnsproxy como serviço de DNS:
nameserver 127.0.0.1
nameserver ::1

Pronto! Dessa forma será possível utilizar o servidor Adguard Home na minha rede doméstica e utilizar DoH quando estiver fora dela sem que o Network Manager utilize o servidor DNS fornecido pelo DHCP da rede em que eu me conectar.

Marcadores