Forum général.général iptables port forwarding

Posté par .
Tags : aucun
1
30
jan.
2009
J'aimerai rediriger le port d'une machine B (192.168.0.10) vers le même port de la machine A (192.168.0.1).

sur la machine B j'ai donc:
iptables -t nat -A PREROUTING -p tcp -d 192.168.0.10 --dport 8080 -j DNAT --to 192.168.0.1

Malgré cette règle, une connexion sur 192.168.0.10:8080 tombe systématiquement en timeout.

ip_forward est à 1 et toutes les chaines sont en ACCEPT.
De plus, un log sur la chaine FORWARD de la table filter m'indique bien que l'ip de destination a bien été modifié par la règle ci-dessus

Je dois forcément oublier quelque chose, mais quoi ?
  • # Normal

    Posté par (page perso) . Évalué à 2.

    Tu fais la traduction sur B, le paquet arrive sur B, est transformé, traverse B resort pour aller sur A.

    A voir le paquet, traite le demande, puis renvoit le paquet à la machine d'origine.

    La machine d'origine ne connait pas A et ignore le paquet.

    Il faut donc que tu fasse croire à A que le paquet vient de B -> du SNAT en plus en sortie, mais attention.
    • [^] # Re: Normal

      Posté par . Évalué à 2.

      Pas d'accord avec ta réponse, ni celle du dessous.
      Iptables est un firewall _statefull_, ce qui veut dire qu'il track les connexions, et dans NAT il y a _translation_, ce qui veut dire que B va bien faire croire à A que c'est lui qui a inité la connexion.
      Alors, où se trouve le problème ? Là, j'avoue qu'on manque un peu de détails :
      - quelle est le schéma du réseau ? A et B sont-ils sur le même segment ethernet ? (à priori oui, mais on sait jamais)
      - quelles sont les autres règles du par-feu ? À priori c'est effectivement un problème de "retour" des paquets, mais il faudrait par exemple bien voir si B qui forwarde autorise bien les paquets retour (avec une règle genre --cstate ESTABLISHED,RELATED), etc.
      • [^] # Re: Normal

        Posté par . Évalué à 2.


        ce qui veut dire qu'il track les connexions, et dans NAT il y a _translation_, ce qui veut dire que B va bien faire croire à A que c'est lui qui a inité la connexion.

        Dans DNAT il y a Destination, donc seule la destination est modifiée c'est bien pour ça qu'il faut également modifier la source pour faire croire à A que c'est B qui a initié la connection.

        quelles sont les autres règles du par-feu ? À priori c'est effectivement un problème de "retour" des paquets, mais il faudrait par exemple bien voir si B qui forwarde autorise bien les paquets retour (avec une règle genre --cstate ESTABLISHED,RELATED), etc.

        Les chaines sont en ACCEPT, donc à priori le pare-feu est ouvert (sauf si certaines règles de DROP se trouvent dans la chaine FORWARD..).

        A ma connaissance, NEW, ESTABLISHED.. servent à affiner le filtrage du paquet par rapport a l'état de sa connection (si le protocole est stateful). Si ce n'est pas spécifié, pas de filtrage sur ce point.
        RELATED c'est utile avec certains protocoles qui ouvrent des ports dynamiquements et qui peuvent être autorisés grace à un 'connection tracker' tel que: irc_conntrack, ftp_conntrack...

        Iptables est un firewall _statefull_,

        Iptables stateful? j'ai des doutes, car ça dépend du protocole.
        Je pense que l'ont peut configurer un firewall stateful avec iptables, mais que ce n'est pas une obligation.
        Exemple, UDP est stateless par nature, il me semble qu'iptables simule du stateful en se servant d'un module externe (xt_state, xt_tcpudp probablement) qui utilise des temporisateurs configurables comme ici: /proc/sys/net/ipv4/netfilter/ip_conntrack_udp_timeout.
        Ainsi, il est possible d'utiliser des choses tel que -m state --state NEW sur une connection UDP. Mais ça reste optionel (-m).
        D'ailleur il me semble que c'est à cause de ce 'UDP-timeout' que quand l'on décide d'interdire un flux UDP, il faut attendre un certain temps avant que cette règle ne soit fonctionnelle sur le traffique déjà existant.. à confirmer..
        • [^] # Re: Normal

          Posté par . Évalué à 2.

          Dans DNAT il y a Destination, donc seule la destination est modifiée c'est bien pour ça qu'il faut également modifier la source pour faire croire à A que c'est B qui a initié la connection.
          Rhaa, merde, désolé, je me suis emmélé les pinceaux.

          Les chaines sont en ACCEPT, donc à priori le pare-feu est ouvert (sauf si certaines règles de DROP se trouvent dans la chaine FORWARD..).
          Re-désolé, j'ai lu trop vite. Effectivement dans ce cas les NEW/ESTABLISHED sont inutiles, et ton explication de leur rôle est bonne.

          Je pense que l'ont peut configurer un firewall stateful avec iptables, mais que ce n'est pas une obligation.
          Oui, c'est ce que je voulais dire, même si j'ai un peu raccourci... Qui peut le plus (statefull) peut le moins (stateless). Enfin, en général ...
      • [^] # Re: Normal

        Posté par (page perso) . Évalué à 3.

        En effet, iptables est stateful (autant que possible), mais il ne fait pas ce qu'on ne lui dit pas de faire.

        Le paquets recu par le firewall seront bien retransformé dans l'autre sens lors du retour. Sauf que là il n'y a pas de retour puisqu'on ne lui a pas dit de modifier l'adresse de retour pour qu'elle passe par lui.

        Le problème est en quelque sorte sur la machine de destination. Un autre solution serait de changer la table de routage de la machine de destination A pour qu'elle passe par B à chaque fois. Mais ca pourrait être genant pour les autres connexions.
        • [^] # Re: Normal

          Posté par (page perso) . Évalué à 2.

          oui je suis d'accord avec l'analyse de peck.

          soit une station X qui envoie un paquet vers 192.168..0.10:8080:
          ce paquet est de la forme:
          source:X,portX,destination:192.168.0.10:8080 (tcp SYN)

          ce paquet arrive à B tel quel et est transformé par B en
          source:X,portX,destination:192.168.0.1:8080 (tcp SYN)

          et est expédié à A qui le reçoit :
          source:X,portX,destination:192.168.0.1:8080 (tcp SYN)

          l'application (apache ? ) le traite et y réponds :
          source:192.168.0.1.0:8080, destination:X:portX (tcp SYN,ACK)

          là le paquet est réexpédé à la station X sans passer pas B....

          vu de X on a donc eu un échange :
          > source:X,portX,destination:192.168.0.10:8080. (tcp SYN)
          < source:192.168.0.1:8080, destination:X:portX (tcp SYN,ACK)

          Si ce paquet arrive jusqu'à X, l'application sur X qui l'a émis ne le recevra pas, la pile TCP/IP de X détruira simplement ce paquet car il ne correspond pas à la conversation attendue ( on attends source:192.168.0.10:8080, destination:X:portX (tcp SYN,ACK) )

          un petit wireshark sur B A et X permettra de te montrer explicitement ce qui se passe

          En fait le NAT doit s'effectuer sur le routeur ( dont on a aucun renseignement ici ) et non sur le server 192.168.0.1. sinon il faut utliser de la redirection au niveau http et monter un serveur apache sur 192.168.0.1...
        • [^] # Re: Normal

          Posté par . Évalué à 2.

          OK, comme dit plus haut, je me suis trompé.
          Par contre, le problème arrive parce que les deux machines A et B sont sur le même segment : s'ils elles n'y étaient pas, et que B était la gateway de A, B retransformerait bien l'adresse comme il faut au retour.
          D'où ta solution de changer la table de routage de A, qui peut fonctionner si B forward tout comme il faut.
  • # Rajoute ça sur B:

    Posté par . Évalué à 1.

    Rajoute ça sur B:

    iptables -t nat -A POSTROUTING -p tcp -d 192.168.0.1 --dport 8080 -j SNAT --to-source 192.168.0.10


    Sans cette règle:
    -Une machine C envoie un paquet B
    -B transmettra bien ce paquet à A. (tcpdump doit pouvoir le confirmer)
    -Mais A reçoit un paquet ayant pour source C
    -A répond à C alors que C attends logiquement une réponse de B.
    -Si C est dans le même réseau que A, C recevra le paquet de 'retour'
    mais l'ignorera car il ne vient pas de B.
    -Si C n'est pas dans le même réseau, le paquet de 'retour' sera routé via la
    gateway par défaut de A qui n'est probablement pas B dans ton cas..

    Donc soit le paquet de 'retour' n'arrivera pas, soit il aura une mauvaise source et sera rejetté par C.

    Par contre, si B est la gateway par défaut de A et que celle-ci (A) NAT ce qui sort, cette règle de POSTROUTING n'est pas nécessaire quand C est en dehors du réseau A,B.

Suivre le flux des commentaires

Note : les commentaires appartiennent à ceux qui les ont postés. Nous n'en sommes pas responsables.