Маршрутизатор (Router) и Файервол (Firewall) на FreeBSD x.x штатными средствами — natd и ipfw

Как гласит второе правило нормального системного админа — «Нет ничего лучше и надежнее штатных программ, если они решают поставленные задачи!».

Про первое правило напомню  тем, кто забыл — «Работает!, не трогай и во время смазывай!»

Тема статейки избитая донельзя, но когда надо что-то похожее поднять в работу, ничего путнего найти почему-то не получается. То уже устарело наглухо, то написано — не разобрать, то сказано «А», а про «Б» забыли, в общем решил сам наваять, такую важную на любом предприятии или месте где нужно надежно раздать инет на непонятное множество компутеров, статью. Все в голове не удержишь, а когда надо можно подглядеть сюда. Поэтому решил оформить статейку в виде готового руководства к действию.

Пользоваться, как понятно из преамбулы, будем естественно только штатными средствами, такими как:
1. демон NAT — natd;
2. Родной файервол — ipfw v.2
3. Самая надежная и непрожорливая до аппаратных ресурсов ОС — FreeBSD.
Версию ОС возьмем последнюю  9-ую, дабы актуальность статьи была самой длительной, хотя  все действия будут аналогичны хоть для 8, хоть для 7, хоть для 6.

Теперь, после постановки задачи и средств при помощи которых мы ее будем решать, необходимо расписать по пунктам как к этому решению будем добираться.  По простому, чтобы не запутаться надо составить план злодействий.

1. Первое, что необходимо, это установка ОС на что-нибудь аппаратное с двумя физическими сетевыми интерфейсами (сетевыми картами). Как это сделать, можно порыть здесь Установка FreeBSD 9.0 на зеркало Gmirror
и здесь Установка руками FreeBSD 8.x на раздел/зеркало с ZFS. Можно также прогуглить яндекс.

2. Затем рекомендую обновить исходные коды ОС и портов до последних стабильных. Как, смотрим тут Обновление портов и исходников FreeBSD 8.x используя CSUP.

3. Крайне рекомендую пересобрать ядро ОС с включением файервола ipfw и других необходимых опций в него по умолчанию. Как енто сделать, можно подрыть тут Сборка ядра (Kernel), а также разные опции (OPTION) и устройства (device) ядра для FreeBSD 8 – *.

4. Непосредственно сконфигурировать ОС под работу демонов. Чем собственно и займемся дальше, об этом сейчас и начнется речь:

Раскрываем 4 пункт, при условии, что первые три уже выполнены и Вы находитесь в локальной консоли непосредственно за клавиатурой и монитором (рекомендованные пункты выполнять не обязательно, но очень рекомендовано для оптимизации потребления ресурсов):

1. подключить интернет к одному из сетевых интерфейсов выбранным Вами способом. Самый одеяльный вариант — это тупо статический адрес со всеми реквизитами для конфигурации сети. Но на практике обычно это либо pppoe, либо VPN pptp, l2tp. В первом случае все можно просто и легко настроить через ppp-клиента (/etc/ppp/ppp.conf), во втором придется конкретно пошурупить мозгом и провайдером, чтобы поймать подключение, здесь можно воспользоваться например mpd5 (есть в портах). Последний вариант на практике самый сложно реализуемый, глючный и часто падающий.

2. Подключить локальную сеть  с явным пониманием какой сетью IP адресов Вы будете в ней пользоваться, какие статические локальные адреса кому назначены и т. п.

3. Конфигурим подключение по локальной сети и подключение к провайдеру инета.

Для того, чтобы это сделать, нужно определить соответствующие названия устройств сетевых карт и что к ним подключено. Это должно быть уяснено еще на этапе сборки ядра, там Вы должны были поубирать лишние драйвера сетевых карт. Просим вывод ifconfig и смотрим что у нас есть:

router# ifconfig
rl0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
options=3808<VLAN_MTU,WOL_UCAST,WOL_MCAST,WOL_MAGIC>
ether 00:50:22:39:5a:37
inet 0.0.0.0 netmask 0xffffff00 broadcast 0.0.0.0
media: Ethernet autoselect (100baseTX <full-duplex>)
status: active
rl1: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
options=3808<VLAN_MTU,WOL_UCAST,WOL_MCAST,WOL_MAGIC>
ether 00:0d:61:46:c7:b7
inet 0.0.0.0 netmask 0xffffff00 broadcast 0.0.0.0
media: Ethernet autoselect (100baseTX <full-duplex>)
status: active
plip0: flags=8810<POINTOPOINT,SIMPLEX,MULTICAST> metric 0 mtu 1500
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> metric 0 mtu 16384
options=3<RXCSUM,TXCSUM>
inet6 fe80::1%lo0 prefixlen 64 scopeid 0x5
inet6 ::1 prefixlen 128
inet 127.0.0.1 netmask 0xff000000
nd6 options=3<PERFORMNUD,ACCEPT_RTADV>
...............................

В моем случае тут две сетевые карты rl0 и rl1, обе на довольно неплохом чипе Realtek 8139D по цене 150 рэ за штуку в базарный день. Чтобы понять, что куда подключено, нужно просто выдернуть из сетевой карты кабель, например локалки и повторно вывести эту команду. На одном из интерфейсов в строке status: будет значение «no carier» вместо «active». У нас это вышло на интерфейсе rl1, следовательно локальная сеть подключена к этому интерфейсу, а провайдер к rl0. Крайне рекомендую на системнике сверху четко написать, например так rl0 — WAN, rl1 — LAN. На подходящих кабелях скотчем примотать бумажки с указанием: что это и откуда, например «WAN-inet 89.107.88.256/29 провайдер Имя провайдера». Для внятности обсуждения нарисовал вот такую картинку

Далее назначаем rl1 необходимые реквизиты сети например ip 192.168.5.1 маску 255.255.255.0.
Интерфейсу rl0 смотрящего в провайдера также назначаем выданные им ip и маску в случае обычного статического подключения по ethernet.
Если подключение идет через DSL модем, то тогда нужно сконфигурить ip адрес интерфейса rl0 на 192.168.1.2 например, а на модеме ip адрес LAN интерфейса назначить 192.168.1.1. Для DSL это можно вообще не делать, но лучше сконфигурить, будет можно управлять модемом через его LAN порт без отключения с любого хоста в локальной сети по набору в брАузере http://192.168.1.1.
Конфигурирование ip адресов и масок интерфейсов лучше делать на постоянку через /etc/rc.conf

router# ee /etc/rc.conf
#Ко всему прочему дописываем либо корректируем уже существующие строки
hostname="router.net.local"
ifconfig_rl1="inet 192.168.5.1  netmask 255.255.255.0"
# rl0 если чистая статика конфигурим на реквизиты выданные провайдером, если DSL или просто pppoe то, тогда как тут
ifconfig_rl0="inet 192.168.1.2  netmask 255.255.255.0"

Локальную сеть вроде бы отконфигурили, а вот с подключением к инету еще не все. Идем в файл /etc/resolv.conf, если его нет, создаем его и прописываем DNS сервера.

router# ee /etc/resolv.conf
#Если есть DNS server внутри локальной сети, указываем его первым например у него адрес 192.168.5.2
nameserver 192.168.5.2
#DNS сервера выданные провайдером
nameserver 212.16.193.34
nameserver 212.16.215.234

Теперь настройки разделятся для статичного чистого IP адреса и для подключения по pppoe.
Для чистой статики по ethernet в rc.conf указываем следующее

gateway_enable="YES"
# IP адрес шлюза, выданный провайдером
defaultrouter="89.107.88.хх"

При статичном подключении для получения инета на этой машине больше ничего настраивать не нужно, чего не скажешь про DSL или просто pppoe.
Для ppppoe конфигурим ppp-клиента. В /etc/rc.conf пишем:

gateway_enable="YES"
defaultroute_delay="30"
ppp_enable="YES"
ppp_mode="ddial"
ppp_nat="NO"
ppp_profile="provider"

Первая строка gateway_enable=»YES» говорит машине, что она теперь шлюз и должна работать базой по перевалке пакетов между вашими и нашими.
defaultrouter=»89.107.88.хх» — добавляет в таблицу маршрутизации маршрут по умолчанию, аналог команды «route add net default 89.107.88.хх», вместо default можно написать 0.0.0.0/0 — Это тоже самое. Значением этого параметра должен быть ip адрес, являющийся шлюзом в (локальной) сети провайдера. Выдается он вместе с другими реквизитами подключения, провайдером.
Во втором случае его нет, потому что ррр-клиент сам добавляет маршрут по умолчанию при создании сессии рррое.
Строки начинающиеся на ррр_ конфигурят клиента ppp, т. е. как ему работать. У клиента ррр есть свой NAT внутри него реализованный, но мы им пользоваться не будем, потому как хотим все через natd, поэтому отказываемся от него строкой ppp_nat=»NO». При прогрузке машины, часто оказывается так, что сессия рррое не успела еще подняться и маршрут по умолчанию не прикрутился, а система уже во всю орет что дефолтного маршрута нету. Так вот чтобы она раньше времени не кипишила, есть в конфиге такая строка defaultroute_delay=»30″, которая дает 30-ти секундную задержку на появление дефолтного маршрута.
Таперича чешем настраивать поднятие клиента ррр в /etc/ppp/ppp.conf. Там собстна и наваяем куда создавать подключение по pppoe, какие имена пароли и прочие подобные параметры какие есть необходимость указать.

router# eet /etc/ppp/ppp.conf
#################################################################
# PPP Configuration File
# created by rudkovskij.pv
# # $FreeBSD: src/etc/ppp/ppp.conf,v 1.11.2.2.2.1 2010/06/14 02:09:06 kensmith Exp $
#################################################################

default:
set log Phase tun command
set ifaddr 0.0.0.0/0 0.0.0.0/0

vtc:
set device PPPoE:rl0
set authname ***LOGIN***************************
set authkey ****PASSWORD***********************
set dial
set login
disable ipv6cp
enable lqr echo
set reconnect 3 5
set redial 3 10
set lqrperiod 45
add default HISADDR

Подключения конфиг, абсолютно типичен для большинства провайдеров, за исключением механизма lqr.
Теперь нужно перегрузить маршруттер и посмотреть лог прогрузки в консоли, если есть ошибки — исправить.

router# shutdown -r now
# или просто
router# reboot

Если чего-то не пошло, можно почитать типичные проблемы с ррр тута.


Link Quality Reporting (LQR) — крайне незаменимая вещь для отслеживания живости канала рррое. Очень часто бывает при соединениях по типу DSL, что сам канал остается поднятым, а пакеты ни туды ни сюды бегать не хотять, т.е. подключение просто повисает. В этом случае ррр-клиент ничего не делает и делать не будет, потому как ему кажется что все ровно, раз соединение и виртуальный интерфейс (tun) поднят. У меня такая ботва очень часто проявлялась на подключении DSL у Дальмрази (ныне Ростелеком). Тогда этой проблемой и озадачился, начал выискивать механизм, который мог бы понимать, что пакеты не ходят и при помощи простого скрипта рвать подключение внаглую, а затем его также беспардонно подымать. Каково было мое удивление, када я после недельного глубокого изучения этой проблемы, нашел решение в самом ррр-клиенте =) — это и есть lqr.

Работает эта штука примерно так. На внешний(ие) DNS ip адрес(а) по времени указанному в lqr_period каждые 45 секунд посылается эхо запрос. Ответ получен сидим и работаем ровно, если нет, подключение гасится (tun0 умирает) и подымается заново принудительно. До реализации такого вот механизма дергали постоянно, что инета нету, ныли, доставали. Но как только прикрутил lqr, сразу же перестали теребить постоянно, уже почти 4 года радуюсь =).
Будем надеяться, что инет на машине у Вас появился, проверить сей факт довольно просто.
Если ядро собрали с ipfw, то убедитесь, что есть разрешающие правила.

router# ipfw show
100      4983020   457392839 allow ip from any to any
65535  2955818   886049092 deny ip from any to any

Если файер пока не настроен, можно добавить одно правило для тестирования, разрешающее хождение любых пакетов куда заблагорассудится, для того чтоб файервол пока не мешал:

router# ipfw add 10 allow ip from any to any
00010 allow ip from any to any

После выполните или nslookup ya.ru или dig google.com. Можно помучать команду ping, но обычно ее в инете режут. При нормальной работе инета на машине вылезет следующее (у меня DNS свой, локальный):

router# nslookup ya.ru
Server:         192.168.5.2
Address:        192.168.5.2#53

Non-authoritative answer:
Name:   ya.ru
Address: 213.180.204.3
Name:   ya.ru
Address: 77.88.21.3
Name:   ya.ru
Address: 87.250.250.3
Name:   ya.ru
Address: 87.250.250.203
Name:   ya.ru
Address: 87.250.251.3
Name:   ya.ru
Address: 93.158.134.3
Name:   ya.ru
Address: 93.158.134.203
Name:   ya.ru
Address: 213.180.193.3

Что ж будем считать с подачей инета (внешней маршрутизации) на наш роутер мы справились, теперь настала пора раздать инет на машины в локальной сети по адресу 192.168.5.0/24 и связь с которой, у нас осуществляется через сетевой интерфейс rl1 с ip адресом 192.168.5.1.
Для этого осталось совсем ничего — настроить natd и втемяшить два правила в файервол.
Начнем с файера ipfw. Кстати, для того чтобы пакеты могли из файера выворачиваться в natd и заворчиваться в него, надо облизательно собрать ядро с пачкой опций:
options IPFIREWALL
options IPFIREWALL_VERBOSE
options IPFIREWALL_FORWARD
options LIBMCHAIN
options LIBALIAS
options IPFIREWALL_NAT
options IPDIVERT
options DUMMYNET
Зачем, смотрите в соответствующей статье Сборка ядра (Kernel), а также разные опции (OPTION) и устройства (device) ядра для FreeBSD 8 – *

Типичный кусок конфига файервола с двумя добавленными правилами DIVERT

router# ee /etc/ipfw.conf
#!/bin/sh

ipfw="/sbin/ipfw"
# если статика чистая, здесь выданный Вам ip адрес на внешнем интерфейсе rl0, если рррое, то ip адрес на интерфейсе tun0
ext_ip="89.107.88.xxx"
# если чистая статика, то rl0, если рррое, то tun0
ext_if="tun0"
our_net="192.168.5.0/24"
int_ip="192.168.5.1"
int_if="rl1"

# Сбрасываем все правила
$ipfw -f flush

# Проверяем установившиеся динамические правила
$ipfw add check-state

#localhost
$ipfw add allow ip from any to any via lo0
$ipfw add deny ip from any to 127.0.0.1/8
$ipfw add deny ip from 127.0.0.1/8 to any

$ipfw add allow gre from any to any

#antihack
#Запрещаем ip внутренней сети на внешнем интерфейсе
$ipfw add deny ip from $our_net to any in via $ext_if
# Частные сети
$ipfw add deny ip from any to 10.0.0.0/8 in via $ext_if
$ipfw add deny ip from any to 172.16.0.0/12 in via $ext_if
#$ipfw add deny ip from any to 192.168.0.0/16 in via $ext_if
$ipfw add deny ip from any to 0.0.0.0/8 in via $ext_if
# Мочим автоконфигуреную частную сеть
$ipfw add deny ip from any to 169.254.0.0/16 in via $ext_if
# Рубаем мультикастовые рассылки
$ipfw add deny ip from any to 240.0.0.0/4 in via $ext_if
# Рубим фрагментированные ICMP
$ipfw add deny icmp from any to any frag
# Убиваем широковещательные ICMP на внешнем айфейсе
$ipfw add deny log icmp from any to 255.255.255.255 in via $ext_if
$ipfw add deny log icmp from any to 255.255.255.255 out via $ext_if

# Теперь собстннна IPFIREWALL
#******** NAT ************************************
$ipfw add divert 8668 ip from $our_net to any out via $ext_if
$ipfw add divert 8668 ip from any to $ext_ip in via $ext_if
#************************************************
# Рубим траффик от частных сетей на внешний айфейс
$ipfw add deny ip from 10.0.0.0/8 to any out via $ext_if
$ipfw add deny ip from 172.16.0.0/12 to any out via $ext_if
$ipfw add deny ip from 192.168.0.0/16 to any out via $ext_if
$ipfw add deny ip from 0.0.0.0/8 to any out via $ext_if
# Разрешаем все установившиеся соединения
$ipfw add allow tcp from any to any established

# Разрешаем траффик с внешнего IP через внешний айфейс
$ipfw add allow ip from $ext_ip to any out xmit $ext_if
#...........................................................

#httpd
$ipfw add allow tcp from any to $ext_ip 80,443 via $ext_if

#DNS, NTP
$ipfw add allow udp from any to any 53,123
$ipfw add allow udp from any 53,123 to any

#Внутренняя сеть
$ipfw add allow icmp from any to any via $int_if
$ipfw add allow ip from $our_net to $our_net via $int_if
$ipfw add allow ip from $our_net to any
$ipfw add allow ip from any to $our_net

# POP3 SMTP
$ipfw add allow ip from any  to $ext_ip 25,110 via $ext_if

#SSH
$ipfw add allow ip from 89.107.88.ххх/29 to me 22
$ipfw add allow ip from ххх.ххх.ххх.ххх/16 to me 22

#ftp
$ipfw add allow ip from any to $ext_ip 21,49152-65535 via $ext_if

Не забудьте файервол настроить при запуске системы, для этого в /etc/rc.conf вносим строки

router# ee /etc/rc.conf
.........................................................
firewall_enable="YES"
firewall_script="/etc/ipfw.conf"
.........................................................

Дальше нужно настроить natd, для этого можно воспользоваться /etc/rc.conf и все вписать туда, но при множестве опций, все же лучше свалить все в отдельный файл. Итак в /etc/rc.conf вносим:

router# ee /etc/rc.conf
.........................................................
natd_enable="YES"
natd_flags="-dynamic -f /etc/natd.conf"
# Если чистая статика, то интерфейс rl0, если рррое, то tun0
natd_interface="tun0"
.........................................................

Как видно, путь прописан к файлу /etc/natd.conf. Приведем его содержимое:

router# ee /etc/natd.conf
port 8668
same_ports yes
use_sockets yes
redirect_port tcp 192.168.5.2:3389 3389
redirect_port tcp 192.168.5.3:3389 3390
# !!!Пустая строка в конце обязательна, иначе демон не запустится!!!!

Здесь порт 8668, на котором крутится демон, в файере в правилах диверт указан именно он.
same_ports yes — использовать те же порты, что и в пакетах после их перенаправления.
use_sockets yes — использовать сокеты при работе демона.
redirect_port tcp 192.168.5.2:3389 3389 — здесь дословно: перенаправить пакеты tcp приходящие на порт 3389 внешнего интерфейса (у нас rl0/tun0) внутрь локальной сети на хост с ip адресом 192.168.5.2 и порт 3389.
redirect_port tcp 192.168.5.3:3389 3390 — та же пестня, за исключением, что пакеты будут ломиться на внешний интерфейс на порт 3390, а перенаправляться на ip адрес 192.168.5.3 с портом 3389.
Эта штука в простонародье называется — «проброс порта». В данном случае пробрасывается порт 3389 — это RDP для винды. Если пойти на порт 3389 из инета, попадешь на rdp 192.168.5.2, а если пойти из инета на порт 3390, то попадешь на rdp 192.168.5.3. Думаю пример понятен, дальше сами настрогаете пробросов сколько нужно.

Собственно как бы и все, можно все сохранить и перегрузиться, все должно работать.
При отладке могут потребоваться следующие нюансы:
/etc/netstart -«перезапустить сеть» и выполнить заново скрипт файервола. У кого проблемы с этим скриптом, его можно открыть в любом текстовом редакторе и посмотреть, что конкретно он делает.

/etc/rc.d/natd [start, stop, restart] — запустить, остановить, рестартануть скриптом демон natd.
ipfw show — показывает фактически работающие правила файера.
man tcpdump — ман по очень полезной утиле, которая может снифить все пакеты на интерфейсах с подробным логом оных, нужна обычно для отладки.
sockstat -4l — показывает запущенные демоны и процессы по факту
netstat -rn — отображает фактическую таблицу маршрутизации
ifconfig rl1 — показывает текущие настройки интерфейса rl1.

Маршрутизатор (Router) и Файервол (Firewall) на FreeBSD x.x штатными средствами — natd и ipfw: 2 комментария

  1. «/etc/netstart -перезапустить сеть и выполнить заново скрипт файервола.»
    После этого уже не нужно перезапускать natd потому, что он автоматически перезапускается вместе с фаерволлом.

  2. Абсолютно верно, но тогда нужно еще указать, что перечитывается также и большая часть /etc/rc.conf.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

CAPTCHA изображение

*