Loopback para encaminhado Endereço IP público da rede local - Hairpin NAT

43

This is a Canonical Question about Hairpin NAT (Loopback NAT).

A forma genérica desta pergunta é:

Temos uma rede com clientes, um servidor e um roteador NAT. Há encaminhamento de porta no roteador para o servidor, portanto, alguns dos seus serviços estão disponíveis externamente. Temos DNS apontando para o IP externo. Os clientes da rede local não conseguem se conectar, mas o trabalho externo.

  • Por que isso falha?
  • Como posso criar um esquema de nomenclatura unificado (nomes DNS que funcionam local e externamente)?

Esta pergunta tem respostas mescladas de várias outras perguntas. Eles originalmente referenciavam FreeBSD, D-Link, Microtik e outros equipamentos. Eles estão todos tentando resolver o mesmo problema no entanto.

    
por adopilot 18.08.2009 / 17:16

11 respostas

14

O que você está procurando é chamado de "hairpin NAT". As solicitações da interface interna para um endereço IP atribuído à interface externa devem ser NAT, como se tivessem vindo da interface externa.

Eu não tenho nenhuma familiaridade com o FreeBSD, mas lendo o manual "pf" para o OpenBSD ( link ) as soluções propostas de DNS split-horizon, usando uma rede DMZ, ou proxy TCP, me levam a acreditar que "pf" não suporta NAT hairpin.

Eu examinaria a rota do DNS de horizonte dividido e não usaria endereços IP em URLs internamente, mas, em vez disso, usando nomes.

    
por 18.08.2009 / 17:30
46

Desde que esta foi elevada a questão canônica sobre o NAT hairpin, eu pensei que provavelmente deveria ter uma resposta que fosse mais válida do que a atualmente aceita, que (apesar de excelente) se relaciona especificamente ao FreeBSD.

Esta questão aplica-se a serviços fornecidos por servidores em redes IPv4 endereçadas por RFC1918, que são disponibilizadas para usuários externos através da introdução do NAT de destino (DNAT) no gateway. Os usuários internos tentam acessar esses serviços por meio do endereço externo. Seu pacote sai do cliente para o dispositivo de gateway, que reescreve o endereço de destino e imediatamente o injeta de volta na rede interna. É este desvio que o pacote faz no gateway que dá origem ao nome hairpin NAT , por analogia com o curva fechada .

O problema surge quando o dispositivo de gateway reescreve o endereço de destino, mas não o endereço de origem. O servidor recebe um pacote com um endereço de destino interno (próprio) e um endereço de origem interno (o do cliente); sabe que pode responder diretamente a tal endereço, assim o faz. Como essa resposta é direta, ela não passa pelo gateway, que, portanto, nunca tem a chance de balancear o efeito do NAT de destino de entrada no pacote inicial, reescrevendo o endereço de origem do pacote de retorno.

O cliente envia um pacote para um endereço IP externo , mas recebe uma resposta de um endereço IP interno . Não faz ideia de que os dois pacotes fazem parte da mesma conversa, por isso não acontece nenhuma conversa.

A solução é que para pacotes que requerem tal NAT de destino, e que atingem o gateway da rede interna , também executam NAT de origem (SNAT) no pacote de entrada, geralmente reescrevendo a fonte endereço para ser aquele do gateway. O servidor pensa que o cliente é o próprio gateway e responde diretamente a ele. Isso, por sua vez, dá ao gateway uma chance de balancear os efeitos de ambos DNAT e SNAT no pacote de entrada reescrevendo os endereços de origem e de destino no pacote de retorno.

O cliente acha que está falando com um servidor externo. O servidor acha que está falando com o dispositivo de gateway. Todas as partes estão felizes. Um diagrama pode ser útil neste ponto:

Alguns dispositivos de gateway do consumidor são brilhantes o suficiente para reconhecer os pacotes para os quais a segunda etapa do NAT é necessária, e provavelmente funcionarão sem problemas em um cenário de NAT suspenso. Outros não são, e não o fazem, e é improvável que possam ser feitos para o trabalho. Uma discussão sobre quais dispositivos de classe de consumidor são que estão fora do tópico para falha do servidor.

Dispositivos de rede adequados geralmente podem ser instruídos a trabalhar, mas - porque não estão no negócio de adivinhar seus administradores - eles precisam ser instruídos a fazê-lo. O Linux usa iptables para fazer o DNAT assim:

iptables -t nat -A PREROUTING  -p tcp --dport 80 -j DNAT --to-destination 192.168.3.11

que ativará o DNAT simples para a porta HTTP, para um servidor interno em 192.168.3.11 . Mas, para ativar o NAT hairpin, também seria necessário uma regra como:

iptables -t nat -A POSTROUTING -d 192.168.3.11 -p tcp --dport 80 -j MASQUERADE

Observe que essas regras precisam estar no lugar certo nas cadeias relevantes para funcionar corretamente e, dependendo das configurações na cadeia filter , regras adicionais podem ser necessárias para permitir o fluxo do tráfego NATted. Todas essas discussões estão fora do escopo desta resposta.

Mas, como outros já disseram, habilitar corretamente o NAT não é a melhor maneira de lidar com o problema. O melhor é DNS split-horizon , em que sua organização exibe respostas diferentes para a pesquisa original, dependendo de onde o cliente solicitante está, seja com servidores físicos diferentes para usuários internos e externos ou configurando o Servidor DNS para responder de forma diferente de acordo com o endereço do cliente solicitante.

    
por 27.11.2013 / 13:20
8

O problema aqui é que o seu roteador não atende o endereço do seu cliente interno. Assim, o handshake TCP falha.

Vamos presumir os seguintes IPs

  • Cliente: 192.168.1.3
  • Servidor: 192.168.1.2
  • Roteador interno: 192.168.1
  • Roteador externo: 123.123.123.1

Aqui está o que está acontecendo:

  1. O cliente (192.168.1.3) envia o TCP-SYN para o seu IP externo, porta 80 (123.123.123.1:80)
  2. O roteador vê a regra de encaminhamento de porta e encaminha o pacote para o servidor (192.168.1.2:80) sem alterar o IP de origem (192.168.1.3)
  3. O cliente aguarda um SYN-ACK do IP externo
  4. O servidor envia sua resposta de volta ao cliente diretamente, porque está na mesma sub-rede. Não envia o pacote ao roteador, que inverteria o NAT.
  5. O cliente recebe um SYN-ACK de 192.168.1.2 em vez de 123.123.123.1. E descarta isso.
  6. O cliente ainda espera por um SYN-ACK de 123.123.123.1 e expira.
por 10.10.2009 / 13:32
4

Por que não usar o dns split horizon em vez de codificar endereços IP em todos os lugares? Você teria ext.seudominio apontando para 217.x.x.x do lado de fora e 192.x.x.x para dentro.

    
por 20.08.2009 / 10:42
2

Se é um roteador D-Link original (ou seja, não Rev. D / Firmware versão 1.00VG da Virgin Media), você deve ser capaz de ajustar as configurações para contornar isso. (No entanto, eu concordo com a sugestão do cartaz anterior de DD-WRT por muitas outras razões!)

  1. Faça login na interface da web do roteador
  2. Clique na guia Avançado na parte superior
  3. Clique na guia Configurações de firewall à esquerda
  4. Clique no botão de opção Independente do ponto final em Filtragem do ponto final TCP , conforme mostrado na captura de ecrã abaixo (ou consulte o emulador de roteador no site da D-Link)
  5. Salvar alterações; você está feito

Esta captura de tela é do modelo Rev. C; o seu pode ser um pouco diferente.

    
por 11.03.2012 / 03:37
2

Respondeu uma pergunta semelhante recentemente: O NAT estático da Cisco não está funcionando no lado da LAN e acabou de perceber que essa é uma Questão Canônica. Então, permita-me resumir a solução aqui.

Primeiro de tudo: esqueça o NAT (se puder) - a questão não é nada sobre configurar o NAT. Trata-se de acessar um servidor colocado atrás do NAT da Internet e da LAN. Empregar duas zonas DNS é uma alternativa viável, mas nem sempre a solução. Mas a solução existe e é incrivelmente simples (embora não seja perfeita, provavelmente):

(1) no servidor: adicione o endereço IP público como um endereço IP secundário na interface de rede do servidor com a máscara 255.255.255.255 (o serviço da web ou o que você quiser no servidor também deve ouvir este endereço IP); Todos os sistemas operacionais modernos permitirão que você faça isso (ou uma interface de loopback com o endereço IP público atribuído a ele pode ser usada em vez de adicionar um IP secundário à interface primária).

(2) nos hosts da LAN: adicione uma rota de host para o endereço IP público, por exemplo, para hosts Windows, use o seguinte comando: route -p add 203.0.113.130 mask 255.255.255.255 192.168.1.11 (você também pode usar a opção "rota estática" do DHCP para distribuir a rota). Ou, se houver (a) switch (es) / roteador (es) L3 entre os clientes e o roteador voltado para a Internet, configure a rota do host nessa (s) chave (s) intermediária (s) / roteador (es), não nos clientes.

Para aqueles que se preocupam com o handshake de três vias TCP: ele funcionará bem na configuração proposta.

Por favor, forneça feedback (pelo menos, voto).

    
por 03.11.2015 / 12:14
1

Vou responder às minhas perguntas apenas para ampliar horizontes para pessoas com problemas semelhantes.

Entrei em contato com meu provedor e solicitei que ele resolvesse meus problemas. O que eles me ofereceram é outro endereço IP público apenas para servidor, Agora eu tenho tráfego local no lado WAN do FreeBSD e fizemos canais específicos para taxa de transferência mais rápida entre o tráfego local e o IP público do servidor

    
por 20.08.2009 / 10:37
1

De um ponto de vista técnico, a melhor solução para este problema é ativar o IPv6 na sua rede. Quando o IPv6 está ativado, você precisa criar um registro AAAA para seu domínio. Mantenha o registro A existente apontando para o IPv4 externo do roteador . Crie um registro AAAA apontando para o endereço IPv4 do servidor .

O IPv6 tem endereços suficientes para evitar o NAT, portanto, você não precisará de NAT de gancho para o IPv6. E uma vez que você tenha ativado o IPv6 e criado os registros AAAA, qualquer cliente que suporte o RFC 8305 experimentará o IPv6 antes do IPv4. Isso significa que você não precisa de NAT para IPV, porque os clientes não o usarão.

Você ainda precisará da sua NAT IPv4 existente para conexões de saída e encaminhamento de porta para conexões de entrada até que a maior parte do mundo também tenha ativado o IPv6.

É mais rápido também.

Usar o IPv6 proporcionará um desempenho melhor do que o NAT suspenso.

Com o hairpin NAT, seu cliente enviará um pacote através de um switch para o roteador, o roteador realizará duas rodadas de tradução e, finalmente, enviará o pacote através do switch para o servidor. Os pacotes do servidor para o cliente percorrerão todo o caminho ao contrário.

Com o IPv6, você evita o NAT, em vez disso, os pacotes são enviados diretamente por meio do switch entre o cliente e o servidor. Isso significa que, em uma viagem de ida e volta, você reduz o número de passes através do comutador de 4 para 2 e evita duas viagens pelo roteador e pelas 4 conversões que o roteador teria realizado. Isso se traduz em melhor desempenho.

Isso é verdade mesmo se você usar um switch embutido na mesma caixa do roteador.

E se o ISP não tiver IPv6?

Se você estiver usando um ISP que não suporta IPv6, questionarei se você deve hospedar servidores nessa rede. Estas são minhas sugestões sobre o que fazer se o ISP atualmente não suportar o IPv6.

Primeiro, informe ao ISP que você precisa do IPv6. E talvez lembrá-los de que o protocolo IPv6 existe há 20 anos, por isso eles estão muito atrasados em apoiá-lo. Se isso não for suficiente para o ISP levá-lo a sério, comece a procurar outros ISPs.

Se você encontrar um ISP com suporte a IPv6, poderá executar com ambos os ISPs por um período de transição. No roteador conectado ao novo ISP, você pode desativar o IPv4 no lado da LAN e, em seguida, conectar os lados da LAN de ambos os roteadores ao mesmo switch. IPv4 e IPv6 são dois protocolos independentes e, como tal, não é problema se essas conexões passarem por diferentes roteadores. Como um benefício secundário, você terá alguma redundância se uma das conexões tiver uma interrupção.

Se você não conseguir encontrar um ISP com suporte a IPv6, considere a possibilidade de mover seu servidor para uma instalação de hospedagem. Com um servidor em uma instalação de hospedagem, você depende menos da localização geográfica e, por esse motivo, há mais concorrência entre provedores, o que ajudará a garantir que haja um que atenda às suas necessidades.

Mover o servidor para uma instalação de hospedagem não dará aos seus clientes o IPv6, mas mover o servidor significa que você não precisa mais do NAT suspenso para alcançá-lo.

O que você não deve fazer

Não ative o IPv6 e crie registros AAAA se não tiver uma maneira de rotear o tráfego IPv6. Se o seu ISP não suportar o IPv6, mas você optar por habilitar o IPv6 na sua rede de qualquer maneira (talvez usando endereços RFC 4193) e criar registros AAAA, ele funcionará para os clientes em sua LAN que acessam o servidor em sua LAN. Mas a comunicação entre a sua LAN e o mundo exterior primeiro tentaria o IPv6 (que não funcionaria), e você estaria contando com a queda para o IPv4, o que na melhor das hipóteses é um pouco mais lento ou, na pior das hipóteses, não acontece.     

por 05.11.2018 / 12:57
0

Como também fiz essa pergunta (consulte Como acesso um serviço de rede NATed atrás de um firewall de dentro usando seu IP externo? ) e foi redirecionado aqui, mas as respostas aqui não forneceram uma solução (em contraste com explicações genéricas ) que eu forneça minha solução Linux ( iptables specific) aqui para salvar todo mundo algumas horas de experimentação. Este arquivo está no formato iptables-restore e pode ser lido diretamente no iptables (depois de editar os endereços IP, é claro). Isto é para um servidor web (porta 80) e somente para IPv4 - as regras para IPv6 e para SSL (porta 443) são análogas.


# Port forwarding for VM / Container access with „hairpin NAT“.
*nat
:PREROUTING ACCEPT [3:205]
:INPUT ACCEPT [59:670]
:OUTPUT ACCEPT [16:172]
:POSTROUTING ACCEPT [20:257]

# This was simple port forwarding - access works from outside but not from inside
#-A PREROUTING  -4 -p tcp -i eth0 --dport 80 -j DNAT --to web.local:80

# This is real hairpin NAT which allows „web.local“ to access itself via the VM hosts external IP.
# First we need to masquerade any traffic going out the external interface:
-A POSTROUTING -o eth0 -j MASQUERADE

# Then we need to reroute incoming traffic on the public IP to the local IP:
-A PREROUTING  -4 -p tcp -d web.public.com --dport  80 -j DNAT --to web.local:80

# And finally we need to tell the router that the source IP of any traffic
# coming from the LAN must be source-rewritten when going to the web server:
-A POSTROUTING -4 -p tcp -s lan.local/24 -d web.local --dport  80 -j SNAT --to-source web.public.com:80

COMMIT

Substitua lan.local , web.local e web.public.com pela sua rede local (por exemplo, 10.0.x.0 / 24), pelo IP local do seu servidor (por exemplo, 10.0.1.2) e pelo IP público do seu roteador (por exemplo, 4.5.6.7). O -4 é apenas para permitir regras IPv6 e IPv4 no mesmo arquivo (linhas ignoradas por ip6tables ). Além disso, lembre-se de colocar endereços IPv6 em [colchetes] quando eles incluem declarações de porta, por exemplo, %código%.

Essas foram todas as coisas que me fizeram puxar o cabelo ao tentar realmente implementar as explicações nesta questão. Espero não ter deixado nada de fora.

    
por 24.03.2017 / 07:02
0

Vou adicionar uma resposta aqui, pois os comentários aqui não abordaram o meu problema específico. Eu suspeito que é porque eu acertei um bug do kernel linux desagradável. A configuração é:

internet <--> modem 1.1.1.1/30 <--> switch <---> LAN 10.1.1.0/24
                                      ^
        +----------------------+      |
        |              /--eth0 o <----/
        |              |       |           
        | 10.1.1.1/24 br0      |           v (antenna)
        |  1.1.1.2/30  |       |           |
        |              \-wlan0 o ----------/
        +----------------------+ 

Apesar da imagem complexa, a única mudança relevante nas situações abordadas em outros comentários é a adição da ponte de software, br0. Está lá porque a caixa do gateway também é um ponto de acesso sem fio para a LAN.

Nossa caixa de gateway ainda está realizando tarefas de NAT para as máquinas na LAN. Por ter apenas 1 porta ethernet, ele é forçado a fazer NAT hairpin. Eu suspeito que deve funcionar apenas com as regras do iptables dadas em outros comentários aqui, mas no kernel Linux 4.9 pelo menos não. Em 4.9, enquanto nossa caixa de gateway pode acessar a internet, as máquinas na LAN tentando acessá-lo via NAT não podem.

tcpdump mostra respostas aos pacotes que entram na eth0, mas eles não saem de br0. A execução desse comando corrige isso:

ebtables -t brouter -A BROUTING -d 01:00:00:00:00:00/01:00:00:00:00:00 -j ACCEPT
ebtables -t brouter -A BROUTING -p IPv4 --ip-dst 10.1.1.0/24 -j ACCEPT
ebtables -t brouter -A BROUTING -p IPv4 --ip-src 10.1.1.0/24 -j ACCEPT
ebtables -t brouter -A BROUTING -p IPv4 -j DROP

Antes que o comando seja executado, os pacotes recebidos são processados de acordo com o comportamento padrão dos kernels, que é o de fornecê-los à bridge, passando-os então aos módulos de roteamento do kernel. O comando força os pacotes que não são da LAN a contornar a ponte e ir diretamente para o roteamento, o que significa que a ponte não tem chance de soltá-los. Endereços de transmissão e multicast devem ser interligados, caso contrário, coisas como DHCP e mDNS não funcionarão. se você estiver usando o IPv6, você deve adicionar regras também.

Você pode se sentir tentado a corrigir o problema usando:

brctl hairpin br0 eth0 on
brctl hairpin br0 wlan0 on

Eu certamente fiquei tão tentado - foi minha primeira tentativa. Assim que fiz isso, as máquinas na LAN ganharam acesso à internet, por isso funciona por um tempo. Então ocorreu o seguinte (e não me importei em repetir o experimento):

  1. Os tempos de ping na LAN para o gateway dobraram em intervalos de 10 segundos, passando de 0,1 ms a 0,2 ms, 0,4 ms, 0,8 ms, 2 ms e assim por diante, até que a caixa do gateway estivesse inacessível da LAN. Cheirava como uma tempestade de pacotes, mas o STP estava ligado em todos os lugares.
  2. Não muito depois de todos os pontos de acesso sem fio terem morrido.
  3. Ao tentar diagnosticar o que estava acontecendo com a rede sem fio, todos os telefones IP foram reinicializados.
  4. Pouco tempo depois, as máquinas com fio perderam todo o contato com a LAN.

A única saída era reiniciar todas as máquinas do prédio. A única exceção foi os switches de hardware, que não puderam ser reinicializados. Eles tiveram que ser alternados.

    
por 22.06.2017 / 07:45
-2

No FreeBSD usando o PF é fácil como (no seu arquivo pf.conf):

extif = "tun0"
intif = "em0"
{other rules}...
nat on $intif from any to 192.168.20.8 port 80 -> ($extif)

192.168.20.8 seria o servidor web interno.

    
por 25.06.2014 / 06:20