Page MenuHomeFreeBSD

Document IPFW's in-kernel NAT
ClosedPublic

Authored by driesm on Aug 17 2019, 3:56 PM.
Tags
None
Referenced Files
Unknown Object (File)
Sun, Apr 14, 5:42 AM
Unknown Object (File)
Sat, Apr 13, 10:24 AM
Unknown Object (File)
Dec 20 2023, 4:38 AM
Unknown Object (File)
Dec 19 2023, 9:42 PM
Unknown Object (File)
Nov 19 2023, 10:41 AM
Unknown Object (File)
Nov 19 2023, 8:51 AM
Unknown Object (File)
Nov 19 2023, 7:18 AM
Unknown Object (File)
Nov 19 2023, 7:16 AM
Subscribers

Details

Summary

Basically did a rewrite of the NAT chapter with a focus on in-kernel NAT, at the end there is still a small section documenting natd.

Test Plan

I ran igor against chapter.xml, but I can't seem to figure out how to fix the leftover alignment errors it is spitting out.
Would love if someone checks and "teaches" me what was wrong (and how I can fix it in the future).

Diff Detail

Repository
rD FreeBSD doc repository - subversion
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

en_US.ISO8859-1/books/handbook/firewalls/chapter.xml
2441 ↗(On Diff #60948)

Extra capitalizing seems to be unintended.

Thank you very much for starting this work. We really need updates to the Handbook.

There are some not-so-serious issues that can, however, complicate migration from natd to ipfw nat in practice and Handbook chapter should make it easier instead of adding more complexity:

  1. Standard scripts using standard settings in /etc/rc.conf generate ipfw ruleset using rule 50 instead of 500 and "nat 123" instead of "nat 1". To simplify learning curve we should make the Handbook more consistent with system it describes.
  1. Modern IPFW has "ipfw disable one_pass" command equivalent for sysctl net.inet.ip.fw.one_pass="0", and had it for long time. Users should be able to touch fewer files to configure IPFW and the Handbook should use "ipfw disable one_pass". This is also less cryptic to read and remember.
  1. There is more serious issue with in-kernel LIBALIAS replacement for user-land copy of libalias used with natd binary.

GENERIC kernel has no "options LIBALIAS". This option provides complete in-kernel replacement for userland libalias.

For GENERIC-based system, kernel module libalias.ko is automatically loaded by ipfw instead. However, libalias.ko does NOT provide complete replacement for userland libalias by itself. One needs to specify additional protocol helpers manually by means of /boot/loader.conf or rc.conf's kld_list variable:

alias_cuseeme.ko
alias_ftp.ko
alias_nbt.ko
alias_skinny.ko
alias_irc.ko
alias_pptp.ko
alias_smedia.ko

You won't get working FTP or PPtP etc. transit traffic aliasing otherwise if you migrate from natd to ipfw nat. Or if you setup ipfw nat initially.

The Handbook should mention this somehow.

There is also one subtle difference between "ipfw divert" command used with natd and "ipfw nat" command.

Correct NAT operations require IP fragments reassembly to be performed before passing traffic to NAT engine. ipfw(8) manual page informs: "Incoming packet fragments diverted by divert are reassembled before delivery to the socket" (see BUGS section). So, default ipfw rules generated by system guarantee fragment reassembly.

This is not a case after move to ipfw nat and one may need additional "ipfw reass" rule manually added before "ipfw nat" rule. It is mostly unneeded as TCP and some UDP-based protocols have means to prevent IP fragmentation from happening in first place. But sometimes it is needed if system routinely processes other types of IP packets like IPSEC/ESP/GRE tunneling other IP packets. Sometimes encapsulation leads to oversized and therefore fragmented traffic.

Thanks for the feedback Eugen, that will take a bit more time to restructure / add some of your comments.

I have one remark regarding 1), rc.firewall creates the NAT rule at number 50, although I think the example in the handbook and the ruleset rc.firewall creates are different. rc.firewall only has one NAT rule and does not have all stateful rules. So I don't feel too strong about renumbering the existing ruleset in the handbook just to match the NAT rule at number 50. Renaming the nat instance from 1 -> 123 is quickly done. Thoughts?

In D21306#464409, @driesm.michiels_gmail.com wrote:

Thanks for the feedback Eugen, that will take a bit more time to restructure / add some of your comments.

I have one remark regarding 1), rc.firewall creates the NAT rule at number 50, although I think the example in the handbook and the ruleset rc.firewall creates are different. rc.firewall only has one NAT rule and does not have all stateful rules. So I don't feel too strong about renumbering the existing ruleset in the handbook just to match the NAT rule at number 50.

There is nothing wrong with extended examples in Handbook. But we should avoid unneeded confusion for users and state is explicitly that default rule number is different. Also, please make sure your example creates no conflicts with default ruleset, e.g. it does not produce ruleset with both default rule 50 and additional ipfw nat rule. Also, rule number 500 is already in use by default ruleset, look at /etc/rc.firewall:

setup_loopback() {
        ############
        # Only in rare cases do you want to change these rules
        #
        ${fwcmd} add 100 pass all from any to any via lo0
        ${fwcmd} add 200 deny all from any to 127.0.0.0/8
        ${fwcmd} add 300 deny ip from 127.0.0.0/8 to any
        if [ $ipv6_available -eq 0 ]; then
                ${fwcmd} add 400 deny all from any to ::1
                ${fwcmd} add 500 deny all from ::1 to any
        fi
}

Thanks, I see what you mean now! :-) Let me see what I can cook up.

Address feedback. Thanks for the review!

Thanks for the update to the handbook. I've found a couple of things that are fairly easy to correct.

en_US.ISO8859-1/books/handbook/firewalls/chapter.xml
2193 ↗(On Diff #62563)

There must be a space between "with" and "<application>" and a sentence stop before the closing </para> is missing.

2270 ↗(On Diff #62563)

s/taffic/traffic/ and there are two sentence stops at the end of the line.

2288 ↗(On Diff #62563)

s/baked in/baked-in/

2308 ↗(On Diff #62563)

s/Remeber/Remember/

2381 ↗(On Diff #62563)

libalias.ko should be wrapped in <filename> tags.

2383 ↗(On Diff #62563)

s/Atlhough/Although/

2386 ↗(On Diff #62563)

s/functionalaity/functionality/

2390 ↗(On Diff #62563)

All of the .ko files in this sentence should be wrapped in <filename> tags.

2419 ↗(On Diff #62563)

This <para> needs to be on the same indentation level as the one above.

2512 ↗(On Diff #62563)

s/Lets/Let's/
generally, abbreviations like this are discouraged in the handbook, so you should use: Let us.

2515 ↗(On Diff #62563)

Sentence constructs with "in order to/for" can almost always be avoided to increase clarity and make sentences less long.

2519 ↗(On Diff #62563)

s/userpace/userspace/ and the ; at the end of daemon can also go play somewhere else... ;-)

2533 ↗(On Diff #62563)

s/also used/also be used/

Address feedback from @bcr. Thanks for the review!

firewall.rc is actually rc.firewall.

Hi guys, any more pointers or feedback? Otherwise I think this might be ready to commit :-).

Sorry to keep you waiting. I'll commit this soon. Thank you!

This revision was not accepted when it landed; it landed in state Needs Review.Oct 11 2019, 7:21 PM
This revision was automatically updated to reflect the committed changes.