Avoiding DROP in iptables nat.POSTROUTING when SNAT is involved

Discussion in 'Linux Networking' started by Andrew Gideon, Feb 19, 2013.

  1. In upgrading some boxes that are using iptables to SNAT routed traffic, I
    am hitting the:

    The "nat" table is not intended for filtering, the use of DROP is
    therefore inhibited.

    restriction. But I'm not sure how to achieve what I want w/o it.

    The ruleset I want to implement prevents outbound traffic with an improper
    source IP - one that doesn't belong to my network. As I understand it, I
    am *supposed* to do this in the filter table. That would be fine
    normally, but a check of the source IP cannot reliably be performed in the
    filter table. The problem is that an invalid source IP as of filter can
    be SNATed into validity by nat.POSTROUTING which runs after
    filter.FORWARD.

    So...how can one reliably filter packets for invalid source IPs without
    checking after nat.POSTROUTING? Or is there some way to do additional
    filtering after nat.POSTROUTING runs? I am currently under the impression
    that nat.POSTROUTING is the final ruleset to run before a packet departs.

    Thanks...

    Andrew
     
    Andrew Gideon, Feb 19, 2013
    #1
    1. Advertisements

  2. Hello,

    Andrew Gideon a écrit :
    You know what SNAT rules you have in nat.POSTROUTING. So you know what
    packets in filter.FORWARD will be SNATed or already have a valid source
    address. You can create filtering rules which match the same packets as
    the SNAT rules but with the ACCEPT target instead of SNAT.
    Correct.
     
    Pascal Hambourg, Feb 21, 2013
    #2
    1. Advertisements

  3. I deliberately avoid this right now for a couple of reasons.

    First, this means that any given expression that SNAT is occurring must be
    implemented twice. Redundancy of this sort is never a good thing; it
    means that two different but effectively identical sets of rules need to
    be maintained.

    [This might not be so bad were there a way to share rulesets over tables,
    but - at least as far as I know - there is not.]

    Second, this presumes that the rules are perfect. That is, if I err
    somehow in filter.FORWARD such that a packet that should be either blocked
    or SNATed is not, then the duplicated logic in nat.POSTROUTING will have
    the same error. Right now, I avoid this by having as final rules in the
    nat.POSTROUTING ruleset some very simple (and therefore tough to get wrong
    {8^) logic which blocks anything I might have previously missed.

    I usually do pretty well by assuming that I'm less than perfect. It seems
    like a mistake waiting to happen to depend upon always getting something -
    even just a little complex - correct.

    I'm thinking that the only solution that's really guaranteed to avoid
    leaking packets with bad source IPs is to have nat.POSTROUTING SNAT
    anything with a bad source IP. The presumption would be that
    filter.FORWARD would have only permitted what's desired.

    This avoids the possibility of leaking, but it doesn't provide any check
    against errors on my part.

    Am I missing something?

    - Andrew
     
    Andrew Gideon, Feb 21, 2013
    #3
  4. Andrew Gideon

    Ken Sims Guest

    Hi Andrew -

    That's what I do.

    In my nat.POSTROUTING, I have two rules. (Actually I have more, left
    over from when I had multiple internet connections. But only two
    matter.)

    The first ... if the output interface is my internet interface and if
    the destination IP address is 192.168.100.1 (the cablemodem's internal
    IP address), SNAT to 192.168.100.2. This allows me to easily connect
    into the cablemodem's software.

    The second ... if the output interface is my internet interface, SNAT
    to my static internet IP address.
     
    Ken Sims, Feb 22, 2013
    #4
  5. Andrew Gideon a écrit :
    Redundancy of this sort is common with NAT however. For example when you
    do port forwarding (destination NAT), you need one DNAT rule in
    nat.PREROUTING and one ACCEPT rule in filter.FORWARD for the final
    destination. Why would it be different with source NAT ?

    You can make it easier by keeping the two rules together in the script,
    or using functions which create both rules based on the same parameters.
    Or you can mark packets and apply multiple operations in different
    tables and chains to packets with a given mark.
    There is nothing specific in your case. Wrong rules always result in
    packets being incorrectly processed... Deal with it, as all people who
    write rulesets do. After writing or modifying a ruleset, you must test it.
    That is not even true. Not all outgoing packets pass through
    nat.POSTROUTING. The nat table chains see only (but not all) packets in
    the state NEW. Packet is in any other state skip the nat table chains.
    This the reason why filtering in this table is not reliable.
     
    Pascal Hambourg, Feb 23, 2013
    #5
  6. Andrew Gideon

    Ken Sims Guest

    Hi Pascal -

    It wouldn't have to be that redundant. You can DNAT specific ports to
    specific IP addresses (such as to different servers in a DMZ), but
    ACCEPT everything being FORWARDed to those IP addresses.
     
    Ken Sims, Feb 23, 2013
    #6
    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.