Todos os produtos
Search
Central de documentação

Alibaba Cloud Linux:Use vtoa to get the real client address after address translation

Última atualização: Jun 29, 2026

Em cenários de FullNAT, como Anti-DDoS Proxy e aceleração de CDN, o nó de encaminhamento substitui o IP e a porta de origem do cliente pelos seus próprios antes de passar o tráfego para o servidor backend. O vtoa é um módulo de kernel para Alibaba Cloud Linux 3 que recupera o IP e a porta originais do cliente a partir do TCP Option Address (TOA) incorporado no cabeçalho TCP. Sua aplicação obtém essas informações sem alterações na infraestrutura de rede, utilizando getsockopt (recomendado) ou getpeername.

Há suporte tanto para IPv4 quanto para IPv6.

Como funciona

  1. Uma solicitação do cliente chega ao nó de encaminhamento (por exemplo, um nó Anti-DDoS).

  2. O nó de encaminhamento executa o FullNAT, substituindo o IP e a porta de origem do cliente pelos seus próprios, e insere o endereço original em um campo TCP Option (TOA).

  3. O servidor backend recebe a conexão. O vtoa extrai os dados TOA do cabeçalho TCP no kernel.

  4. Sua aplicação chama getsockopt (recomendado) ou getpeername para recuperar o endereço original do cliente.

Casos de uso

  • Anti-DDoS Proxy: As solicitações do cliente passam por FullNAT no nó de encaminhamento Anti-DDoS. O Anti-DDoS insere o IP e a porta reais do cliente na TCP Option. O servidor de origem backend usa o vtoa para recuperar o IP real do cliente.

    image

  • Aceleração de CDN: Os nós de aceleração de CDN encaminham solicitações ao servidor de origem. Esse servidor utiliza o vtoa para recuperar o endereço real do cliente.

Sistemas compatíveis

O vtoa requer Alibaba Cloud Linux 3 com versão de kernel 5.10.134-15 ou posterior.

Execute uname -r para verificar a versão do kernel.

Aviso

O vtoa modifica o valor retornado pela chamada de sistema getpeername. Confirme se os pontos abaixo são aceitáveis antes de instalar:

  • Componentes de rede que modificam o getpeername via eBPF — como o Cilium — podem entrar em conflito com o vtoa e causar comportamento anormal.

  • Aplicações que dependem do getpeername podem ser afetadas.

Para evitar esses problemas, utilize o método getsockopt, que recupera o endereço original do cliente sem modificar o retorno do getpeername.

Instale o vtoa

Instale o vtoa com o yum:

sudo yum install vtoa -y

Após a instalação, o vtoa inicia imediatamente e fica configurado para iniciar automaticamente na inicialização. Geralmente, nenhuma configuração adicional é necessária.

Para desinstalar:

sudo yum remove vtoa -y

Após a desinstalação, o vtoa é desativado.

Gerencie o serviço vtoa

Embora o vtoa seja executado automaticamente após a instalação, você pode controlá-lo com o systemctl:

Ação

Comando

Iniciar

sudo systemctl start vtoa

Parar

sudo systemctl stop vtoa

Ativar início automático na inicialização

sudo systemctl enable vtoa

Desativar início automático na inicialização

sudo systemctl disable vtoa

Verificar status

systemctl status vtoa

Obtenha o endereço real do cliente

Com o vtoa em execução, use uma das seguintes chamadas de sistema para recuperar o endereço original do cliente. O campo caddr.sa_family é AF_INET para IPv4 e AF_INET6 para IPv6.

Use getsockopt (recomendado)

Importante

Este método requer a versão de kernel 5.10.134-17 ou posterior. Execute uname -r para verificar.

O vtoa registra uma opção de socket com valor optname igual a 1348. Chame getsockopt com IPPROTO_IP e este optname para recuperar diretamente o endereço original do cliente. Este método não modifica o valor retornado pelo getpeername, tornando-o seguro em ambientes com ferramentas de rede baseadas em eBPF.

struct sockaddr caddr;
int optlen = sizeof(caddr);
int optname = 1348;

getsockopt(fd, IPPROTO_IP, optname, &caddr, &optlen);
// caddr.sa_family can be AF_INET or AF_INET6, which correspond to IPv4 and IPv6 addresses.

Use getpeername

Importante

Este método é compatível com a versão de kernel 5.10.134-15 ou posterior. Ele pode ser descontinuado no futuro. Sempre que possível, use getsockopt.

Quando o vtoa está ativado, o getpeername retorna o endereço original do cliente em vez do endereço FullNAT. Nenhuma alteração no código da aplicação é necessária além de chamar o getpeername normalmente.

struct sockaddr caddr;
int caddr_len = sizeof(caddr);

getpeername(fd, &caddr, &caddr_len);
// caddr.sa_family can be AF_INET or AF_INET6, which correspond to IPv4 and IPv6 addresses.
// accept() can also be used to get the client address in a similar way.

Por que getsockopt é preferível: O getpeername substitui globalmente o endereço do par para todos os chamadores no socket. Isso pode quebrar componentes que esperam o endereço NAT, como certas ferramentas baseadas em eBPF, e pode ser descontinuado em uma versão futura do kernel. O getsockopt recupera o endereço original do cliente sem alterar o retorno do getpeername, tornando-o mais seguro em ambientes mistos.

Perguntas frequentes

Quais formatos de opção TCP o vtoa suporta?

O vtoa analisa as informações de endereço transportadas nas TCP Options. Se o formato não corresponder, o vtoa ignora silenciosamente a opção. Isso não afeta a aplicação e equivale ao vtoa estar desativado.

Dois formatos são suportados:

TOA (IPv4) — opcode 254

opsize = 8. Tanto ip quanto port estão em ordem de bytes de rede.

0                   1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |     opcode    |    opsize     |              port             |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                              ip                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

TOA_V6 (IPv6) — opcode 253

opsize = 20. Tanto ip quanto port estão em ordem de bytes de rede.

0                   1                   2                   3
    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |     opcode    |    opsize     |              port             |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   |                                                               |
   +                                                               +
   |                                                               |
   +                              ip                               +
   |                                                               |
   +                                                               +
   |                                                               |
   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Como uso o vtoa em ambientes de contêiner?

O vtoa não oferece suporte a isolamento no nível de contêiner. Instale o vtoa no host, não dentro de um contêiner. Uma vez instalado no host, ele é efetivo para todos os contêineres nesse nó (por exemplo, ao usar ACK com o runtime containerd).

O vtoa está instalado, mas ainda recebo o endereço FullNAT — como solucionar?

Verifique os itens abaixo nesta ordem:

  1. Versão do kernel: Execute uname -r e confirme se a versão é 5.10.134-15 ou posterior (ou 5.10.134-17 ou posterior se estiver usando getsockopt).

  2. Status do serviço: Execute systemctl status vtoa e confirme se o serviço está ativo (running).

  3. Formato TOA: Confirme se o seu nó de encaminhamento upstream (Anti-DDoS, CDN ou FullNAT personalizado) está inserindo um TOA com opcode 254 (IPv4) ou 253 (IPv6). Se o opcode ou formato não corresponder, o vtoa ignora silenciosamente a opção.

  4. Conflitos de eBPF: Se o Cilium ou outro componente baseado em eBPF estiver em execução no host, verifique se ele também faz hook no getpeername. Hooks conflitantes podem produzir resultados inesperados. Nesse caso, mude para o método getsockopt, que não modifica o valor de retorno do getpeername.