Como usar systemd-resolved para gerenciar DNS localmente no Linux

1. Introdução ao systemd-resolved e sua arquitetura

O systemd-resolved é um serviço de resolução de nomes integrado ao ecossistema systemd, projetado para gerenciar consultas DNS de forma eficiente e segura. Diferente de soluções tradicionais como dnsmasq ou BIND, o systemd-resolved opera como um stub resolver — um intermediário que encaminha consultas para servidores DNS configurados, mas também mantém um cache local para acelerar resoluções repetidas.

A arquitetura do systemd-resolved é centrada no endereço 127.0.0.53, que funciona como um resolvedor local. Quando um aplicativo faz uma consulta DNS, ela é redirecionada para esse endereço, que verifica o cache antes de encaminhar a consulta ao servidor DNS apropriado. Isso reduz significativamente a latência em redes com consultas frequentes.

Comparado a outros resolvedores:
- dnsmasq: Mais leve, mas com menos integração com systemd
- BIND: Completo, mas complexo para uso doméstico
- resolvconf: Apenas gerencia arquivos de configuração, não resolve consultas

O systemd-resolved oferece vantagens como suporte nativo a DNSSEC, cache inteligente e integração direta com systemd-networkd.

2. Instalação e ativação do serviço

Na maioria das distribuições Linux modernas (Ubuntu 18.04+, Fedora, Arch Linux), o systemd-resolved já está instalado. Para verificar:

$ systemctl status systemd-resolved
● systemd-resolved.service - Network Name Resolution
     Loaded: loaded (/lib/systemd/system/systemd-resolved.service; enabled)
     Active: active (running) since Mon 2024-01-15 10:30:00 BRT

Se o serviço não estiver ativo, inicie e habilite:

$ sudo systemctl enable --now systemd-resolved

O próximo passo é configurar o link simbólico /etc/resolv.conf para apontar para o stub resolver gerenciado pelo systemd-resolved:

$ sudo ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf

Isso garante que todas as consultas DNS do sistema passem pelo systemd-resolved.

3. Configuração básica de servidores DNS

O arquivo principal de configuração é /etc/systemd/resolved.conf. Exemplo de configuração básica:

[Resolve]
DNS=8.8.8.8 8.8.4.4
FallbackDNS=1.1.1.1 9.9.9.9
Domains=~.
DNSSEC=allow-downgrade
  • DNS: Servidores DNS primários (separados por espaço)
  • FallbackDNS: Servidores usados se os primários falharem
  • Domains: ~. significa que todos os domínios usam esses servidores
  • DNSSEC: allow-downgrade tenta validar DNSSEC, mas não falha se não for suportado

Para configuração por interface, use o comando resolvectl:

$ resolvectl dns eth0 192.168.1.1
$ resolvectl domain eth0 "~local" "~corporativo.com"

Para visualizar configurações ativas:

$ resolvectl status
Global
       Protocols: -LLMNR -mDNS -DNSOverTLS DNSSEC=allow-downgrade
resolv.conf mode: stub

Link 2 (eth0)
    Current Scopes: DNS
         Protocols: +DefaultRoute +LLMNR -mDNS -DNSOverTLS
       DNS Servers: 192.168.1.1 8.8.8.8
        DNS Domain: ~corporativo.com ~local

4. Gerenciamento de domínios e zonas de pesquisa

Uma das funcionalidades mais poderosas do systemd-resolved é o roteamento condicional de consultas DNS por domínio. Isso é essencial em ambientes com múltiplas redes (por exemplo, rede corporativa + internet pública).

Exemplo prático: configurar DNS corporativo para domínios internos e DNS público para o resto:

$ resolvectl dns eth0 10.0.0.1
$ resolvectl domain eth0 "~corporativo.com" "~interna.local"

$ resolvectl dns wlan0 8.8.8.8
$ resolvectl domain wlan0 "~."

Aqui, consultas para *.corporativo.com e *.interna.local usam o servidor DNS corporativo (10.0.0.1), enquanto todas as outras consultas (~.) usam o Google DNS via Wi-Fi.

Para configurar domínios de pesquisa (search domains):

$ resolvectl domain eth0 "corporativo.com" "interna.local"

Isso permite resolver nomes curtos como servidor1 para servidor1.corporativo.com.

5. Cache DNS e otimização de performance

O systemd-resolved mantém um cache local que armazena resultados de consultas DNS por um período baseado no TTL (Time To Live) do registro. O cache inclui:
- Cache positivo: Resultados bem-sucedidos
- Cache negativo: Respostas indicando que um domínio não existe (NXDOMAIN)

Para visualizar estatísticas do cache:

$ resolvectl statistics
DNSSEC supported by current servers: yes
Transactions
Current Transactions: 0
  Total Transactions: 1250
  Total Cache Hits: 980 (78.4%)
  Total Cache Misses: 270

Uma alta taxa de cache hits indica boa performance. Para limpar manualmente o cache (útil após alterações de DNS):

$ sudo resolvectl flush-caches

Para monitorar o cache em tempo real:

$ sudo journalctl -u systemd-resolved -f

6. Solução de problemas e depuração

O comando resolvectl query é essencial para testar a resolução de nomes:

$ resolvectl query google.com
google.com: 142.250.218.78                       (reachable)
          2607:f8b0:4007:80b::200e              (reachable)

-- Information acquired via protocol DNS in 12.8ms.
-- Data is authenticated: yes

Para testar um servidor DNS específico:

$ resolvectl query google.com @@8.8.8.8

Análise de logs para diagnóstico:

$ journalctl -u systemd-resolved --since "5 minutes ago"

Problemas comuns e soluções:
- Conflito com outros resolvedores: Desative dnsmasq ou resolvconf (systemctl stop dnsmasq && systemctl disable dnsmasq)
- Permissões: O serviço deve rodar como root ou usuário systemd-resolve
- Firewall: Certifique-se de que a porta 53 UDP não está bloqueada localmente

7. Integração com containers e redes avançadas

Para containers Docker, configure o DNS globalmente no daemon do Docker (/etc/docker/daemon.json):

{
  "dns": ["127.0.0.53"]
}

Isso faz com que containers usem o systemd-resolved do host.

Em redes com VPN, configure roteamento condicional:

# Interface da VPN (tun0)
$ resolvectl dns tun0 10.8.0.1
$ resolvectl domain tun0 "~vpn.corporativo.com"

# Tráfego normal
$ resolvectl dns eth0 192.168.1.1
$ resolvectl domain eth0 "~."

Para redes complexas com múltiplas interfaces virtuais (tun/tap):

$ resolvectl default-route eth0 true
$ resolvectl default-route tun0 false

Isso garante que apenas consultas para domínios específicos da VPN sejam roteadas para o servidor DNS da VPN.

8. Dicas de segurança e boas práticas

Ative DNSSEC para validar respostas DNS:

[Resolve]
DNSSEC=yes
DNSOverTLS=yes

Isso impede ataques de envenenamento de cache e garante que as consultas sejam autenticadas.

Limite a escuta do serviço apenas ao localhost (padrão seguro):

[Resolve]
DNSStubListener=yes

Nunca exponha o stub resolver (127.0.0.53) para a rede externa.

Para ambientes de produção:
- Monitore o cache regularmente com resolvectl statistics
- Configure fallback DNS confiáveis (Cloudflare 1.1.1.1, Quad9 9.9.9.9)
- Use DNSSEC=allow-downgrade inicialmente, depois mude para yes quando validado
- Documente todas as configurações por interface

Em sistemas multi-usuário, considere usar namespaces de usuário para isolar consultas DNS entre diferentes usuários.

Referências