On Sun, Dec 05, 2004 at 03:22:35AM +1100, Darren Reed wrote:

> In some email I received from Grina, Peter (IT), sie wrote:
> > 
> > What are the most common causes for an increasing "bad nat" counter?  Is
> > there any troubleshooting method to help isolate the cause?
> 
> compiled in maximums being reached.
> 

In this case, the table sizes are very generous and the table limit
counters are all zero.

One interesting thing I am noticing with (ipnat -dlv), is that for some
of the translations the source is a single host, and in that case the
"ppip" (ports per ip) that is reported is zero.

Also in that case, the outbound connections in the list of active
translations always show the input source port == output source port.

This is perhaps the origin of the problem, because we are simulating
TCP plugs with IPFilter "double NAT":

        (source:dynamic port, firewall inside ip:port) --->
RDR     (source:dynamic port, outside host:outside port) --->
MAP     (firewall outside ip:dynamic port, outside host:outside port)

If we try to preserve the dynamic source port, we can get port collisions
from multiple inside clients each translated in this fashion via one or
more plugs.

The (3.4.X) code seems to not support dynamic port selection for mappings
where the source and translation IP masks are equal:

    void nat_setgroupmap(n)
    ipnat_t *n;
    {
            if (n->in_outmsk == n->in_inmsk)
                    n->in_ippip = 1;
            else if (n->in_flags & IPN_AUTOPORTMAP) {
                    n->in_ippip = ~ntohl(n->in_inmsk);
                    if (n->in_outmsk != 0xffffffff)
                            n->in_ippip /= (~ntohl(n->in_outmsk) + 1);
                    n->in_ippip++;
                    if (n->in_ippip == 0)
                            n->in_ippip = 1;
                    n->in_ppip = USABLE_PORTS / n->in_ippip;
            } else {
                    n->in_space = USABLE_PORTS * ~ntohl(n->in_outmsk);
                    n->in_nip = 0;
                    if (!(n->in_ppip = n->in_pmin))
                            n->in_ppip = 1;
                    n->in_ippip = USABLE_PORTS / n->in_ppip;
            }
    }

The rules generally look like:

    map iIF from any to dIP/32 -> 0.0.0.0/32 portmap tcp auto
    rdr oIF from any to iIP/32 port = iPort -> dIP port oPort tcp

the rules in question instead read:

    map iIF from srcIP/32 to dIP/32 -> 0.0.0.0/32 portmap tcp auto
    rdr oIF from srcIP/32 to iIP/32 port = iPort -> dIP port oPort tcp

Could this be the source of the problem? In addition to source port
collisions, there could also be traffic with an internal source address
leaving the network (unless this is already taken care of in the filter
part of the rules).

Is there a better way to define "pseudo-plugs" (for a single source
IP)? Perhaps the rules should always NAT all client, but permit access
to only the intended client? Restricting access to just one machine by
subjecting only its source address to translation may not be the right
approach...

-- 

 /"\ ASCII RIBBON                  NOTICE: If received in error,
 \ / CAMPAIGN     Victor Duchovni  please destroy and notify
  X AGAINST       IT Security,     sender. Sender does not waive
 / \ HTML MAIL    Morgan Stanley   confidentiality or privilege,
                                   and use is prohibited.

Reply via email to