Comment faire le transfert de port d'une adresse IP à une autre adresse IP dans le même réseau?

77

Je voudrais faire un peu NATde iptablespo Ainsi, tous les paquets arrivant sur 192.168.12.87et le port 80seront transférés au 192.168.12.77port 80.

Comment faire cela avec iptables?

Ou

Y a-t-il d'autres moyens d'atteindre le même objectif?

Sam
la source
@ Matthewlfe, Pour une raison quelconque, je dois transférer toutes les demandes Apache de (192.168.12.87) à (192.168.12.77).
sat
1
@ Matthewlfe, j'ai deux serveurs de production. On est connecté avec l'adresse IP statique publique. En raison de problèmes de connectivité, je ne parviens pas à me connecter à la base de données ni à d’autres systèmes 192.168.12.87. Donc, je dois transmettre toute la demande à 192.168.12.77.
sat
@lain, je ne suis pas au courant iptables. Et j'ai vu des exemples. Mais, il semble être besoin de deux ethernet. Lien: revsys.com/writings/quicktips/nat.html
sam
Vous pouvez également utiliser le mode proxy dans la configuration de votre serveur Web pour envoyer des demandes à 192.168.12.77 à partir de 192.168.12.87 (si votre serveur Web le prend en charge)
krisFR

Réponses:

75

Ces règles devraient fonctionner, en supposant que cela iptablesfonctionne sur le serveur 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

Vous devez DNAT le trafic entrant sur le port 80, mais vous devez également renvoyer le trafic par SNAT.


Alternative (et meilleure approche IMHO):

En fonction de la nature de votre serveur Web (Apache, NGinx), vous devez envisager un proxy HTTP sur votre serveur frontal (192.168.12.87):

krisFR
la source
Fonctionne tant que ufw est désactivé, même si le port est autorisé à ufw, mais si ufw est activé, ce transfert ne fonctionne pas, vous avez une idée?
Sudhir N
1
Grande question avec une bonne réponse. Un autre cas d’utilisation est utile si vous devez rediriger temporairement tout le trafic provenant d’un service, disons squid, vers un autre IP / port, de manière à effectuer une maintenance du service original sans reconfigurer tous les clients! Très utile!
PF4Public
3
"mais vous devrez également renvoyer le trafic." -> Vous avez sauvé ma journée. Merci
obayhan
Cette solution ne fonctionne pas pour moi. J'ai besoin de transférer depuis eth0 vers un réseau virtuel (virb0) utilisé par un invité KVM. J'ai essayé d'ajouter les options -i et -o mais -o n'est pas autorisé pour le préroutage. Aucune suggestion?
lostiniceland
Soyez prudent avec cette solution. J'ai complètement perdu l'accès à ma machine distante maintenant.
Sören
28

Une raison apparemment évidente iptables -t nat -A PREROUTING -d 192.168.12.87 -p tcp --dport 80 -j DNAT --to-destination 192.168.12.77ne fonctionnera pas, c'est la façon dont les paquets de retour seront acheminés.

Vous pouvez configurer des règles pour que les paquets envoyés à 192.168.12.87 soient simplement convertis en NAT en 192.168.12.77, mais 192.168.12.77 enverra ensuite les réponses directement au client. Ces réponses ne passeront pas par l'hôte où votre règle iptables utilise NAT. Par conséquent, les paquets d'une direction sont traduits, mais les paquets de l'autre ne le sont pas.

Il existe trois approches pour résoudre ce problème.

  1. Sur le premier hôte, ne faites pas que DNAT, mais également SNAT de sorte que le trafic de retour soit renvoyé par le premier hôte. La règle pourrait ressembler à quelque chose commeiptables -t NAT -A POSTROUTING -d 192.168.12.77 -p tcp --dport 80 -j SNAT --to-source 192.168.12.87
  2. Inspirez-vous de l'équilibrage de charge DSR et DNAT les paquets au niveau de la couche Ethernet au lieu de la couche IP. En remplaçant la MAC de destination des paquets par la MAC de 192.168.12.77 et en l'envoyant sur Ethernet sans toucher à la couche IP, 192.168.12.77 pourrait alors avoir 192.168.12.87 configuré sur une interface fictive et ainsi pouvoir mettre fin à la connexion TCP avec l'adresse IP du serveur connue du client.
  3. Utilisez la solution naïve (mais ne fonctionne pas) sur le premier hôte. Ensuite, gérez les paquets de retour sur le second hôte en effectuant un SNAT sur le trafic de retour. Une règle pourrait ressembler àiptables -t nat -A OUTPUT -p tcp --sport 80 -j SNAT --to-source 192.168.12.87

Chacune de ces trois solutions présentant des inconvénients, vous devez donc examiner attentivement si vous devez réellement effectuer cette transmission particulière.

  1. Si SNAT perd l'adresse IP du client, l'hôte numéro 2 pensera que toutes les connexions proviennent de 192.168.12.87. De plus, vous utiliserez la bande passante par le biais de l'hôte numéro 1 pour tous les paquets de réponse, ce qui emprunterait un chemin plus direct avec les autres approches.
  2. L’approche DSR interrompt toutes les autres communications entre les deux nœuds. L’approche DSR n’est vraiment appropriée que lorsque l’adresse du serveur n’est pas l’IP principale de l’un des hôtes. Chaque hôte doit avoir une adresse IP principale, qui n'est pas l'adresse IP du DSR.
  3. Utiliser le suivi de connexion sur un hôte pour traduire dans un sens et le suivi de connexion sur un autre hôte pour traduire dans l'autre sens est vraiment moche, et il peut être rompu de différentes manières. Par exemple, si les numéros de port sont modifiés par NAT sur l'un des hôtes, il est impossible de les reconstruire. Ce n’est pas non plus un fait, le suivi de la connexion fonctionnera correctement si le premier paquet qu’il voit est un SYN-ACK plutôt qu’un ACK.

Je pense que la première est l’une des trois approches qui est la plus susceptible de fonctionner. Donc, si vous n'avez pas besoin de connaître les adresses IP du client, c'est celle que je recommanderais.

Vous pouvez également choisir d'oublier le NAT complètement et de ne pas essayer de résoudre le problème sur la couche MAC ou IP. Vous pouvez aller jusqu'à la couche HTTP et chercher une solution là-bas. Dans ce cas, la solution que vous trouverez est un proxy HTTP. Si vous installez un proxy HTTP sur 192.168.12.87 et le configurez correctement, vous pouvez le faire transférer les demandes vers 192.168.12.77 et renvoyer les réponses. De plus, il peut insérer un en-tête X-Forwarded-For préservant l'adresse IP du client d'origine. Le serveur sur 192.168.12.77 doit ensuite être configuré pour faire confiance à l'en-tête X-Forwarded-For de 192.168.12.87.

Kasperd
la source
Je suis surpris, ce -j MASQUERADEn'est pas mentionné ici; N'est-ce pas l'approche habituelle avec DNAT?
Remram
3
@remram j'ai mentionné SNATau lieu de MASQUERADE, parce que c'est ce que dit la documentation. La formulation exacte dans la documentation est la suivante:It should only be used with dynamically assigned IP (dialup) connections: if you have a static IP address, you should use the SNAT target.
kasperd