📜 ⬆️ ⬇️

Overview and comparison of how to configure NAT on FreeBSD

In this article, I would like to give examples of how to configure NAT on the FreeBSD OS and to make some comparison of the methods that, in my opinion, are most often used.

To start:
NAT (from the English. Network Address Translation - "Network Address Translation") is a mechanism in TCP / IP networks that allows you to convert the IP addresses of transit packets. Also known as IP Masquerading, Network Masquerading and Native Address Translation.

Considered options:
- Demon Natd
- IPFilter (ipnat)
- PF nat
- ng_nat
- ipfw nat (kernel nat)

')
NAT with natd

From handbook:
The Network Address Translation daemon on FreeBSD, commonly known as natd (8), is a daemon that accepts incoming IP packets, changes the sender's address to the address of the local machine, and resends these packets in an outgoing packet stream. natd does this by changing the sender's IP address and port in such a way that when data is received back, it can determine the location of the source of the initial data and send it to the machine that originally requested the data.

Natd needs ipfw to work.
In the core:
# Ipfw support
options IPFIREWALL
options IPFIREWALL_VERBOSE
options "IPFIREWALL_VERBOSE_LIMIT = 100"
#DIVERT packets arriving at the interface for NAT
options IPDIVERT

Add to /etc/rc.conf
gateway_enable = "yes"
or add to /etc/sysctl.conf
net.inet.ip.forwarding = 1.

em0 - external interface
192.168.0.0/24 - internal network
200.200.200.200 - foreign address

Also in /etc/rc.conf add:
natd_enable = "YES"
natd_interface = "em0"
natd_flags = ""

In the firewall we add rules for divert:
/ sbin / ipfw add divert natd ip from 192.168.0.0/24 to any out via em0
/ sbin / ipfw add divert natd ip from any to 200.200.200.200 in via em0

Described in more detail in Hendbuk .

NAT using IPFilter (ipnat)

In the core:
options IPFILTER
options IPFILTER_LOG
or load as a module and do not touch the core.

Add to /etc/rc.conf
gateway_enable = "yes"
or add to /etc/sysctl.conf
net.inet.ip.forwarding = 1.

Also in /etc/rc.conf add:
ipnat_enable = "YES" # Turn on ipnat
ipnat_program = "/ sbin / ipnat" # Path to ipnat
Ipnat_rules = "/ etc / ipnat.rules" Rules
ipnat_flags = "" # with what parameters to start

To log in syslog.conf add:
local0. * /var/log/ipmon.log
and launch the IPFilter - ipmon operation monitoring utility with the -Dvas keys
-D - start by daemon
-v - to detail
-a - track all IPFilter devices
-s - via syslog

Examples:

If a:
em0 - external interface
192.168.0.0/24 - internal network
200.200.200.200 - foreign address

That example of rules for Nat will look like this:
map em0 from 192.168.0.0/24 to any -> 200.200.200.200/32

Or without specifying the destination address:
map em0 192.168.0.0/24 -> 200.200.200.200/32

If the address is dynamic, you can do so:
map em0 192.168.0.0/24 -> 0.0.0.0/32

Some useful commands when working with ipnat:
Reboot ipnat:
/etc/rc.d/ipnat restart
General statistics for Nat robots:
ipnat –s
The list of active rules and the list of currently active sessions:
ipnat –l
Reread config:
ipnat -CF -f /etc/ipnat.rules
-C - clears the rules table.
-F - deletes entries from the translation table.
You can learn more about ipnat and IPFilter in general from:
ipnat (1), ipnat (5), ipnat (8), ipf (5), ipf (8), ipfstat (8), ipftest (1), ipmon (8)
More details here .

NAT with pf

In the core:
device pf # Enable PF OpenBSD packet-filter firewall
device pflog # pf log support

Add to /etc/rc.conf
gateway_enable = "yes"
or add to /etc/sysctl.conf
net.inet.ip.forwarding = 1.

Also in /etc/rc.conf add:
pf_enable = "YES"
pf_rules = "/ etc / pf.conf"
pf_program = "/ sbin / pfctl"
pf_flags = ""
pflog_enable = "YES"
pflog_logfile = "/ var / log / pf.log"
pflog_program = "/ sbin / pflogd"
pflog_flags = ""

An example of the rule itself:
em0 - external interface
192.168.0.0/24 - internal network
200.200.200.200 - foreign address

In /etc/pf.conf:
nat on em0 from 192.168.0.0/24 to any -> (em0)

NAT with ng_nat

In the core:
options NETGRAPH
options NETGRAPH_IPFW
options LIBALIAS
options NETGRAPH_NAT
... and other non-graph options if necessary

Or just load the modules:
/ sbin / kldload /boot/kernel/ng_ipfw.ko
/ sbin / kldload /boot/kernel/ng_nat.ko

em0 - external interface
192.168.0.0/24 - internal network
200.200.200.200 - foreign address

Creating NAT nodes:
ngctl mkpeer ipfw: nat 60 out
ngctl name ipfw: 60 nat
ngctl connect ipfw: nat: 61 in
ngctl msg nat: setaliasaddr 200.200.200.200
Add lines to ipfw to redirect traffic to the created node:
/ sbin / ipfw add netgraph 61 all from any to 200.200.200.200 in via em0
/ sbin / ipfw add netgraph 60 all from 192.168.0.0/24 to any out via em0
Further
sysctl net.inet.ip.fw.one_pass = 0

All written to form a script and shove it in /usr/local/etc/rc.d with startup rights for autoloading.

More details here .

NAT using ipfw nat

Support for ipfw nat has appeared since FreeBSD 7.0
To the core:
options IPFIREWALL
options IPFIREWALL_DEFAULT_TO_ACCEPT
options IPFIREWALL_FORWARD
options IPFIREWALL_VERBOSE
options IPFIREWALL_VERBOSE_LIMIT = 50
options IPFIREWALL_NAT
options LIBALIAS

Add to /etc/rc.conf
firewall_enable = "YES"
firewall_nat_enable = "YES"
firewall_type = "/ etc / firewall"
gateway_enable = "YES"

In /etc/sysctl.conf add:
net.inet.ip.fw.one_pass = 1

em0 - external interface
192.168.0.0/24 - internal network
200.200.200.200 - foreign address

Example:

/ sbin / ipfw add nat 1 config log if em0 reset same_ports
/ sbin / ipfw add nat 1 ip from 192.168.0.0/24 to not table \ (10 ​​\) via em0
/ sbin / ipfw add nat 1 ip from any to 200.200.200.200 via em0
Where table 10 - does not go through nat

Some statistics can be viewed as:
ipfw nat 1 show

A bit of comparison

It should be said that ipfw, natd, ipf, ipnat get along well together. At the same time, it is necessary to remember the features of the filters: ipfw works by the first match, and ipf (without the quick option in the rule) by the last. Well, you should always keep in mind the order of passing a packet through the filters. So, if ipf support is compiled in the kernel, then no matter how ipfw is running, first of all the packets will pass through the ipf rules, and ipfw will receive only what is passed to them by input. If ipfw is built in the kernel, and ipf is loaded as a module, then ipfw will use the championship right.

If we consider the difference and features, we can note the following:

Natd:
- Dying becomes ineffective when traffic exceeds 40-50 megabits
- Realization in the form of a demon
- Difficulties when working on multiple interfaces
+ Easy to set up
+ Functionality, flexibility

Ipnat:
+ Easy to set up
+ Proximity to the core
- At very high loads need tuning


ng_nat:
- Relatively complex setup
- Cannot redirect_port
+ Implemented through libalias in the kernel.
+ Consumes relatively few resources

Ipfw nat:
+ Work speed
+ Flexibility
+ Implemented through libalias in the kernel.
UPD from nightfly :
- impossibility is normal without a ton of aliases to natit from under the pool
- vague statistics
+ finally stopped flowing
+ Unlike others, an active FTP from a box can do that allows you not to keep a proxy FTP near
+ does not suffer from childhood diseases such as jokes with simultaneous pptp through nat

Pf nat:
+ Work speed
+ Use macros to write rules
- Problems with smp

findings

I will not mention any of the above options due to the fact that the topic is a bit holivar, and the opinions of readers may not coincide with mine. I just tried to describe configuration examples and make some comparison of the many methods of NAT organization on FreeBSD OS. Also, I did not begin to describe the materiel on NAT, because it is here .

Source: https://habr.com/ru/post/111580/


All Articles