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?
Respostas:
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:
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 .
fonte
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.
fonte
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:
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:
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:
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.
fonte