Como o NAT decide quais conexões são de entrada e quais são de saída?


7

Estou criando um aplicativo P2P que precisa acessar nós atrás de um NAT. Esse NAT não permite conexões de entrada; portanto, os nós fora da rede não podem alcançar os nós atrás do NAT.

Minha solução para esse problema é que o nó atrás do NAT alcançaria o nó externo, e o nó externo, quando o tempo estiver pronto, se conectaria ao nó que está dentro do NAT usando essa conexão TCP pré-estabelecida. Como essa conexão seria estabelecida pelo nó dentro do NAT, isso não seria bloqueado pelo NAT.

Aqui está a minha pergunta. Não sei quais interpretações sublinhadas estão corretas ou se ambas estão erradas.

Interpretação # 1

Não é um conceito de uma conexão TCP, efetivamente um tubo, e quando um nó dentro do NAT faz uma solicitação para qualquer coisa no mundo exterior, que o tubo abre, a resposta é colocar nele, e o tubo se fecha para sempre.

Resultado: o NAT não permitirá nenhuma conexão TCP adicional ao cliente a partir do nó externo após o fechamento do tubo.

Interpretação # 2

Não existe uma conexão TCP, mas uma transmissão TCP. Como uma conexão TCP é definida como a local ip:port, e a remote ip:port, depois que um nó atrás do NAT chama um nó de fora, o nó de fora pode retornar usando a mesma porta da qual o cliente fez a solicitação e que "contaria" como o mesmo TCP conexão, não uma chamada não solicitada pelo NAT.

Resultado: o NAT efetivamente adivinha se essa conexão foi uma resposta ao que o nó dentro do NAT solicitou, observando o registro histórico. Como o nó atrás do NAT fez a primeira chamada, o nó externo pode retornar usando a mesma porta do cliente e funcionaria.

Meu modelo mental estava mais próximo do nº 1, mas quando inspecionei as conexões com o Wireshark, elas apareceram como conexões TCP separadas ou pelo menos como entidades separadas.

É mais perto de # 1, ou # 2, ou estou irremediavelmente confuso?


Você pode querer olhar para cima STUN e trabalhos relacionados: en.wikipedia.org/wiki/STUN
pjc50

5
Eu recomendo fortemente que você implemente primeiro uma versão IPv6 do seu aplicativo para que você não precise lidar com toda a complexidade do NAT na primeira versão. Depois de ter uma versão funcional no IPv6, comece a pensar em como fazê-lo funcionar no IPv4.
kasperd

Respostas:


9

O TCP é um protocolo orientado a conexão e só pode se comunicar por meio de conexões.

Antes de começar a programar usando o TCP, seria útil entender primeiro como o TCP funciona e você deve começar com o RFC 793, Transmission Control Protocol , que é a definição do TCP.

O RFC explica soquetes e conexões:

Multiplexação:

Para permitir que muitos processos em um único host usem os recursos de comunicação TCP simultaneamente, o TCP fornece um conjunto de endereços ou portas em cada host. Concatenado com os endereços de rede e host da camada de comunicação da Internet, isso forma um soquete. Um par de soquetes identifica exclusivamente cada conexão. Ou seja, um soquete pode ser usado simultaneamente em várias conexões.

A ligação de portas a processos é tratada de forma independente por cada host. No entanto, é útil anexar processos usados ​​com freqüência (por exemplo, um "logger" ou serviço de compartilhamento de tempo) a soquetes fixos que são divulgados ao público. Esses serviços podem ser acessados ​​através dos endereços conhecidos. Estabelecer e aprender os endereços de porta de outros processos pode envolver mecanismos mais dinâmicos.

Conexões:

Os mecanismos de confiabilidade e controle de fluxo descritos acima requerem que os TCPs inicializem e mantenham determinadas informações de status para cada fluxo de dados. A combinação dessas informações, incluindo soquetes, números de sequência e tamanhos de janelas, é chamada de conexão. Cada conexão é especificada exclusivamente por um par de soquetes, identificando seus dois lados.

Quando dois processos desejam se comunicar, seus TCPs devem primeiro estabelecer uma conexão (inicializar as informações de status de cada lado). Quando a comunicação é concluída, a conexão é encerrada ou fechada para liberar os recursos para outros usos.

Como as conexões devem ser estabelecidas entre hosts não confiáveis ​​e através do sistema de comunicação da Internet não confiável, um mecanismo de handshake com números de sequência baseados em relógio é usado para evitar a inicialização incorreta das conexões.

No que diz respeito ao ponto TCP externo, ele está se conectando ao endereço externo do dispositivo NAT, mesmo que esse dispositivo esteja encaminhando para o outro ponto TCP interno, com base na conexão iniciada pelo dispositivo interno.

Você também pode estudar o RFC 5382, Requisitos comportamentais do NAT para TCP .


7

Uma conexão TCP é considerada "em vigor" desde que os processos do software em cada extremidade mantenham o soquete aberto.

Quando os processos em uma ou ambas as extremidades fecham o soquete (normalmente ou a conexão é interrompida por algum motivo), isso se traduz, no fio, em um pacote TCP com o sinalizador FIN ou RST definido.

A implementação do NAT no roteador NAT procura os sinalizadores FIN e RST e, quando vê um pacote com esses sinalizadores, "fecha o buraco". Após esse ponto, o cliente precisa iniciar uma nova conexão para "abrir um novo furo".

Para resumir, desde que seu cliente e servidor mantenham seus soquetes abertos, a associação NAT permanece ativa.


4

Quando escrevo o "habitual" aqui, estou pensando no seu roteador WLAN-NAT de consumidor médio com uma configuração sã ou em alguma rede Linux simples com configurações padrão. Como sempre, isso pode ser feito o mais complexo ou complicado possível. Como a pergunta é muito básica, isso parece fazer mais sentido para mim, em vez de ir direto para as soluções NAT de nível empresarial mais complicadas.

Você já aceitou uma resposta, mas deixe-me tentar abordar diretamente a pergunta que você fez:

Como o NAT decide quais conexões são de entrada e quais são de saída?

A base da decisão (para qualquer decisão em um roteador) é um conjunto de regras de alguma forma ou forma. Nesse caso, para cada uma das interfaces envolvidas (ou seja, a interface LAN interna versus a interface WAN / uplink externa), o administrador implementará regras. Essas regras são bem diferentes, ou seja, as regras para uma interface LAN parecem muito diferentes das de uma interface WAN.

Saber de onde um pacote vem e para onde vai é o pão com manteiga do que um roteador faz.

Deixe-me começar com um

Exemplo

A página NAT da Wikipedia possui muito texto sobre esse assunto, mas um caso simples (uma LAN simples da empresa versus um único uplink DSL) é o que acontece:

  1. O PC cliente tenta iniciar uma conexão HTTP com um servidor baseado na Internet, por exemplo, 198.51.100.20. O próprio PC possui um endereço não roteado como 192.0.2.2. O roteador DSL barato tem duas interfaces, uma interna (192.0.2.1) e uma externa (203.0.113.10, muito provavelmente mudando com freqüência e fornecidas por algum protocolo de link local pelo provedor DLS). Portanto, o PC envia um pacote SYN para 198.51.100.20:80 através de seu gateway padrão, que é 192.0.2.1.
  2. O roteador pega o pacote na interface 192.0.2.1, como também faria se não houvesse NAT envolvido. Ele foi configurado para executar NAT nesta interface, portanto, segue as seguintes ações:
    • Invente um novo número de porta, que não está sendo usado até o momento. Por exemplo 12345.
    • Altere o endereço "remetente" no cabeçalho IP para 203.0.113.10.
    • Lembre-se do número da porta remetente original no cabeçalho TCP (fornecido pelo PC), vamos chamá-lo de 4321.
    • Altere o cabeçalho TCP para conter o número da porta do remetente 12345.
    • Adicione uma entrada (12345; 192.0.2.2; 4321) em sua tabela de conversão de NAT.
    • Envie o pacote no seu caminho alegre para seu próprio uplink / gateway.
  3. 198.51.100.20 eventualmente recebe o pacote, percebe que é um SYN ("estabelecer nova conexão") e envia uma mensagem SYN-ACK de volta ao remetente. Do seu ponto de vista, este é o endereço IP 203.0.113.10, com a porta de destino TCP 12345.
  4. O roteador recebe esse pacote em sua interface WAN. A interface WAN foi configurada para resolver endereços NATted como este. O roteador então ...
    • ... verifica sua tabela de tradução NAT, encontra a entrada ...
    • ... modifica o pacote para um destino 192.0.2.2 ...
    • ... corrige a porta de destino TCP de volta para 4321 ...
    • ... e envia pelo caminho alegre (na interface da LAN).
  5. O PC recebe o pacote e não vê nada sobre o procedimento NAT. Os olhares de pacotes apenas como se 198.51.100.20 tinha enviado, como se o roteador NAT não estava lá em tudo.

Em nenhum momento o tópico de uma "conexão" aparece. O roteador NAT (em sua forma mais simples) não precisa se preocupar com o conteúdo das mensagens. Ele se preocupa com os endereços IP e as portas do remetente e do receptor, mas nada mais. (Concedido: isso provavelmente está ignorando todos os tipos de problemas relacionados à segurança e desempenho; mas esse é o princípio muito básico, como o que está em questão nesta questão.)

Então, como o roteador sabe?

O roteador não precisa saber sobre "conexões". De fato, procedimentos semelhantes, como os descritos para o TCP, existem para o protocolo UDP sem conexão (perfuração de furo UDP) ou podem realmente ser implementados para qualquer protocolo que tenha algo como números de porta na camada de transporte.

A razão pela qual o roteador precisa conhecer o protocolo de nível de transporte (TCP, UDP, ...) em relação ao NAT é principalmente porque as próprias portas não fazem parte do IP; e ports são o que torna o "hack" que (esse tipo de) NAT é, facilmente possível.

Então, para sua pergunta:

Como o NAT decide quais conexões são de entrada e quais são de saída?

As conexões de saída são, por definição, aquelas que começam com um pacote SYN (ou um soco UDP inicial no caso de UDP) que aparece na interface da LAN. Chamá-los de "conexão" no caso do NAT é um pouco demais; eles acabam simplesmente como uma entrada temporária em uma tabela de conversão de NAT (mais as adições de segurança / desempenho que o roteador NAT individual também pode empregar).

As conexões de entrada não existem no cenário que usei na resposta até o momento. É claro que existem variantes do NAT que fazem isso; por exemplo, você pode identificar estaticamente uma porta na interface WAN do roteador com um IP: PORT específico na interface da LAN, o que possibilita executar um servidor dentro da sua LAN NAT. Isso também é frequentemente suportado por roteadores DSL / WLAN baratos para consumidores. E com roteadores "reais", você obviamente pode configurá-los da forma que desejar.

Pacotes IP de entrada / saída adicionais não são diferentes dos dados no exemplo. Depois que o handshake SYN inicial for concluído e o roteador tiver a entrada em sua tabela de tradução, ele passará (com a mesma tradução conforme explicada no exemplo) todos os pacotes adicionais nas duas direções.

Se, no contexto de uma conexão TCP assim estabelecida, o servidor deseja enviar dados ao cliente (o que é perfeitamente possível - o TCP é bidirecional), esses são apenas mais pacotes IP, no que diz respeito ao roteador NAT. Realmente não se importará muito com o conteúdo desses pacotes (isto é, se eles contêm determinadas cargas úteis ou são apenas pacotes de "gerenciamento" do TCP ou o que for).

Em nenhum momento o roteador "fecha o tubo" como você o coloca. Obviamente, o roteador terá alguma noção de quando pode limpar a entrada da tabela de conversão (provavelmente quando perceber um handshake FIN que encerra a conexão, ou por algum tempo limite ou algum estado de erro), mas do início ao fim é um caso contínuo.


11
Por favor, use endereços IP do RFC5737, definidos especificamente para fins de documentação, em vez de "seqüestrar" endereços válidos, especialmente do Google.
Patrick Mevzek 12/0318

11
As conexões são bidirecionais, portanto, são de entrada e de saída. É o início da conexão que seria de entrada ou saída.
Ron Maupin

@ RonMaupin, sim, explico isso nos últimos parágrafos, especialmente no penúltimo. Isso corresponde ao que você quis dizer, ou eu escrevi de uma maneira obscura?
AnoE

@PatrickMevzek, aprenda algo novo todos os dias. Concluído + obrigado!
31 de

Obrigado. Concordo que minha pergunta talvez seja mais especificamente formulada como iniciação da conexão, não como uma questão relativa à bidirecionalidade geral. Eu já implementei o mapeamento de portas e os roteadores que atuam normalmente funcionarão. Eu fiz essa pergunta para descobrir o que pode ser feito para roteadores que não colaboram, como em cafés, locais públicos e assim por diante. Esta é uma ótima resposta que aborda a situação geral, porém, muito apreciada.
314 Dean M.Mar
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.