iptables + NAT + FTP problem

Discussion in 'Linux Networking' started by Jaroslaw Rafa, May 27, 2015.

  1. Hello,
    maybe I'm asking something obvious, but have extensively searched the Net
    and didn't find any answer...

    I have a machine A that needs to communicate with two networks X and Y,
    which both have the same address range, say 10.0.9.0/24 (in fact the
    networks are more complicated and consist of many subnetworks, but I'm
    simplifying the case here). The networks must have the same address range,
    because one is a backup system for the other, so I can't change this.

    The only solution seems to create a one-to-one NAT between machine A and one
    of the networks. I connected machine A directly to network X (there is a
    dedicated IP address 10.0.9.100 for that machine on that network), and put
    another machine B between machine A and network Y which does the NAT.

    eth0 on machine B is connected to machine A and has address 192.168.200.254
    (corresponding interface of machine A has address 192.168.200.1), and eth1 is
    connected to network Y and has address 10.0.9.100.

    On machine B, iptables is doing DNATs and SNATs using a series of rules like
    the ones below (example for a single host):

    iptables -t nat -A PREROUTING -s 192.168.200.1 -d 10.0.99.1 -j DNAT --to-destination 10.0.9.1
    iptables -t nat -A POSTROUTING -s 192.168.200.1 -d 10.0.9.0/24 -j SNAT --to-source 10.0.9.100
    iptables -t nat -A PREROUTING -s 10.0.9.0/24 -d 10.0.9.100 -j DNAT --to-destination 192.168.200.1
    iptables -t nat -A POSTROUTING -s 10.0.9.1 -d 192.168.200.1 -j SNAT --to-source 10.0.99.1

    With this in effect, if machine A wants to communicate with a host 10.0.9.1
    in network Y, it connects to the address 10.0.99.1. Per routing table, this
    packet is sent to machine B. On machine B the packet is routed to 10.0.9.1
    and the source address is set to 10.0.9.100, so the destination host will
    see the connecting host's address as 10.0.9.100 and send the reply there.

    Similarly the other way - if the host 10.0.9.1 in network Y wants to
    communicate with machine A, it connects to 10.0.9.100 (which is actually
    machine B's interface connected to that network). Machine B routes the
    packet to machine A and sets the source address to 10.0.99.1 so that machine
    A will see the connecting host's address as 10.0.99.1.

    Everything works fine except - you guess of course ;) - FTP. As both
    connecting parties are unaware of the NAT, they send their real IP addresses
    in PORT commands. If - for example - 10.0.9.1 is connecting to FTP server on machine A in
    passive mode, it gets from the server a PORT command telling it to connect to
    192.168.200.1, while it would need 10.0.9.100. In active mode, the server
    gets the PORT command from the client telling the server to connect to
    10.0.9.1, while the server would need 10.0.99.1.

    I was thinking that ip_conntrack_ftp module is supposed to change the
    addresses sent in PORT commands appropriately, but even after loading
    ip_conntrack and ip_conntrack_ftp modules, nothing changes. The addresses
    are sent unchanged to the other party, so in neither passive nor active mode
    it is not possible to establish the data connection.

    What can I do to make FTP work?

    I know, at least for passive mode there is a workaround. I can set another
    IP address in the config file of the FTP server, which the server would then
    send to the clients. I have applied that and it works, but I can't consider
    this a solution, but rather only a makeshift workaround. Also, some FTP
    clients - among them, Windows built-in FTP client, which I must use in some
    cases - are not capable of using passive mode, so this workaround doesn't
    help. I'm looking for a real solution, ie. appropriate change of addresses
    on the NAT machine.
     
    Jaroslaw Rafa, May 27, 2015
    #1
    1. Advertisements

  2. Jaroslaw Rafa

    Damien Wyart Guest

    Did you consider bonding or "teaming"?
     
    Damien Wyart, May 27, 2015
    #2
    1. Advertisements

  3. Jaroslaw Rafa

    Denis Corbin Guest

    Le 27/05/2015 14:31, Jaroslaw Rafa a écrit :
    I suspect the ip_conntrack_ftp is either not loaded or you miss an
    iptable rule that allows RELATED packets.

    something like this for example with iptables (but also valid with
    ip6tables):

    iptables -N attack
    iptables -F attack
    iptables -A attack --match state --state INVALID -j DROP
    iptables -A attack -p tcp ! --syn -m state --state NEW -j DROP
    iptables -A attack --match state --state RELATED -j ACCEPT
    iptables -A attack --match state --state ESTABLISHED -j ACCEPT
    iptables -A attack --match state --state NEW -j RETURN
    iptables -A attack --match limit --limit 1/hour --limit-burst 10 -j
    LOG --log-level 2 --log-prefix "Firewall unknown state "
    iptables -A attack -j DROP

    Then you just have to filter the NEW sessions once the attack table has
    'RETURN'ed :

    iptables -A INPUT -j attack
    iptables -A INPUT -p tcp --dport ftp -j ACCEPT
    ....
    [...]

    Cheers,
    Denis.
     
    Denis Corbin, May 27, 2015
    #3
  4. Jaroslaw Rafa

    detha Guest

    I suspect ftp_conntrack can not handle the bi-directional NAT. If you
    leave the reverse rules (from Y back to A) out, it should see it as
    'normal' single NAT, and hopefully pick it up.

    Alternatively, can you make machine B the default gateway for network
    Y? Or at least add a route to 192.168.200.0/24 to 10.0.9.100, so you don't
    have to SNAT. Machine Y will see the packets as coming from 192.168.200.1,
    and reply to B.

    -d
     
    detha, May 27, 2015
    #4
  5. If I understand correctly, you are referring to rules in 'filter' table of
    the iptables here.

    I have no rules at all in the 'filter' table, as I don't need to filter
    anything - I don't need machine B to operate as a firewall, only as a NAT
    router between machine A and network Y. I'm using only the 'nat' table.

    Are you saying that I need to put some artificial rules into 'filter' table
    to make ip_conntrack_ftp work?
     
    Jaros?aw Rafa, May 29, 2015
    #5
  6. Unfortunately I can not leave out the reverse rules, and cannot make any
    changes to routing in network Y. This is actually a quite complicated
    network with lots of hosts, subnetworks and routers, that are configured
    using preset templates. It would take too much effort and be very
    error-prone to introduce additional route in each of these templates,
    especially taking into account the fact that network Y is a backup for
    network X and should have identical structure (the whole network Y can be
    simply plugged instead of network X if needed). So both network X and
    network Y must see the machine A as 10.0.9.100, and should not be aware if
    there is anything "behind" 10.0.9.100.
     
    Jaros?aw Rafa, May 29, 2015
    #6
  7. What do you have in mind exactly?

    There are duplicate IP addresses in both networks. Almost all addresses are
    duplicate, I already said that network Y is a backup for network X. So for
    example I have 10.0.9.1 in network X and in network Y. How bonding is
    supposed to handle this?
     
    Jaros?aw Rafa, May 29, 2015
    #7
  8. Jaroslaw Rafa

    Denis Corbin Guest

    Le 29/05/2015 16:42, Jaros?aw Rafa a écrit :
    No, I just thought the problem could be filtering, but as you say you
    just perform NAT without filtering, I have no clew on how to solve the
    issue you meet.

    Cheers.
     
    Denis Corbin, May 29, 2015
    #8
  9. Hello,

    Jaroslaw Rafa a écrit :
    You may consider using NETMAP to simplify the needed rules.
    Err, no. The server does not send any commands, and the PORT or EPRT
    command is sent by the client to set (extended) active mode. When the
    client sets passive mode with the PASV command, the server sents its
    passive address in its reply to this command. Note that using the EPSV
    command to set extended passive mode instead of PASV if both the client
    and server support it make things easier, because the server does not
    send any address : the same address as the one used to establish the
    control connection is implied.
    No, nf_conntrack_ftp (ip_conntrack_ftp was the old name and is now an
    alias) just does the tracking of FTP connections. It does not change
    anything but the state of the SYN packet of an FTP data connection from
    NEW to RELATED. You also need to load the nf_nat_ftp module to manage
    correctly FTP connections with NAT.

    Note that these modules do not work with encrypted control connections.
    A similar workaround works for active mode if the client allows to set
    the advertised address. Passive and active modes are symmetric.
     
    Pascal Hambourg, Jun 7, 2015
    #9
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.