La redirection de port iptables ne fonctionne pas pour localhost

55

Je veux rediriger tout le trafic du port 443 vers le port interne 8080. J'utilise cette configuration pour iptables:

iptables -t nat -I PREROUTING --source 0/0 --destination 0/0 -p tcp \
         --dport 443 -j REDIRECT --to-ports 8080

Cela fonctionne pour tous les clients externes. Mais si j'essaie d'accéder au port 443 à partir de la même machine, j'obtiendrai une erreur de connexion refusée.

wget https://localhost

Comment puis-je étendre la règle iptables pour rediriger également le trafic local?

Chris
la source
Cette rubrique fournit une réponse plus générale: serverfault.com/questions/380447/iptables-preroute-localhost
Jeroen
1
Quelqu'un avec le représentant peut-il ajouter une barre oblique inverse à la commande avant le saut de ligne?
Ciro Santilli a écrit:

Réponses:

69

PREROUTING n'est pas utilisé par l'interface de bouclage, vous devez également ajouter une règle OUTPUT:

iptables -t nat -I PREROUTING -p tcp --dport 443 -j REDIRECT --to-ports 8080
iptables -t nat -I OUTPUT -p tcp -o lo --dport 443 -j REDIRECT --to-ports 8080
Andy
la source
3
Pas besoin de la première règle. Les paquets générés localement ne passent pas par la chaîne PREROUTING.
Khaled
9
J'ai ajouté la règle initiale par souci de compatibilité, car il souhaitait également que le trafic externe soit redirigé. La règle n'a pas besoin de source / destination si elle dit seulement d'accepter toutes les adresses IP
Andy
oh appologies je n'ai pas vu votre réponse quand j'ai répondu.
Andy
Bonjour Andy, je suis toujours en train de me connecter à server.com | <ip> |: 443 ... a échoué: la connexion a été refusée.
Chris
Bonjour Chris, s’agit-il de Connexion à localhost | 127.0.0.1 | 443 ou est-ce le domaine? Si ce dernier et vous l'exécutez à partir de votre serveur, vous pourriez avoir un problème de routage interne. Vous pouvez double-vérifier en essayant wget server.com:8080 (bien que je suppose que la raison du transfert de port est son blocage externe). Mon propre VPC a ce problème, mais vous pouvez éventuellement contourner le problème en définissant le domaine comme 127.0.0.1 dans votre fichier / etc / hosts.
Andy
10

Pour rediriger les paquets de localhost vers une autre machine, la règle:

 iptables -t nat -A OUTPUT -o lo -d 127.0.0.1 -p tcp --dport 443 -j DNAT  --to-destination 10.x.y.z:port

fonctionnera, MAIS vous devez également activer cette option dans le noyau:

sysctl -w net.ipv4.conf.all.route_localnet=1

Sans cette configuration du noyau, cela ne fonctionnera pas.


la source
Cela fonctionnerait aussi. Je pense que tout faire dans iptables est plus propre.
Quadruplebucky
En fait, le paramètre du noyau est requis si la destination est sur une autre machine, connectez une machine virtuelle ou une machine distante.
ce n'est pas si vous avez les deux règles comme Andy a suggéré ci-dessus.
quadruplebucky
Désolé, je parlais du cas de transfert vers une autre machine sur laquelle DNAT ne fonctionne pas. Je cherchais cette solution pour trouver une solution à un problème lorsque j'essayais de transmettre quelque chose qui pensait qu'il était connecté à localhost à un conteneur situé sur la même machine. par exemple, exécuter le serveur de noms dans un conteneur pour les requêtes locales.
En fait, cela dépend apparemment de la version du noyau> = 3.6.
Quadruplebucky
3

Que dis-tu de ça?

iptables -t nat -A SORTIE -d 127.0.0.1 -p tcp --dport 443 -j REDIRECT --to-port 8080

Athanasios
la source
2

Vous avez dit que vous obtenez une erreur de connexion refusée . Cela signifie qu’aucun processus local n’écoute sur le port auquel vous essayez de vous connecter! Pour vérifier les processus d'écoute, utilisez la commande:

$ sudo netstat -lnp | grep 8080

Après avoir appliqué la règle, vous devez avoir un processus à l'écoute sur le port 8080 pour vous connecter.

Il semble que vous devriez plutôt avoir la règle suivante:

$ iptables -t nat -I OUTPUT --source 0/0 --destination 0/0 -p tcp
                                       --dport 443 -j REDIRECT --to-ports 8080

Rappelez-vous que vous envoyez depuis l'hôte local. Donc, vous devez rediriger le paquet de sortie.

Khaled
la source
1
Merci pour votre réponse. Le processus écoute sur le port 8080. Par conséquent, je souhaite rediriger tout le trafic sur ce port.
Chris
Êtes-vous sûr que le processus écoute également sur l'interface de boucle? Il se peut qu’il n’écoute que sur votre interface physique. En règle générale, votre serveur Web devra écouter 0.0.0.0 plutôt que, par exemple, 192.168.10.0
MrMajestyk le