Bug 201448 - [IPFW] keep-state and in-kernel NAT exposes local ip on external interface
Summary: [IPFW] keep-state and in-kernel NAT exposes local ip on external interface
Status: New
Alias: None
Product: Documentation
Classification: Unclassified
Component: Books & Articles (show other bugs)
Version: Latest
Hardware: amd64 Any
: --- Affects Only Me
Assignee: freebsd-doc (Nobody)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2015-07-10 00:19 UTC by g_amanakis
Modified: 2015-07-22 23:40 UTC (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description g_amanakis 2015-07-10 00:19:46 UTC
According to the example of the handbook regarding NAT (https://www.freebsd.org/doc/handbook/firewalls-ipfw.html), the inbound NAT rule should be placed first (below 0400) followed by the outbound NAT rule (below 24000)

-------8<--------
ipfw nat 123 config ip xxx.xxx.xxx.xxx same_ports reset

00100 reass ip from any to any in
00200 allow ip from any to any via lo0
00300 allow ip from any to any via em1
00400 nat 123 ip from any to any in recv em0
00500 check-state
00600 skipto 24000 ip from any to me dst-port 80,443,22,500,4500,1194,993,8112 in recv em0 keep-state
00700 skipto 24000 ip from any to any out xmit em0 keep-state
00800 deny log ip from any to any
24000 nat 123 ip from any to any out xmit em0
24100 allow ip from any to any
-------8<--------

However this allows some packets to escape NAT (why?) and IPs on the LAN (behind NAT) are exposed on the external interface (where NAT is performed).

When one places the NAT rules with the opposite order (i.e. outbound rule first and then the inbound rule) the problem disappears.

-------8<--------
    ipfw nat 123 config ip xxx.xxx.xxx.xxx same_ports reset

    00100 reass ip from any to any in
    00200 allow ip from any to any via lo0
    00300 allow ip from any to any via em1
    00400 nat 123 ip from any to any out xmit em0
    00500 check-state
    00600 skipto 24000 ip from any to me dst-port 80,443,22,500,4500,1194,993,8112 in recv em0 keep-state
    00700 skipto 24000 ip from any to any out xmit em0 keep-state
    00800 deny log ip from any to any
    24000 nat 123 ip from any to any in recv em0
    24100 allow ip from any to any
-------8<--------

See https://forums.freebsd.org/threads/ipfw-keep-state-and-in-kernel-nat-exposes-local-ip-on-external-interface.52134/
Comment 1 dlegrand 2015-07-11 06:14:12 UTC
You're not alone.
I got the same problem for months.
See https://forums.freebsd.org/threads/some-ip-frames-not-nated-with-ipfw-natd.51015/ for more information.
Comment 2 g_amanakis 2015-07-12 16:47:56 UTC
(In reply to dlegrand from comment #1)
Could you confirm that reversing the NAT rules resolves the issue for you?
Comment 3 dlegrand 2015-07-14 08:57:53 UTC
(In reply to g_amanakis@yahoo.com from comment #2)

I've done the changes you proposed, and there is no more IP packet not nated.
But I don't think there is an error in the handbook for the intended purpose in the NAT section. If the outbound traffic is aliased before checking rules in your IPFW rules file, you can't check on LAN private IP because the private IP is replaced with your public IP. This is why we are using 'skipto' to do outbound aliasing after the check on private IP.

I think there is something wrong with IPFW + NAT, but the handbook seems OK.
Comment 4 g_amanakis 2015-07-22 23:40:05 UTC
(In reply to dlegrand from comment #3)
You are definitely right. See PR 201590.
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=201590