Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 9 Mar 2016 15:02:18 -0800 (PST)
From:      Don Lewis <>
Subject:   Re: ipwf dummynet vs. kernel NAT and firewall rules
Message-ID:  <>

Next in thread | Raw E-Mail | Index | Archive | Help
On  9 Mar, Don Lewis wrote:
> On  9 Mar, Don Lewis wrote:
>> On  9 Mar, Don Lewis wrote:
>>> On  9 Mar, Freddie Cash wrote:
>>>> ?Do you have the sysctl net.inet.ip.fw.one_pass set to 0 or 1?
>>> Aha, I've got it set to 1.
>>>> If set to 1, the a dummynet match ends the trip through the rules, and the
>>>> packet never gets to the NAT rules.  Or, if a NAT rule matches, the trip
>>>> through the rules ends, and it never get to the dummynet rules.  Depending
>>>> on which you have first.
>>> Dummynet is first.
>>>> You'll need to set net.inet.ip.fw.one_pass?=0 in order to re-inject the
>>>> packet into the rules after it matches a dummynet or NAT rule.  Or, do the
>>>> NAT and dummynet rules on different interfaces to match different traffic.
>>> How do I prevent the re-injected packets from being sent back into
>>> dummynet?  My NAT rule looks like it could have the same problem, but
>>> that looks fixable.
>> I just read the fine man page and is says that after re-injection the
>> packet starts with the next rule ... cool!
> Ignoring dummynet for a moment since I haven't added those rules back
> ... DNS lookups break when I set net.inet.ip.fw.one_pass=0.  This
> machine is running BIND as a DNS forwarder and I have this rule to
> allow DNS lookups in and out:
>   pass udp from me to any 53 out via re0 keep-state
> If BIND has the results of a lookup cached, then I get the expected
> query results from an internal host when I set
> net.inet.ip.fw.one_pass=0, but if the results are not cached I get
> ";; connection timed out; no servers could be reached" when I do a
> lookup on an internal host, and running the query on the firewall
> machine also does not work.  If BIND has the query cached, I am able
> to download from servers on the internet to an internal host, so that
> indicates that NAT is functioning, but it shouldn't be involved in DNS
> lookups.

It looks like the problem was an interaction between
net.inet.ip.fw.one_pass, my NAT rules, and my keep-state rules.  My nat
rule was:
  nat 123 ip4 from any to any via re0
so it was matching by outgoing DNS queries even though they didn't need
to be NATed.  I think that when net.inet.ip.fw.one_pass=1, the DNS
queries were totally being handled by NAT and not using the keep-state
rule at all.  I'm wondering if net.inet.ip.fw.one_pass=0 was interfering
with setting the ipfw dynamic state and the response packet was getting
blocked after it was reinjected by NAT.

In any case, changing my NAT rules to this make things work:

  nat 123 ip4 from internal/24 to any out xmit re0
  nat 123 ip4 from any to me in recv re0

The "me" in the second rule should really be the address of re0, but
that's not readily available.

Want to link to this message? Use this URL: <>