Home Comunidade Eventos YouTube Networks Desafios // produtos Academy News CTI | CVE Contato

08 - Systemd-networkd e systemd-resolved

video explicativo
Video explicativoEspaco reservado para o video desta anotação — adicione video: https://youtu.be/... no frontmatter da nota.

A modernização da infraestrutura de rede no ecossistema Linux liderada pela suíte systemd manifesta-se através de dois daemons especializados e fortemente integrados: o systemd-networkd (orquestração de interfaces, rotas e tabelas de enlace na Camada 2/3) e o systemd-resolved (resolução de nomes, gerenciamento de caches DNS e criptografia via DNSSEC/DNS-over-TLS na Camada 7).

Historicamente, o gerenciamento de rede em distribuições Linux era fragmentado em scripts shell imperativos específicos de cada distribuidor (como os arquivos /etc/network/interfaces no Debian ou /etc/sysconfig/network-scripts/ifcfg-* no RHEL/CentOS) ou delegado a ambientes dinâmicos orientados a sessões desktop interativas (como o NetworkManager).

A introdução do systemd-networkd e do systemd-resolved estabeleceu um padrão estritamente declarativo, determinístico e de alta performance, otimizado para servidores headless, ambientes de virtualização corporativa, contêineres e arquiteturas de nuvem (cloud-init).


1. Arquitetura do systemd-networkd

O systemd-networkd é um daemon de gerenciamento de rede nativo do espaço de usuário que monitora e configura interfaces de rede físicas e virtuais à medida que elas são detectadas pelo kernel Linux ou sinalizadas pelo sub-serviço systemd-udevd.

Em vez de invocar utilitários externos da suíte net-tools (ifconfig) ou da suíte iproute2 (ip), o systemd-networkd comunica-se diretamente com o subsistema Netlink do kernel Linux via soquetes de comunicação IPC de alta velocidade (NETLINK_ROUTE). Isso permite que o daemon configure endereços IP, tabelas de roteamento, vlan tags e pontes de rede (bridges) atomicamente na memória do kernel em escala de microssegundos, sem a sobrecarga de criar sub-processos do shell.

┌─────────────────────────────────────────────────────────────────────────┐
│                           ESPAÇO DE USUÁRIO                             │
│                                                                         │
│  [ Arquivos Declarativos em /etc/systemd/network/ ]                     │
│  ├── 10-netdev.netdev  (Criação de Dispositivos Virtuais: bond, bridge) │
│  └── 20-wired.network  (Endereçamento IP, Rotas, DHCP, DNS)             │
│                                                                         │
│                                 │ Parse Declarativo                     │
│                                 ▼                                       │
│                       systemd-networkd (Daemon)                         │
└─────────────────────────────────┬───────────────────────────────────────┘
                                  │
                                  │ IPC Direto via Soquete NETLINK_ROUTE
                                  ▼
┌─────────────────────────────────────────────────────────────────────────┐
│                            ESPAÇO DE KERNEL                             │
│                                                                         │
│  [ Subsistema de Rede do Kernel Linux ]                                 │
│  ├── Driver da Placa (enp3s0)  <── Netlink ──> Aplica IP/MAC            │
│  ├── Tabela de Roteamento (FIB) <── Netlink ──> Injeta Rotas            │
│  └── Dispositivos Virtuais (br0, vlan10) <── Netlink ──> Instancia Devs  │
└─────────────────────────────────────────────────────────────────────────┘


2. As Três Famílias de Arquivos Declarativos

A configuração do systemd-networkd é inteiramente declarativa e reside no caminho de carga /etc/systemd/network/ (prioridade do administrador), /run/systemd/network/ (transiente/efêmero) ou /usr/lib/systemd/network/ (padrões do fornecedor).

A suíte utiliza três extensões de arquivo distintas com semânticas bem definidas:

Os arquivos .link são processados pelo systemd-udevd durante a inicialização do dispositivo de hardware. Eles aplicam alterações na interface física antes que a pilha de rede de Camada 3 seja inicializada.

  • Aplicações: Renomear interfaces de rede, alterar endereços MAC físicos (MAC spoofing / cloning), configurar atalhos Offload da placa (TCPOffload), ajustar políticas de MTU física ou alterar parâmetros de velocidade e Duplex via ethtool.

2.2. Arquivos .netdev (Criação de Dispositivos Virtuais)

Os arquivos .netdev instruem o kernel Linux a instanciar dispositivos de rede virtuais na memória.

  • Aplicações: Criação de pontes de rede (Bridges - kind=bridge), agregação de links (Bonding / LACP - kind=bond), interfaces de VLAN 802.1Q (kind=vlan), túneis VPN WireGuard (kind=wireguard), ou interfaces virtuais para contêineres (kind=veth).

2.3. Arquivos .network (Configuração de Camada 3 / Endereçamento e Rota)

Os arquivos .network determinam como uma interface específica (física ou virtual criada por um .netdev) deve ser desempenhada no ambiente de rede.

  • Aplicações: Configuração de endereços IPv4/IPv6 estáticos ou via cliente DHCP integrado, rotas estáticas, opções de Gateway, servidores DNS e parâmetros de KeepAlive.

3. Estrutura e Dissecação de um Arquivo .network

A correspondência entre um arquivo de configuração .network e uma placa de rede física é determinada pela seção [Match]. Se a placa de rede detectada pelo kernel atender às condições do [Match], o systemd-networkd aplica as regras definidas nas seções subsequentes.

Exemplo de configuração estática avançada (/etc/systemd/network/10-servidor-estatico.network):

[Match]
Name=enp3s0

[Network]
Address=192.168.1.50/24
Gateway=192.168.1.1
DNS=127.0.0.53
DNS=1.1.1.1
Domains=empresa.local
NTP=pool.ntp.org
IPv6AcceptRA=no
LinkLocalAddressing=no

[Address]
Address=2001:db8:1::50/64

[Route]
Destination=10.0.0.0/8
Gateway=192.168.1.254
Metric=100

Dissecação das Diretivas Fundamentais:

  1. Seção [Match]:
    * Name=enp3s0: Aplica a regra especificamente à interface nomeada enp3s0. Aceita coringas (ex: Name=enp* para associar a todas as placas PCI Ethernet) ou buscas por endereço MAC (MACAddress=00:11:22:33:44:55).

  2. Seção [Network]:
    * Address=192.168.1.50/24: Define o endereço IPv4 e a máscara de rede em notação CIDR.
    * Gateway=192.168.1.1: Injeta a rota padrão (default gateway) na tabela de roteamento do kernel.
    * DNS=127.0.0.53: Exporta o endereço do servidor DNS para o systemd-resolved via D-Bus.
    * Domains=empresa.local: Define o domínio de busca de sufixos de host para resolução local.

  3. Seção [Route]:
    * Permite a adição de rotas estáticas para sub-redes específicas (Destination=10.0.0.0/8), definindo a métrica do caminho e gateways alternativos sem necessidade de executar scripts auxiliares.


4. Agregação de Enlace (Bonding) e Bridges com .netdev

A criação de infraestruturas complexas de rede para hipervisores (KVM/QEMU) utilizando o systemd-networkd demonstra o poder da composição declarativa.

Para criar uma ponte virtual (br0) que agrega a interface física enp3s0 e provê rede para máquinas virtuais:

Passos de Composição Declarativa:

1. Definir o dispositivo virtual da ponte (/etc/systemd/network/10-bridge.netdev):

[NetDev]
Name=br0
Kind=bridge

2. Acoplar a interface física à ponte (/etc/systemd/network/20-bind-fisica.network):

[Match]
Name=enp3s0

[Network]
Bridge=br0

3. Atribuir o endereço IP à interface da ponte (/etc/systemd/network/30-bridge-ip.network):

[Match]
Name=br0

[Network]
Address=10.0.0.10/24
Gateway=10.0.0.1
DNS=1.1.1.1

O systemd-networkd analisa as dependências entre as três unidades e executa as chamadas Netlink na ordem estrita: cria a interface br0, altera o estado da placa enp3s0 para modo promíscuo/escravo da ponte e atribui a Camada 3 ao nó lógico br0.


5. Arquitetura do systemd-resolved

O systemd-resolved é o daemon responsável pela resolução de nomes de domínio (DNS - Domain Name System), gerenciamento de sufixos de busca, validação de assinaturas DNSSEC, criptografia via DNS-over-TLS (DoT) e resolução local por multicast (mDNS e LLMNR).

5.1. O Problema do Arquivo /etc/resolv.conf Histórico

No modelo histórico do UNIX, a resolução de nomes dependia exclusivamente da biblioteca C da glibc (gethostbyname(), getaddrinfo()), que lia diretamente o arquivo estático /etc/resolv.conf.

Este modelo falha categoricamente em ambientes modernos:

  • Não possui suporte nativo a cache de consultas DNS em memória (todas as requisições geram tráfego de soquete UDP na porta 53 para a rede externa).
  • Não suporta resolução condicional baseada em interfaces (ex: direcionar consultas *.empresa.internal para o DNS da VPN corporativa enquanto envia todo o tráfego genérico para o DNS público).
  • Sofre de condições de corrida (race conditions) quando múltiplos processos (DHCP, VPNs, NetworkManager) tentam sobrescrever o arquivo /etc/resolv.conf simultaneamente.

6. O Stub Resolver Local (127.0.0.53) e os Modos de Integração

Para resolver a fragilidade do /etc/resolv.conf e prover caching transparente para qualquer aplicativo no espaço de usuário, o systemd-resolved implementa um Stub Resolver interno.

O daemon abre um soquete de escuta na interface de loopback local no endereço IP 127.0.0.53 e porta UDP/TCP 53.

┌─────────────────────────────────────────────────────────────────────────┐
│                           APLICAÇÃO (Navegador, cURL, Ping)             │
└────────────────────────────────────┬────────────────────────────────────┘
                                     │ 1. Consulta DNS: "wiki.empresa.local"
                                     ▼
┌─────────────────────────────────────────────────────────────────────────┐
│                 BIBLIOTECA GLIBC / NSSWITCH (/etc/nsswitch.conf)        │
│  - Redireciona a consulta para o endereço configurado em resolv.conf    │
└────────────────────────────────────┬────────────────────────────────────┘
                                     │ 2. Consulta enviada para 127.0.0.53:53
                                     ▼
┌─────────────────────────────────────────────────────────────────────────┐
│                     SYSTEMD-RESOLVED (127.0.0.53:53)                    │
│                                                                         │
│  [ Memória Cache RAM ] ──► Possui o registro? ──► Retorna ao app (0ms)  │
│           │ Não                                                         │
│           ▼                                                             │
│  [ Roteamento de Consultas por Interface (Routing Domain) ]             │
│  ├── VPN (tun0)   ──► Redireciona consultas *.empresa.local             │
│  └── Wi-Fi (wlan0)──► Redireciona consultas genéricas via DoT (Port 853)│
└─────────────────────────────────────────────────────────────────────────┘

6.1. A Tripla Estrutura do /etc/resolv.conf

Para garatrir retrocompatibilidade com aplicações antigas, o systemd-resolved provê três modos de integração gerenciados através de links simbólicos no diretório /etc/:

  1. Modo Stub Resolver Nativo (Recomendado):
    O arquivo /etc/resolv.conf é um symlink apontando para:
    /run/systemd/resolve/stub-resolv.conf
    Conteúdo: Declara exclusivamente nameserver 127.0.0.53. Todas as aplicações enviam consultas para o systemd-resolved, que gerencia o cache, validação DNSSEC e roteamento por interface.
  2. Modo Direto / Estático:
    O arquivo /etc/resolv.conf é um symlink apontando para:
    /run/systemd/resolve/resolv.conf
    Conteúdo: Lista diretamente os IPs dos servidores DNS reais aprendidos por todas as interfaces de rede (ex: nameserver 1.1.1.1), bypassando o stub local de 127.0.0.53, mas perdendo recursos de resolução por interface.
  3. Modo de Substituição Externa (Foreign):
    O arquivo /etc/resolv.conf é mantido como um arquivo de texto físico editável gerenciado por um aplicativo externo (como o NetworkManager tradicional ou um script de VPN). O systemd-resolved lê esse arquivo em modo passivo.

7. Roteamento de Domínios de Busca e Recursos Avançados

Uma das maiores inovações arquiteturais do systemd-resolved é o Roteamento de Consultas DNS por Domínio (Split DNS).

Quando um sistema possui múltiplas interfaces ativas (ex: uma placa Wi-Fi física wlan0 conectada à internet e um túnel VPN tun0 conectado à rede corporativa), o systemd-resolved constrói uma matriz de roteamento de nomes na memória:

# Configuração atrelada à interface VPN (tun0)
[Network]
DNS=10.200.0.1
Domains=~corp.empresa.com ~internal.local

O Prefixo Tilde (~) e a Matriz de Roteamento:

  • O caractere ~ instrui o systemd-resolved a tratar aquela string como um Domínio de Roteamento Exclusivo (Routing Domain).
  • Se a aplicação tentar resolver servidor.corp.empresa.com, o systemd-resolved consulta a matriz, identifica que o sufixo casa com o domínio ~corp.empresa.com atrelado à interface tun0 e envia a requisição UDP **estritamente para o DNS corporativo 10.200.0.1**.
  • Se a aplicação tentar resolver google.com, a consulta é roteada para a interface genérica wlan0 (DNS 1.1.1.1).
  • Isso previne o vamento de nomes corporativos privados (DNS Leakage) para a internet pública e evita falhas de resolução em ambientes multi-homed.

8. Segurança Avançada: DNSSEC e DNS-over-TLS (DoT)

O systemd-resolved incorpora nativamente mecanismos modernos de criptografia e validação de autenticidade de respostas de rede no arquivo de configuração /etc/systemd/resolved.conf:

[Resolve]
DNS=1.1.1.1#cloudflare-dns.com 8.8.8.8#dns.google
FallbackDNS=9.9.9.9
Domains=~.
DNSSEC=allow-downgrade
DNSOverTLS=yes
Cache=yes
MulticastDNS=resolve
LLMNR=no

Dissecação das Diretivas de Segurança:

  1. DNSOverTLS=yes (DoT): Força o systemd-resolved a criptografar todas as consultas DNS de saída utilizando o protocolo TLS através da porta TCP 853 (em vez da porta UDP 53 sem criptografia). Impede que provedores de internet ou atacantes na rede local (Man-in-the-Middle) monitorem ou alterem as consultas DNS do usuário.
  2. DNSSEC=allow-downgrade: Ativa a verificação de assinaturas criptográficas dos registros DNS retornados pelos servidores (garantindo que o IP retornado não foi forjado por um ataque de DNS Cache Poisoning). O modo allow-downgrade valida o DNSSEC se o domínio de destino suportar a extensão, permitindo acesso se a zona não for assinada. O modo DNSSEC=yes força validação estrita, bloqueando domínios sem assinatura válida.
  3. LLMNR=no e MulticastDNS=resolve: Controla a resolução de nomes na rede local sem servidor central. Desativar o LLMNR (Link-Local Multicast Name Resolution) é uma recomendação estrita de segurança em ambientes corporativos para mitigar ataques de envenenamento de rede por ferramentas como o Responder.

9. Ferramentas de Inspeção da CLI (networkctl e resolvectl)

O gerenciamento e o diagnóstico em tempo de execução dos subsistemas de rede e resolução de nomes não utilizam comandos legados, mas sim as ferramentas CLI dedicadas da suíte:

9.1. O Utilitário networkctl

Inspeciona o estado das interfaces de rede gerenciadas pelo systemd-networkd:

# Exibe a lista de interfaces e o estado do link de camada 1/2/3
networkctl list

# Exibe o relatório detalhado de uma interface específica
networkctl status enp3s0

Saída Típica do networkctl status enp3s0:

● 2: enp3s0
                     Type: ether
                    State: routable (configured)
             Online State: online
                  Driver: r8168
                Hardware: 00:11:22:33:44:55
             MTU / Speed: 1500 / 1 Gbps
                  Addresses: 192.168.1.50 (DHCPv4 via 192.168.1.1)
                         2001:db8:1::50
                  Gateway: 192.168.1.1 (TP-Link Technologies)
                      DNS: 127.0.0.53
                           1.1.1.1

9.2. O Utilitário resolvectl

Inspeciona as estatísticas do cache, testa a resolução de nomes e gerencia as configurações de DNS em tempo de execução do systemd-resolved:

# Exibe os servidores DNS e domínios atrelados a cada interface ativa
resolvectl status

# Executa uma consulta de teste exibindo validação DNSSEC e latência de resposta
resolvectl query wiki.empresa.local

# Limpa a memória cache do resolver local
resolvectl flush-caches

# Exibe as estatísticas de acerto/erro (Hit/Miss) do cache RAM
resolvectl statistics


10. Matriz Comparativa: Modelos de Rede e Resolução

Recurso / Propriedade Modelo Histórico (Scripts + resolv.conf) Modelo Moderno (systemd-networkd + resolved)
Mecanismo de Comunicação Invocação de binários iproute2 via subshell. Comunicação atômica direta via Netlink IPC Socket.
Sintaxe de Configuração Imperativa/Específica por distribuição. Declarativa Universal INI (.network, .netdev).
Resolução de Nomes Leitura síncrona simples do /etc/resolv.conf. Stub Resolver em 127.0.0.53 com cache dinâmico.
Criptografia DNS Não suportada (Requer daemons como stubby). DNS-over-TLS (DoT) nativo na porta 853.
VPN / Split-DNS Conflito constante sobre o /etc/resolv.conf. Roteamento por Domínio (~) nativo por interface.
Desempenho no Boot Lento (Depende de encadeamento de scripts). Instantâneo (Paralelizado e orientado a eventos udev).
Validação de Segurança Nenhuma. DNSSEC integrado com fallback configurável.