Soluzione 1:
Queste regole dovrebbero funzionare, supponendo che iptables
è in esecuzione sul server 192.168.12.87
:
#!/bin/sh
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -F
iptables -t nat -F
iptables -X
iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to-destination 192.168.12.77:80
iptables -t nat -A POSTROUTING -p tcp -d 192.168.12.77 --dport 80 -j SNAT --to-source 192.168.12.87
Devi eseguire la DNAT del traffico in entrata sulla porta 80, ma dovrai anche eseguire la SNAT del traffico di ritorno.
Alternativa (e migliore approccio IMHO):
A seconda di quale sia il tuo server Web (Apache, NGinx) dovresti considerare un proxy HTTP sul tuo server front-end (192.168.12.87):
-
mod_proxy (Apache)
-
proxy_pass (NGinx)
Soluzione 2:
Il motivo è apparentemente ovvio iptables -t nat -A PREROUTING -d 192.168.12.87 -p tcp --dport 80 -j DNAT --to-destination 192.168.12.77
non funzionerà è come verranno instradati i pacchetti di ritorno.
È possibile impostare regole che faranno sì che i pacchetti inviati a 192.168.12.87 vengano semplicemente NATtati a 192.168.12.77, ma 192.168.12.77 invierà le risposte direttamente al client. Queste risposte non passeranno attraverso l'host in cui la tua regola iptables sta eseguendo il NAT, quindi i pacchetti in una direzione vengono tradotti, ma i pacchetti nell'altra direzione no.
Esistono tre approcci per risolvere questo problema.
- Sul primo host non eseguire solo DNAT, ma anche SNAT in modo tale che il traffico di ritorno venga rimandato indietro attraverso il primo host. La regola potrebbe assomigliare a
iptables -t NAT -A POSTROUTING -d 192.168.12.77 -p tcp --dport 80 -j SNAT --to-source 192.168.12.87
- Prendi ispirazione dal bilanciamento del carico DSR e dal DNAT dei pacchetti a livello Ethernet invece che a livello IP. Sostituendo il MAC di destinazione dei pacchetti con il MAC di 192.168.12.77 e inviandolo su Ethernet senza toccare il livello IP, allora 192.168.12.77 potrebbe avere 192.168.12.87 configurato su un'interfaccia fittizia e quindi poter terminare la connessione TCP con l'IP del server noto al client.
- Usa la soluzione ingenua (ma non funzionante) sul primo host. Quindi gestire i pacchetti di ritorno sul secondo host eseguendo uno SNAT sul traffico di ritorno. Una regola potrebbe essere simile a
iptables -t nat -A OUTPUT -p tcp --sport 80 -j SNAT --to-source 192.168.12.87
Ognuna di queste tre soluzioni ha degli svantaggi, quindi devi considerare attentamente se hai davvero bisogno di fare questo particolare inoltro.
- L'utilizzo di SNAT perderà l'IP del client, quindi l'host numero 2 penserà che tutte le connessioni provengano da 192.168.12.87. Inoltre utilizzerai la larghezza di banda attraverso l'host numero 1 per tutti i pacchetti di risposta, il che richiederebbe un percorso più diretto con gli altri approcci.
- L'approccio DSR interromperà tutte le altre comunicazioni tra i due nodi. L'approccio DSR è davvero appropriato solo quando l'indirizzo del server non è l'IP primario di nessuno degli host. Ogni host deve avere un IP primario, che non è l'IP DSR.
- Utilizzare il monitoraggio della connessione su un host per tradurre in una direzione e il monitoraggio della connessione su un altro host per tradurre nell'altra direzione è semplicemente brutto e ci sono vari modi in cui potrebbe rompersi. Ad esempio, se i numeri di porta vengono modificati dal NAT su entrambi gli host, non è possibile ricostruirli. Inoltre, non è scontato che il tracciamento della connessione funzioni correttamente, se il primo pacchetto che vede è un SYN-ACK anziché un ACK.
Dei tre approcci, penso che il primo sia quello che ha maggiori probabilità di funzionare. Quindi, se non hai bisogno di conoscere gli indirizzi IP del client, questo è quello che consiglierei.
Puoi anche scegliere di dimenticare del tutto il NAT e non provare a risolvere il problema su livello MAC o IP. Puoi andare fino al livello HTTP e cercare una soluzione lì. In tal caso la soluzione che troverai è un proxy HTTP. Se installi un proxy HTTP su 192.168.12.87 e lo configuri in modo appropriato, puoi fare in modo che inoltri le richieste a 192.168.12.77 e inoltri le risposte. Inoltre può inserire un'intestazione X-Forwarded-For preservando l'IP del client originale. Il server su 192.168.12.77 deve quindi essere configurato per considerare attendibile l'intestazione X-Forwarded-For da 192.168.12.87.