SSD Nodes Learn Hosting plans →
Guias Matt ConnorPor Matt Connor

Tailscale lento: como saber se usa DERP ou ligação direta

Veja se o Tailscale usa DERP ou ligação direta com dois comandos. Entenda o bloqueio de UDP e corrija NAT restrito em um VPS para ganhar velocidade.

Por que o Tailscale é lento: ligação retransmitida em vez de direta

O Tailscale fica lento quando a ligação é retransmitida através de um dos seus servidores DERP partilhados e aproxima-se da velocidade máxima da ligação quando a ligação é direta. Uma ligação direta transporta pacotes WireGuard cifrados diretamente de uma máquina para a outra, por isso funciona à velocidade suportada pelas duas ligações à Internet. Uma ligação retransmitida envia primeiro cada pacote através de uma terceira máquina, por isso fica sujeita à latência dessa máquina e à parte da largura de banda que lhe for atribuída. O impacto depende do relay. O Tailscale descreve os seus servidores DERP como "geralmente mais lentos do que as ligações diretas", enquanto um relay de peer que seja executado por si é "normalmente mais rápido do que o DERP" e, nos testes iniciais do Tailscale, atingiu um débito "próximo do de uma ligação direta". A própria página de desempenho do Tailscale resume a regra geral numa frase: "As ligações diretas resultam quase sempre em menor latência e maior débito."

Nada dentro da aplicação mostra a diferença. A cópia de ficheiros fica simplesmente lenta e a sessão SSH apresenta simplesmente latência. Por isso, o primeiro passo é descobrir que tipo de ligação já tem. Dois comandos respondem a essa questão em menos de um minuto; tudo o que se segue consiste em corrigir a causa. Vale a pena conhecer a parte da configuração antes de começar, porque o servidor de coordenação e o plano de dados WireGuard são sistemas separados e apenas o plano de dados transporta os seus bytes.

Os dois comandos que distinguem uma ligação direta de uma ligação retransmitida

Envie algum tráfego para o peer antes de medir qualquer coisa. O Tailscale cria um caminho conforme necessário. Por isso, um peer com o qual não comunicou hoje pode ainda não ter negociado um caminho, e o resultado lido pode estar desatualizado. Um ping ou um curl para o endereço tailnet do peer é suficiente.

tailscale status

A resposta aparece no fim da linha de cada peer.

100.113.160.82 device-a  tagged-devices linux   active; offers exit node; direct 203.0.113.9:41641
100.104.93.78  device-b  you@           android active; relay "tor"

direct seguido de um endereço e de uma porta significa que os pacotes estão a ser enviados diretamente para esse endereço. relay "tor" identifica um servidor DERP (designated encrypted relay for packets), que é uma das máquinas de retransmissão do Tailscale. Nesse caso, todos os pacotes para esse peer passam por esse servidor. Um terceiro valor, peer-relay, é explicado na secção seguinte.

tailscale ping device-b

Uma ligação saudável começa retransmitida e depois muda. Os primeiros pacotes passam pelo servidor DERP mais próximo enquanto as duas máquinas negoceiam. Depois, o caminho é alterado:

pong from device-b (100.113.160.82) via DERP(tor) in 51ms
pong from device-b (100.113.160.82) via DERP(tor) in 48ms
pong from device-b (100.113.160.82) via 203.0.113.9:41641 in 35ms

A execução termina nesse ponto porque --until-direct tem o valor predefinido true. Uma ligação que não consegue passar para uma ligação direta aparece assim e termina com uma frase, não com um pong:

pong from device-b (100.104.93.78) via DERP(tor) in 53ms
pong from device-b (100.104.93.78) via DERP(tor) in 60ms
direct connection not established

Essa última linha é o resultado. Significa que o Tailscale enviou todas as sondas previstas e nunca obteve um caminho direto. Para continuar a monitorizar um caminho retransmitido em vez de parar na primeira ligação direta, execute tailscale ping --until-direct=false -c 20 device-b e analise a variação da latência. Um caminho retransmitido normalmente apresenta valores mais altos e maior variação, porque combina dois caminhos de Internet através de uma máquina que não controla.

O que significa peer-relay no status do Tailscale?

Um peer relay é uma máquina na sua própria tailnet que retransmite o tráfego de outros membros quando não é possível estabelecer uma ligação direta. A máquina escuta numa porta UDP à sua escolha, e o daemon dá-lhe preferência em relação ao DERP. tailscale status marca uma ligação deste tipo peer-relay, e tailscale ping apresenta o endpoint do relay:

pong from device-b (100.97.143.93) via peer-relay(203.0.113.42:40000:vni:1) in 4ms
direct connection not established

Leia essa saída com atenção. A ligação continua a não ser direta, por isso a execução termina com direct connection not established. O que mudou foi a máquina que retransmite o tráfego. Uma VPS com um endereço IP público e uma franquia de largura de banda generosa é um relay muito melhor para o seu próprio tráfego do que um nó DERP partilhado. É por isso que esta opção é importante para quem aluga um servidor. Ative-a na máquina que tem o endpoint público acessível:

sudo tailscale set --relay-server-port=40000

Uma porta com o valor 0 escolhe uma porta livre aleatória, e uma string vazia desativa o servidor relay. Depois, dê aos dispositivos cliente permissão para a utilizar, com a capacidade tailscale.com/cap/relay no ficheiro de política da sua tailnet:

{
  "grants": [
    {
      "src": ["tag:us-east-vpc"],
      "dst": ["tag:us-east-relays"],
      "app": {
        "tailscale.com/cap/relay": []
      }
    }
  ]
}

Tanto o dispositivo relay como os dispositivos cliente precisam do Tailscale 1.86 ou posterior. Por isso, confirme a versão com tailscale version em cada dispositivo antes de perder uma hora a editar o ficheiro de política. Vale a pena memorizar a ordem das tentativas do daemon. Primeiro, tenta estabelecer uma ligação direta. Se falhar, procura um peer relay que possa utilizar. Se não existir nenhum, recorre ao DERP. O DERP nunca fica totalmente fora do processo, porque também é o canal através do qual as duas máquinas negoceiam inicialmente.

Causa 1: um firewall de saída que bloqueia UDP

A documentação do Tailscale indica duas razões para uma ligação permanecer em relay. A primeira é o UDP bloqueado. Consulte diretamente a máquina:

tailscale netcheck

O relatório está truncado aqui, e o campo superior é o que determina tudo:

Report:
  * UDP: true
  * IPv4: yes, 203.0.113.9:41641
  * IPv6: no
  * MappingVariesByDestIP: false
  * PortMapping:
  * Nearest DERP: Dallas

UDP: false é a indicação mais forte que obterá. Significa que a máquina não conseguiu enviar um pacote UDP para os servidores de sondagem do Tailscale. A própria referência da CLI do Tailscale indica que, nesse caso, "é improvável que o Tailscale consiga estabelecer ligações ponto a ponto". O tráfego passa então pelo DERP sobre a porta TCP 443. Esse fallback explica por que a máquina continua a parecer perfeitamente saudável: está ligada, está acessível e todos os bytes estão a ser encaminhados por relay. netcheck descreve a rede, e não uma ligação específica. Por isso, confirme o caminho que um peer está realmente a utilizar com tailscale status ou tailscale ping antes de alterar regras.

Há duas regras de saída documentadas. "Permitir que os dispositivos internos iniciem UDP de :41641 para *:*", que corresponde ao próprio tráfego WireGuard, e "Permitir que os dispositivos internos iniciem UDP para *:3478", que corresponde ao STUN (session traversal utilities for NAT), o protocolo que a máquina utiliza para descobrir o seu próprio endereço e porta públicos. Utilize wildcards nos destinos. O Tailscale adiciona servidores de relay ao longo do tempo, e uma lista de endereços escrita manualmente estará errada dentro de um ano.

Num servidor alugado, o culpado habitual é uma política de saída restritiva, herdada de uma imagem hardened ou aplicada pelo fornecedor a montante. Consulte primeiro a política de saída predefinida:

sudo ufw status verbose
sudo nft list ruleset

Default: deny (incoming), allow (outgoing) está correto e não é o seu problema. Uma política de saída predefinida de deny, com uma lista curta que permite TCP 443 e DNS, mantém exatamente um servidor num relay permanentemente, porque o caminho DERP sobre TCP 443 passa por essa abertura e o caminho direto não. O local efetivo dessas regras depende de o sistema utilizar iptables ou nftables internamente, e editar o firewall errado é uma forma comum de não alterar nada.

O lado de entrada também é importante, porque uma VPS tem um endereço IP público e pode, por isso, ser a metade mais acessível do par. Se o firewall aceitar UDP na porta em que tailscaled está à escuta, os peers atrás de routers domésticos problemáticos poderão alcançá-la sem técnicas adicionais. Descubra a porta que está efetivamente a ser utilizada:

sudo ss -lunp | grep tailscaled
sudo ufw allow 41641/udp

41641 é a porta estática predefinida. Numa tailnet com a definição randomizeClientPort ativada, os clientes escolhem uma porta aleatória. Nesse caso, utilize o número real apresentado pela saída de ss, e não o valor desta página. Consulte também o painel de controlo do fornecedor. A maioria dos hosts utiliza um firewall de rede separado do firewall dentro do servidor, e uma regra adicionada com ufw não tem qualquer efeito sobre ele.

Causa 2: NAT restritivo num ou em ambos os lados

A segunda causa documentada é o NAT restritivo. NAT (tradução de endereços de rede) é o que um router faz quando reescreve o seu endereço privado para o endereço público. Um router permissivo mantém a mesma porta pública para um determinado socket interno, independentemente do destino da ligação. Isto chama-se mapeamento independente do endpoint. Um NAT restritivo atribui uma porta pública diferente a cada destino. Por isso, o endereço que a máquina aprendeu através de um servidor STUN não é necessariamente o endereço que um peer conseguirá utilizar. O Tailscale apresenta esta situação em netcheck como MappingVariesByDestIP: true.

Um NAT restritivo é tolerável quando existe apenas num dos lados. Se o outro lado tiver um endpoint público estável, a máquina atrás do NAT restritivo ainda consegue iniciar a ligação e o caminho é estabelecido. Dois NAT restritivos em simultâneo causam a falha, porque nenhum dos lados consegue prever a porta em que o outro irá aparecer.

Numa VPS com um endereço IPv4 público, este campo normalmente deve apresentar false. Um endereço público nem sempre significa que não existe tradução. A AWS, por exemplo, documenta que o seu internet gateway executa um NAT um para um entre o endereço IPv4 público e o endereço privado de uma instância. Um mapeamento estático um para um mantém a mesma porta, independentemente do destino da ligação. Por isso, não é NAT restritivo e o campo continua a apresentar false. Se apresentar true num servidor alugado, existe algo na rede do fornecedor a atribuir uma porta diferente por destino. Nenhuma regra de firewall dentro da máquina irá alterar esse comportamento. As opções são colocar um relay de peers numa máquina que tenha um endpoint público direto ou mover a carga de trabalho. Este também é o caso em que anunciar as suas redes privadas a partir de um subnet router é útil, porque passa a precisar de um único caminho funcional para entrar na rede, em vez de um caminho funcional para cada dispositivo nela.

Por que um exit node faz o Tailscale parecer mais lento do que realmente é

Um exit node adiciona um segundo salto, e os utilizadores atribuem esse atraso ao túnel. Com um exit node selecionado, um pedido sai do seu portátil, atravessa o túnel até ao VPS, sai do VPS para a Internet pública e a resposta faz o caminho inverso. Mesmo uma ligação perfeitamente direta a esse VPS não pode tornar o percurso total mais rápido do que a ligação ascendente do próprio VPS. A distância adicional também aparece no carregamento de cada página.

Meça as duas partes separadamente. Desative o exit node e teste apenas o túnel contra o endereço tailnet do VPS:

sudo tailscale set --exit-node=
sudo apt install -y iperf3
iperf3 -s

Execute iperf3 -c 100.113.160.82 no cliente contra esse endereço tailnet. Esse valor corresponde ao seu túnel. Agora volte a ativar o exit node com sudo tailscale set --exit-node=100.113.160.82 e execute um teste de velocidade normal para a Internet pública. Esse valor corresponde ao túnel mais a ligação ascendente do VPS. Se o primeiro valor for bom e o segundo for mau, o Tailscale não é o problema. Nesse caso, deve verificar a própria rede e o dimensionamento do exit node. tailscale exit-node list mostra os exit nodes disponíveis quando não tiver a certeza de qual selecionou.

A CPU é a outra parte do limite de desempenho de um exit node. As recomendações do Tailscale dão preferência a uma geração recente de CPU com uma velocidade de relógio mais elevada, em vez de uma maior quantidade de cores. Por isso, um plano com mais vCPUs não é automaticamente mais rápido neste caso. Num host partilhado sobrecarregado, a CPU prometida pode não ser a CPU que recebe. O steal time causado por um vizinho ruidoso aparece como um débito variável ao longo do dia, sem qualquer alteração do seu lado.

O único parâmetro de ajuste: rx-udp-gro-forwarding

A documentação do Tailscale indica uma única definição do Linux, aplicável a máquinas que encaminham tráfego, ou seja, exit nodes e subnet routers. Um cliente comum não obtém benefícios. É necessário usar Tailscale 1.54 ou posterior e um kernel Linux 6.2 ou posterior. Confirme ambos antes de alterar qualquer definição:

tailscale version
uname -r

Com esses requisitos cumpridos, ative o encaminhamento UDP GRO (generic receive offload) na interface ligada à Internet:

NETDEV=$(ip -o route get 8.8.8.8 | cut -f 5 -d " ")
sudo ethtool -K $NETDEV rx-udp-gro-forwarding on rx-gro-list off

Confirme se a alteração foi aplicada:

ethtool -k $NETDEV | grep -E 'rx-udp-gro-forwarding|rx-gro-list'

Deverá ver rx-udp-gro-forwarding: on e rx-gro-list: off. Isto ajuda porque o tráfego do Tailscale usa UDP. Ao permitir que o kernel mantenha pequenos pacotes UDP agregados ao longo do caminho de encaminhamento, o daemon processa menos segmentos maiores para o mesmo número de bytes. ethtool -K não sobrevive a um reboot, por isso deve torná-lo persistente. Num sistema que usa networkd-dispatcher:

printf '#!/bin/sh\n\nethtool -K %s rx-udp-gro-forwarding on rx-gro-list off \n' "$(ip -o route get 8.8.8.8 | cut -f 5 -d " ")" | sudo tee /etc/networkd-dispatcher/routable.d/50-tailscale
sudo chmod 755 /etc/networkd-dispatcher/routable.d/50-tailscale

Execute o script manualmente uma vez e confirme que o código de saída é 0. Um nó de encaminhamento também precisa de ter o encaminhamento IP ativado. Trata-se de uma definição separada e de uma falha diferente:

echo 'net.ipv4.ip_forward = 1' | sudo tee -a /etc/sysctl.d/99-tailscale.conf
echo 'net.ipv6.conf.all.forwarding = 1' | sudo tee -a /etc/sysctl.d/99-tailscale.conf
sudo sysctl -p /etc/sysctl.d/99-tailscale.conf

Qual é o MTU usado pela sua interface tailscale0?

Não faça estimativas. Leia o valor diretamente na máquina:

ip link show tailscale0

O valor de mtu nessa saída é o que o túnel realmente usa. Ele é inferior aos 1500 informados pela sua interface Ethernet. Isso é intencional, não um erro. Cada pacote enviado dentro do túnel é encapsulado: um cabeçalho IP externo de 20 bytes para IPv4 ou 40 bytes para IPv6, um cabeçalho UDP de 8 bytes e o enquadramento do WireGuard com uma tag de autenticação de 32 bytes. Tudo isso precisa caber no tamanho máximo que o caminho real consegue transportar. O Tailscale escolhe então um valor suficientemente baixo para funcionar em ligações que transportam menos de um pacote completo de 1500 bytes, incluindo ligações PPPoE, algumas redes móveis e túneis IPv6.

O sintoma de um problema de MTU é específico. Não o diagnostique apenas com base na lentidão. O SSH responde, ping funciona e, depois, transferências grandes ou páginas HTTPS extensas ficam totalmente bloqueadas, em vez de apenas lentas. Esse padrão indica que pacotes demasiado grandes estão a ser descartados algures, sem que uma mensagem ICMP consiga chegar ao remetente. Aumentar o MTU de tailscale0 para um valor próximo de 1500 piora o problema, porque os pacotes que já não cabem ficam ainda maiores. A correção é encontrar o MTU funcional do caminho por bisseção e limitar o MSS do TCP no router que encaminha o tráfego. O tipo de ligação não altera este comportamento: um caminho relay e um caminho direto usam o mesmo MTU de interface.

FAQ

Como sei se a minha ligação Tailscale é direta ou retransmitida?

Execute tailscale status e leia o fim da linha do peer. direct 203.0.113.9:41641 indica uma ligação direta, relay "tor" significa que cada pacote passa por esse servidor DERP e peer-relay significa que os pacotes passam por uma máquina na sua própria tailnet. Para obter uma segunda confirmação, execute tailscale ping <peer>: um caminho saudável começa no DERP e depois apresenta um pong com um endereço e uma porta simples, enquanto um caminho retransmitido apresenta pongs DERP até terminar com direct connection not established. Envie primeiro algum tráfego para o peer, porque o Tailscale só cria um caminho quando necessário.

Porque é que o meu VPS nunca obtém uma ligação direta?

Execute tailscale netcheck no VPS. Se apresentar UDP: false, o UDP de saída não está a sair, normalmente devido a uma firewall de saída, e o Tailscale indica que uma ligação ponto a ponto é então improvável. Confirme com tailscale status ou tailscale ping que o peer está no DERP, que funciona através de TCP 443 e explica por que motivo a máquina continua a parecer ligada. Permita UDP de saída da porta 41641 para qualquer destino e UDP de saída para qualquer destino na porta 3478. Verifique a firewall de rede do fornecedor e a firewall dentro do servidor, porque são controlos separados e uma regra ufw não afeta a firewall do fornecedor.

Uma ligação Tailscale retransmitida é menos segura do que uma ligação direta?

Não. Um servidor DERP encaminha pacotes WireGuard que não consegue desencriptar, porque as chaves de encriptação são geradas nos seus dispositivos e nunca os abandonam. O custo de uma retransmissão é latência e débito, não confidencialidade. O que o servidor de coordenação controla é quais dispositivos ficam a conhecer-se, e a separação entre material de chaves e metadados de ligação merece ser compreendida antes de decidir quanto dessa infraestrutura quer alojar por conta própria.

A definição rx-udp-gro-forwarding ajuda todas as máquinas?

Não. Está documentada para máquinas Linux que encaminham tráfego para outras, o que inclui exit nodes e routers de sub-rede. Um portátil ou servidor que comunica apenas com os seus próprios peers não obtém qualquer benefício. Também requer Tailscale 1.54 ou posterior e Linux kernel 6.2 ou posterior. Por isso, verifique primeiro tailscale version e uname -r e lembre-se de que ethtool -K é reposta após um reboot, exceto se a tornar persistente.

O Tailscale é mais lento do que o WireGuard simples?

Ambos usam WireGuard para encriptar o tráfego. O Tailscale acrescenta a configuração da ligação que o WireGuard simples deixa a seu cargo, e é essa configuração que, por vezes, coloca a ligação numa retransmissão. O WireGuard simples não tem uma retransmissão: liga diretamente ou falha completamente. Compare, portanto, situações equivalentes e faça o benchmark do Tailscale apenas quando tailscale status indicar direct. Se quiser a versão configurada manualmente para comparação, um servidor WireGuard que configure por conta própria requer cerca de quarenta linhas de configuração, e a compensação envolvida é explicada em a comparação das duas abordagens.