FreeBSD gateway, ipfw kernel NAT, portforward

 

Начиная с версии FreeBSD 7.0 имеется возможность реализации NAT используя возможности ядра системы не прибегая к помощи приложений пользовательского уровня (natd) или разработок родственных систем (например pf из OpenBSD), а обойтись только родным ipfw.

Очевидно превосходство такого метода по крайней мере над natd. Сокращение задержек пакетов данных заметно даже на несущественно загруженных узлах, что называется "на глазок".

Подготовка.

В поставляемом с дистрибутивом системы ядре GENERIC возможность kernel_NAT отключена.
Кроме того были обнаружены некоторые неочевидные ограничения на возможности конфигурирования системы которые могут при эксплуатации вызвать ошибки.

Настройка ядра.

Добавте следующие строки в конфигурационный файл ядра:

        options         IPFIREWALL
        options         IPFIREWALL_NAT
        options         LIBALIAS

Kernel_NAT будет возможен только при включении IPFIREWALL в ядро, но не отдельным модулем.

Правка исходных текстов.

Отредактируйте файл /usr/src/sys/netinet/ip_fw.h

--- /usr/src/sys/netinet/ip_fw.h        2010-04-19 17:18:43.000000000 +0400
+++ /home/user/ip_fw.h  2009-10-25 04:10:29.000000000 +0300
@@ -380,7 +380,7 @@
 };
 #endif
 
-#define NAT_BUF_LEN     1024
+#define NAT_BUF_LEN     11264
 
 #ifdef IPFW_INTERNAL
 /* Nat configuration data struct. */

Изменение NAT_BUF_LEN позволяет принимать более длинные строки с параметрами.

Вы можете не производить эту правку исходников, однако, однажды можете столкнуться с тем, что ipfw выдаст подобную ошибку:

ipfw: getsockopt(IP_FW_GET_CONFIG): No space left on device

или

ipfw: redirect_port: buf is too small

Наладка.

Выполните:

cd /usr/src/include
make install

Откомпилируйте и установите новое ядро.

Откомпилируйте и установите утилиту ipfw:

cd /usr/src/sbin/ipfw
make install clean

Использование.

Предположим ваш шлюз управляет двумя линками на интерфейсах re0 и re1 на первом из них должен работать NAT, а второй соответственно обращён в вашу локальную сеть с адресным пространством 192.168.0.0/24

Отредактируйте файл /etc/rc.conf, добавив следующие строки:

firewall_enable="YES"
firewall_type="open"
firewall_nat_enable="YES"
firewall_nat_interface="re0"
firewall_nat_flags="unreg_only same_ports \
redirect_port tcp 192.168.0.10:3389 3001 \
redirect_port tcp 192.168.0.11:3389 3002"

Очевидно, что строка redirect_port tcp 192.168.0.10:3389 3001 позволяет входящее соединение на порт 3001 перенаправить на узел в локальной сети 192.168.0.10 и его tcp порт 3389.

/etc/netstart