sviluppo-web-qa.it

Loopback all'indirizzo IP pubblico inoltrato dalla rete locale - Hairpin NAT

Questa è una domanda canonica riguardo a Hairpin NAT (Loopback NAT).

La forma generica di questa domanda è:

Abbiamo una rete con client, un server e un NAT router. C'è un port forwarding sul router al server, quindi alcuni dei suoi servizi sono disponibili esternamente. Abbiamo DNS che punta verso l'esterno IP: i client della rete locale non riescono a connettersi, ma funzionano in modo esterno.

  • Perché questo fallisce?
  • Come posso creare uno schema di denominazione unificato (nomi DNS che funzionano sia localmente che esternamente)?

Questa domanda ha le risposte unite da più altre domande. Inizialmente si riferivano a FreeBSD, D-Link, Microtik e altre apparecchiature. Stanno tutti cercando di risolvere lo stesso problema.

46
adopilot

Quello che stai cercando si chiama "forcina NAT". Le richieste dall'interfaccia interna per un indirizzo IP assegnato all'interfaccia esterna devono essere NAT come se provenissero dall'interfaccia lato esterno.

Non ho alcuna familiarità con FreeBSD, ma leggendo il manuale "pf" per OpenBSD ( http://www.openbsd.org/faq/pf/rdr.html ) le soluzioni proposte di split-horizon DNS, usando un DMZ network, o TCP il proxy mi porta a credere che "pf" non supporti il ​​tornante NAT.

Vorrei seguire la rotta del DNS split-horizon e non usare gli indirizzi IP negli URL internamente ma, invece, usando i nomi.

16
Evan Anderson

Dato che questa è stata elevata per essere la domanda canonica su NAT tornante, ho pensato che probabilmente avrebbe dovuto avere una risposta più generalmente valida di quella attualmente accettata, che (sebbene eccellente) si riferisca specificamente per FreeBSD.

Questa domanda si applica ai servizi forniti dai server su reti IPv4 indirizzate a RFC1918, che sono resi disponibili agli utenti esterni introducendo destination NAT (DNAT) sul gateway. Gli utenti interni tentano quindi di accedere a tali servizi tramite l'indirizzo esterno. Il loro pacchetto esce dal client al dispositivo gateway, il quale riscrive l'indirizzo di destinazione e lo reimposta immediatamente nella rete interna. È proprio questo brusco giro che il pacchetto fa al gateway che dà origine al nome NAT tornante , per analogia con tornante .

Il problema sorge quando il dispositivo gateway riscrive l'indirizzo di destinazione, ma non l'indirizzo di origine. Il server riceve quindi un pacchetto con un indirizzo di destinazione interno (il proprio) e un indirizzo di origine interno (il client); sa che può rispondere direttamente a tale indirizzo, quindi lo fa. Poiché tale risposta è diretta, non passa attraverso il gateway, che quindi non ha mai la possibilità di bilanciare l'effetto della destinazione in entrata NAT sul pacchetto iniziale riscrivendo l'indirizzo di origine del reso pacchetto.

Il client invia quindi un pacchetto a un indirizzo IP esterno, ma riceve una risposta da un indirizzo IP interno. Non ha idea che i due pacchetti facciano parte della stessa conversazione, quindi non avviene alcuna conversazione.

La soluzione è che per i pacchetti che richiedono tale NAT di destinazione e che raggiungono il gateway dalla rete interna, per eseguire anche source NAT (SNAT) sul pacchetto in entrata, di solito riscrivendo l'indirizzo di origine come quello del gateway. Il server quindi pensa che il client sia il gateway stesso e risponde direttamente ad esso. Ciò a sua volta offre al gateway la possibilità di bilanciare gli effetti di DNAT e SNAT sul pacchetto in entrata riscrivendo gli indirizzi di origine e di destinazione sul pacchetto di ritorno.

Il client pensa che stia parlando con un server esterno. Il server pensa che stia parlando con il dispositivo gateway. Tutte le parti sono felici. Un diagramma può essere utile a questo punto:

enter image description here

Alcuni dispositivi gateway consumer sono abbastanza luminosi da riconoscere quei pacchetti per i quali è necessario il secondo passaggio NAT, e probabilmente funzioneranno immediatamente in un tornante NAT Altri non lo sono, e quindi non lo faranno, ed è improbabile che possano essere fatti funzionare. Una discussione su quali dispositivi di livello consumer sono fuori tema per Server Fault.

In genere si può dire che i dispositivi di rete adeguati funzionino, ma - poiché non si tratta di indovinare i propri amministratori - devono essere informati di farlo. Linux usa iptables per fare il DNAT così:

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

che abiliterà DNAT semplice per la porta HTTP, a un server interno su 192.168.3.11. Ma per abilitare il tornante NAT, è necessario anche una regola come:

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

Si noti che tali regole devono trovarsi nel posto giusto nelle catene pertinenti per funzionare correttamente e, a seconda delle impostazioni nella catena filter, potrebbero essere necessarie regole aggiuntive per consentire il flusso del traffico NATted. Tutte queste discussioni non rientrano nell'ambito di questa risposta.

Ma come altri hanno già detto, abilitare correttamente la forcina NAT non è il modo migliore per gestire il problema. Il migliore è DNS split-horizon , in cui l'organizzazione fornisce risposte diverse per la ricerca originale a seconda di dove si trova il client richiedente, sia con server fisici diversi per utenti interni rispetto a quelli esterni, sia configurando il server DNS per rispondere in modo diverso in base al indirizzo del cliente richiedente.

49
MadHatter

Il problema qui è che il tuo router non NAT l'indirizzo del tuo client interno. Pertanto, l'handshake TCP fallisce.

Supponiamo che seguiamo gli IP

  • Cliente: 192.168.1.3
  • Server: 192.168.1.2
  • Router interno: 192.168.1
  • Router esterno: 123.123.123.1

Ecco cosa sta succedendo:

  1. Il client (192.168.1.3) invia TCP-SYN al tuo IP esterno, porta 80 (123.123.123.1:80)
  2. Il router rileva la regola di port forwarding e inoltra il pacchetto al server (192.168.1.2:80) senza modificare l'IP di origine (192.168.1.3)
  3. Il client attende un SYN-ACK dall'IP esterno
  4. Il server invia la sua risposta direttamente al client, perché si trova sulla stessa sottorete. Non invia il pacchetto al router, che invertirebbe il NAT.
  5. Il client riceve un SYN-ACK da 192.168.1.2 anziché 123.123.123.1. E lo scarta.
  6. Il client attende ancora un SYN-ACK dal 123.123.123.1 e scade.
9
PEra

Perché non usare DNS DNS split horizon invece di indirizzi IP hardcoding ovunque? Avresti ext.ydomdomain che punta a 217.x.x.x all'esterno e quindi 192.x.x.x all'interno.

4
Ryaner

Se si tratta di un router D-Link originale (ovvero, non Rev. D/Versione firmware 1.00VG di Virgin Media), dovresti essere in grado di regolare le impostazioni per aggirare questo. (Tuttavia, sono d'accordo con il suggerimento del precedente poster di DD-WRT per molte altre ragioni!)

  1. Accedi all'interfaccia Web del router
  2. Fai clic sulla scheda Avanzate in alto
  3. Fai clic sulla scheda Impostazioni firewall a sinistra
  4. Fare clic sul pulsante di opzione Indipendente dall'endpoint sotto Filtro endpoint TCP , come mostrato in lo screenshot qui sotto (o vedi emulatore del router sul sito web di D-Link)
  5. Salvare le modifiche; hai finito

D-Link router web UI screenshot

Questa schermata è tratta dal modello Rev. C; il tuo potrebbe essere leggermente diverso.

2
David

Di recente ha risposto a una domanda simile: Cisco static NAT non funziona sul lato LAN e ho appena realizzato che si tratta di una domanda canonica. Consentitemi quindi di riassumere il soluzione qui.

Prima di tutto: dimentica di NAT (se puoi) - la domanda non riguarda affatto la configurazione di NAT. Si tratta di accedere a un server posizionato dietro NAT da sia Internet che LAN. L'impiego di due zone DNS è un'alternativa praticabile, ma non sempre la soluzione. Ma la soluzione esiste ed è incredibilmente semplice (anche se non perfetta, probabilmente):

(1) sul server: aggiungi l'indirizzo IP pubblico come indirizzo IP secondario sull'interfaccia di rete del server con la maschera 255.255.255.255 (il servizio web o qualunque cosa tu voglia sul server dovrebbe ascoltare anche su questo indirizzo IP); tutti i moderni sistemi operativi ti permetteranno di farlo (oppure puoi usare un'interfaccia di loopback con l'indirizzo IP pubblico assegnato ad esso invece di aggiungere un IP secondario all'interfaccia primaria).

(2) sugli host LAN: aggiungi una route Host per l'indirizzo IP pubblico, ad esempio per host Windows usa il seguente comando: route -p aggiungi 203.0.113.130 maschera 255.255.255.255 192.168 .1.11 (puoi anche usare l'opzione DHCP "route statica" per distribuire la route). Oppure, se ci sono (a) switch/i/i L3 tra i client e il router con connessione a Internet, configurare quel percorso host su questi (questi) switch/router/i intermedi, non sui clienti.

Per coloro che riguardano il TCP stretta di mano a tre vie: funzionerà bene nella configurazione proposta.

Si prega di fornire un feedback (almeno, votare).

2
Sergio

Da un punto di vista tecnico, la soluzione migliore a questo problema è abilitare IPv6 sulla rete. Quando IPv6 è abilitato, devi creare un record AAAA per il tuo dominio. Mantenere il record A esistente che punta all'IPv4 esterno del router . Creare un record AAAA che punta all'indirizzo IPv6 del server .

IPv6 ha abbastanza indirizzi per evitare NAT, quindi non avrai bisogno di hairpin NAT per IPv6. E una volta abilitato IPv6 e creato AAAA registra qualsiasi client che supporti RFC 8305 proverà IPv6 prima di IPv4. Ciò significa che non hai bisogno di hairpin NAT per IPv4, perché i client non lo useranno.

Avrai ancora bisogno del tuo IPv4 NAT esistente per le connessioni in uscita e il port forwarding per le connessioni in entrata fino a quando la maggior parte del mondo ha abilitato anche IPv6.

È anche più veloce.

L'utilizzo di IPv6 offre prestazioni migliori rispetto al NAT a forcina.

Con hairpin NAT il tuo client invierà un pacchetto attraverso uno switch al router, il router eseguirà quindi due round di traduzione e infine invierà il pacchetto attraverso lo switch al server. Pacchetti dal server al cliente attraverserà l'intero percorso al contrario.

Con IPv6 eviti il ​​NAT, invece i pacchetti vengono inviati direttamente attraverso il passaggio tra client e server. Ciò significa che in un viaggio di andata e ritorno riduci il numero di passaggi attraverso lo switch da 4 a 2 ed eviti 2 viaggi attraverso il router e le 4 traduzioni che il router avrebbe eseguito. Questo si traduce in prestazioni migliori.

Ciò è vero anche se si utilizza uno switch incorporato nella stessa scatola del router.

Cosa succede se l'ISP non ha IPv6?

Se stai usando un ISP che non supporta IPv6, mi chiederò se dovresti ospitare server su quella rete. Questi sono i miei suggerimenti su cosa fare se l'ISP non supporta attualmente IPv6.

Prima di tutto informa l'ISP che hai bisogno di IPv6. E forse ricordare loro che il protocollo IPv6 esiste da 20 anni, quindi sono attesi da tempo per supportarlo. Se questo non è abbastanza perché l'ISP ti prenda sul serio, inizia a cercare altri ISP.

Se trovi un ISP con supporto IPv6, puoi eseguirlo con entrambi gli ISP per un periodo di transizione. Sul router connesso al nuovo ISP è possibile disabilitare IPv4 sul lato LAN e quindi collegare i lati LAN di entrambi i router allo stesso switch. IPv4 e IPv6 sono due protocolli indipendenti e come tali non è affatto un problema se tali connessioni passano attraverso router diversi. Come vantaggio secondario ti dà una certa ridondanza se una delle connessioni ha un'interruzione.

Se non riesci a trovare un ISP con supporto IPv6, dovresti considerare di spostare il tuo server in una struttura di hosting. Con un server in una struttura di hosting sei meno dipendente dalla posizione geografica e per questo motivo c'è più concorrenza tra i fornitori che ti aiuterà a garantire che ce ne sia uno che soddisfi le tue esigenze.

Spostare il server in una struttura di hosting non darà IPv6 ai tuoi clienti, ma spostare il server significa che non hai più bisogno di tornante NAT per raggiungerlo.

Cosa non dovresti fare

Non attivare IPv6 e creare record AAAA se non si dispone di un modo per instradare il traffico IPv6. Se il tuo ISP non supporta IPv6 ma decidi di abilitare comunque IPv6 sulla tua LAN (magari usando indirizzi RFC 4193) e creare record AAAA funzionerà per i client sulla tua LAN che raggiungono il server sulla tua LAN. Ma la comunicazione tra la tua LAN e il mondo esterno proverebbe prima IPv6 (che non funzionerebbe) e ti affideresti a ricadere su IPv4 che nella migliore delle ipotesi è un po 'più lento o nella peggiore delle ipotesi non accade.

1
kasperd

Devo rispondere alle mie domande solo per ampliare gli orizzonti per quelli con problemi simili.

Sono stato contattato dal mio ISP e ho chiesto loro di provare a risolvere i miei problemi. Quello che mi hanno offerto è un altro indirizzo IP pubblico solo per il server, ora ho traffico locale sul lato WAN di FreeBSD e abbiamo creato pipe specifiche per un throughput più veloce del traffico locale verso l'IP pubblico del server

1
adopilot

Aggiungerò una risposta qui poiché i commenti qui non hanno affrontato il mio problema specifico. Ho il sospetto che sia perché ho colpito un brutto bug del kernel Linux. L'impostazione è:

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 ----------/
        +----------------------+ 

Nonostante l'immagine complessa, l'unica modifica rilevante alle situazioni trattate in altri commenti è l'aggiunta del bridge software, br0. È lì perché il gateway box è anche un punto di accesso wireless per la LAN.

Il nostro gateway box sta ancora eseguendo NAT compiti per le macchine sulla LAN. Poiché ha solo 1 porta Ethernet, è costretto a fare un tornante NAT. Sospetto che dovrebbe funzionare solo con le regole iptables fornite in altri commenti qui, ma almeno sul kernel Linux 4.9. Sotto 4.9 i nostri mentre la nostra casella gateway può accedere a Internet alle macchine sulla LAN cercando di accedervi tramite NAT can 't.

tcpdump mostra le risposte ai pacchetti in arrivo che colpiscono eth0, ma non lo fanno da br0. L'esecuzione di questo comando consente di correggere che:

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

Prima di eseguire quel comando, i pacchetti in arrivo vengono elaborati in base al comportamento predefinito dei kernel, che è quello di consegnarli al bridge e poi passare i moduli di routing del kernel. Il comando forza i pacchetti che non provengono dalla LAN per bypassare il bridge e passare direttamente al routing, il che significa che il bridge non ha la possibilità di eliminarli. Gli indirizzi broadcast e multicast devono essere collegati a ponte, altrimenti cose come DHCP e mDNS non funzioneranno. se si utilizza IPv6, è necessario aggiungere anche regole per esso.

Potresti essere tentato di risolvere il problema usando questo:

brctl hairpin br0 eth0 on
brctl hairpin br0 wlan0 on

Ero certamente così tentato: era il mio primo tentativo. Non appena l'ho fatto, le macchine sulla LAN hanno ottenuto l'accesso a Internet, quindi funziona per un po '. Quindi si è verificato quanto segue (e non mi importava ripetere l'esperimento):

  1. I tempi di ping attraverso la LAN al gateway sono raddoppiati a intervalli di circa 10 secondi, passando da 0,1 ms a 0,2 ms, 0,4 ms, 0,8 ms, 2 ms e così via fino a quando il gateway non è stato inaccessibile dalla LAN. Puzzava come una tempesta di pacchetti, ma STP era acceso ovunque.
  2. Non molto tempo dopo la morte di tutti i punti di accesso wireless.
  3. Durante il tentativo di diagnosticare ciò che stava accadendo con il wireless, tutti i telefoni IP si sono riavviati.
  4. Non molto tempo dopo, le macchine cablate persero tutti i contatti con la LAN.

L'unica via d'uscita era riavviare ogni macchina nell'edificio. L'unica eccezione erano gli switch hardware, che non potevano essere riavviati. Dovevano essere sottoposti a ciclo di alimentazione.

0
Russell Stuart

Dal momento che ho anche posto questa domanda (vedi Come posso accedere a un servizio di rete NATed dietro un firewall dall'interno usando il suo IP esterno? ) e sono stato reindirizzato qui ma le risposte qui non hanno fornito un soluzione (al contrario delle spiegazioni generiche ) lascia che fornisca il mio Linux (iptables specifica) qui per risparmiare a tutti qualche ora di sperimentazione. Questo file è in iptables-restore e può essere letto direttamente in iptables (ovviamente dopo aver modificato gli indirizzi IP). Questo è per un server web (porta 80) e solo per IPv4 - le regole per IPv6 e per SSL (porta 443) sono analoghe.


# 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

Sostituisci lan.local, web.local e web.public.com con la tua rete locale (es. 10.0.x.0/24), l'IP locale del tuo server web (es. 10.0.1.2) e l'IP pubblico del tuo router (es. 4.5.6.7). Il -4 è solo per consentire le regole IPv6 e IPv4 nello stesso file (tali righe ignorate da ip6tables). Ricorda inoltre di inserire gli indirizzi IPv6 tra [parentesi] quando includono dichiarazioni di porta, ad es. [fe0a:bd52::2]:80.

Queste erano tutte le cose che mi hanno fatto strappare i capelli quando ho cercato di implementare le spiegazioni in questa domanda. Spero di non aver lasciato nulla fuori.

0
Jens

Poiché è una domanda canonica. Risponderò se hai un router Sonicwall.

L'espressione da sapere è politica di loopback NAT

Questo documento descrive come un host su una LAN SonicWall può accedere a un server sulla LAN SonicWall usando l'indirizzo IP pubblico del server su FQDN. Immagina una rete NSA 4500 (SonicOS Enhanced) in cui la sottorete LAN primaria è 10.100.0.0/24 e la primaria WAN IP è 3.3.2.1. supponiamo di avere un sito Web per i tuoi clienti, e il suo nome host è. Hai già scritto le politiche e le regole necessarie affinché gli estranei possano accedere al sito Web, ma in realtà è in esecuzione su un server lato privato 10.100.0.2. Immagina ora che sei una persona che utilizza un laptop sul lato privato, con IP di 10.100.0.200. Desideri raggiungere il server utilizzando il suo nome pubblico, perché fai la stessa cosa quando il laptop è con te in viaggio. Se ti siedi il lato privato e richiesta http://www.example.com >, il loopback è ciò che rende possibile che funzioni, anche se il server si trova proprio accanto a te su un indirizzo IP locale .

Per consentire questa funzionalità, è necessario creare un NAT criterio di loopback, noto anche come NAT riflessione o forcina.

Criterio di loopback utilizzando WAN Indirizzo IP dell'interfaccia

Login to the SonicWall Management GUI.
Navigate to Manage | Rules | NAT Policies submenu.
Click on the Add button.
Create the following NAT Policy.
Original Source: LAN Subnets (or Firewalled Subnets if you want hosts in other zones to be included)
Translated Source: WAN Interface IP
Original Destination: WAN Interface IP
Translated Destination: (LAN server object)
Original Service: Any
Translated Service: Original
Inbound Interface: Any
Outbound Interface: Any

Il sonicwall riconoscerà il servizio esterno che si tenta di contattare e riscriverà l'indirizzo di destinazione per adattarlo all'indirizzo interno del server, quindi sarà trasparente per il computer.

0
yagmoth555