В каталоге etc мы создали скрипт rc.ipfw с правилами для ipfw.
# Объявляем, что файл является скриптом sh #!/bin/sh cmd=”ipfw –q add” # Сбрасываем все правила ipfw –q –f flush # Отправляем пакеты на наш NAT $cmd 014 divert natd ip from any to any via em1 # Разрешающее правило для всего $cmd 100 allow ip from any to any
Сейчас в этом скрипте у нас есть только одно правило, которое разрешает всё. Вряд ли такой сервер можно назвать защищенным. Нам нужно написать набор разрешающих и запрещающих правил с учетом сервисов запущенных на сервере. Все неиспользуемые порты мы закроем.
Для удобства мы создали переменную cmd и вложили в нее префикс создания правила ipfw -q add. Каждое новое правило будет начинаться с этой переменной.
Добавим еще пару переменных.
Поскольку сервер будет выполнять роль шлюза, у него будет как минимум два интерфейса. Внешний и внутренний. Назовем их LanOut и LanIn.
LanOut это внешний интерфейс, через который сервер подключается к интернету. На всякий случай я добавил комментарий с его айпи адресом. В моем случае это 192.168.73.55. Заодно закомментируем устаревшие правила.
#!/bin/sh cmd=”ipfw –q add” LanOut=”em1” # 192.168.73.55 LanIn=”em0” # 192.168.56.111 ipfw –q –f flush #$cmd 014 divert natd ip from any to any via em1 #$cmd 100 allow ip from any to any
Сделаем разрешающее правило для локальной сети.
#!/bin/sh cmd=”ipfw –q add” LanOut=”em1” # 192.168.73.55 LanIn=”em0” # 192.168.56.111 ipfw –q –f flush #$cmd 014 divert natd ip from any to any via em1 #$cmd 100 allow ip from any to any $cmd 005 allow all from any to any via $LanIn
Вставим переменную $cmd. Переменная обозначается знаком доллара в начале. Добавим порядковый номер для правила, например 005. Диапазон номеров у ipfw от 1 до 65535, нам же для всех правил хватит трёхзначной цифры. Действие будет разрешающее allow всем all от всех from any ко всем to any. И укажем, что правило действует для внутреннего интерфейса via $LanIn. Таким образом мы разрешили весь трафик внутри локальной сети. В будущем правила для локальной сети можно будет настроить более тонко.
Продолжим. Сделаем такое же правило для loopback интерфейса.
$cmd 010 allow all from any to any via lo0
Включим функции нат для входящих и исходящих пакетов используя правило divert natd.
$cmd 014 divert natd ip from any to any in via $LanOut $cmd 800 divert natd ip from any to any out via $LanOut
Правило будет почти в конце скрипта. Дадим ему номер, например, 800. На него будут посылаться все исходящие пакеты посредствам типа действий skipto. Сделаем для него переменную.
На данный момент у нас получился такой набор правил:
#!/bin/sh cmd=”ipfw –q add” LanOut=”em1” # 192.168.73.55 LanIn=”em0” # 192.168.56.111 skip="skipto 800" ipfw –q –f flush #$cmd 014 divert natd ip from any to any via em1 #$cmd 100 allow ip from any to any $cmd 005 allow all from any to any via $LanIn $cmd 014 divert natd ip from any to any in via $LanOut $cmd 800 divert natd ip from any to any out via $LanOut
Добавим разрешающее правило для всех прошедших 800 правило пакетов и отбросим все остальное.
$cmd 801 allow ip from any to any $cmd 802 deny log all from any to any
Добавим поддержку динамических правил.
#!/bin/sh cmd=”ipfw –q add” LanOut=”em1” # 192.168.73.55 LanIn=”em0” # 192.168.56.111 skip="skipto 800" ks="keep-state" ipfw –q –f flush #$cmd 014 divert natd ip from any to any via em1 #$cmd 100 allow ip from any to any $cmd 005 allow all from any to any via $LanIn $cmd 014 divert natd ip from any to any in via $LanOut $cmd 015 check-state $cmd 800 divert natd ip from any to any out via $LanOut $cmd 801 allow ip from any to any $cmd 802 deny log all from any to any
Check-state будет проверять пакет по набору динамических правил, сами правила мы добавим позже, используя ключевое слово “keep-state”. Для него мы сделали переменную.
Разрешим исходящий доступ к днс и dhcp провайдера, 53 и 67 порты соответственно. Также разрешим входящий трафик от dhcp сервера провайдера по udp протоколу. Для удобства визуально разделим в скрипте правила на 2 группы для исходящих и входящих пакетов, out и in соответственно.
#!/bin/sh cmd=”ipfw –q add” LanOut=”em1” # 192.168.73.55 LanIn=”em0” # 192.168.56.111 skip="skipto 800" ks="keep-state" ipfw –q –f flush #$cmd 014 divert natd ip from any to any via em1 #$cmd 100 allow ip from any to any $cmd 005 allow all from any to any via $LanIn $cmd 014 divert natd ip from any to any in via $LanOut $cmd 015 check-state #########################out##################### # dns & dhcp $cmd 030 $skip udp from any to 192.168.73.2 53,67 out via $LanOut $ks #########################in###################### $cmd 300 allow udp from 192.168.73.2 to any 68 in via $LanOut $ks ################################################# $cmd 800 divert natd ip from any to any out via $LanOut $cmd 801 allow ip from any to any $cmd 802 deny log all from any to any
Добавим в группу исходящих out еще пару правил.
Разрешим исходящий http и https трафик на порт 80 и 443 соответственно. Чтобы пользователи в локальной сети могли просматривать интернет страницы в браузере.
# http(s) $cmd 040 $skip tcp from any to any 80,443 out via $LanOut setup $ks
Так же стоит разрешить исходящий трафик для почты.
# mail $cmd 041 $skip tcp from any to any 25,465,110,143 out via $LanOut setup $ks
Порты 25 и 465 это SMTP протокол. 110 порт это POP3 протокол и 143 порт это IMAP протокол.
Разрешим всё для пользователя root.
# root $cmd 042 $skip tcp from me to any out via $LanOut setup $ks uid root
Разрешаем исходящий пинг.
# ping $cmd 043 $skip icmp from any to any out via $LanOut $ks
Перейдем к группе входящих in.
Запретим входящий траффик из незарегистрированных адресных пространств.
$cmd 200 deny all from 169.254.0.0/16 to any in via $LanOut $cmd 201 deny all from 127.0.0.0/8 to any in via $LanOut $cmd 202 deny all from 0.0.0.0/8 to any in via $LanOut $cmd 203 deny all from 192.0.2.0/24 to any in via $LanOut $cmd 203 deny all from 204.152.64.0/23 to any in via $LanOut $cmd 204 deny all from 224.0.0.0/3 to any in via $LanOut
Запрещаем ident и Netbios.
$cmd 205 deny tcp from any to any 113,137-139 in via $LanOut
Запрещаем опоздавшие пакеты.
$cmd 206 deny all from any to any frag in via $LanOut
Запрещаем ACK пакеты которые не совпадают с динамической таблицей правил.
$cmd 207 deny tcp from any to any established in via $LanOut
Предположим, что у нас запущен FTP сервер. Чтобы пользователи через интернет могли подключиться к нашему FTP серверу, потребуется еще одно правило. Добавим его к правилам in.
$cmd 301 allow tcp from any to me 21 in via $LanOut setup $ks
Наконец запретим все не прошедшие по условиям наших правил пакеты.
#!/bin/sh cmd=”ipfw –q add” LanOut=”em1” # 192.168.73.55 LanIn=”em0” # 192.168.56.111 skip="skipto 800" ks="keep-state" ipfw –q –f flush #$cmd 014 divert natd ip from any to any via em1 #$cmd 100 allow ip from any to any $cmd 005 allow all from any to any via $LanIn $cmd 014 divert natd ip from any to any in via $LanOut $cmd 015 check-state #########################out##################### # dns & dhcp $cmd 030 $skip udp from any to 192.168.73.2 53,67 out via $LanOut $ks # http(s) $cmd 040 $skip tcp from any to any 80,443 out via $LanOut setup $ks # mail $cmd 041 $skip tcp from any to any 25,465,110,143 out via $LanOut setup $ks # root $cmd 042 $skip tcp from me to any out via $LanOut setup $ks uid root #ping $cmd 043 $skip icmp from any to any out via $LanOut $ks #########################in###################### $cmd 200 deny all from 169.254.0.0/16 to any in via $LanOut $cmd 201 deny all from 127.0.0.0/8 to any in via $LanOut $cmd 202 deny all from 0.0.0.0/8 to any in via $LanOut $cmd 203 deny all from 192.0.2.0/24 to any in via $LanOut $cmd 203 deny all from 204.152.64.0/23 to any in via $LanOut $cmd 204 deny all from 224.0.0.0/3 to any in via $LanOut $cmd 205 deny tcp from any to any 113,137-139 in via $LanOut $cmd 206 deny all from any to any frag in via $LanOut $cmd 207 deny tcp from any to any established in via $LanOut # dhcp $cmd 300 allow udp from 192.168.73.2 to any 68 in via $LanOut $ks # ftp $cmd 301 allow tcp from any to me 21 in via $LanOut setup $ks ################################################# $cmd 400 deny log all from any to any in via $LanOut $cmd 401 deny log all from any to any out via $LanOut $cmd 800 divert natd ip from any to any out via $LanOut $cmd 801 allow ip from any to any $cmd 802 deny log all from any to any
Этого пока хватит, теперь как это работает.
С компьютера в локальной сети через браузер пользователь хочет открыть сайт. Сайт работает по протоколу http и использует 80 порт. Пакет от нашего локального пользователя попадает на сервер. Проверяется его соответствие правилам, которые заданы в ipfw. А именно, это исходящий пакет на восьмидесятый порт внешнего интерфейса. Соответствующее правило находится у нас под номером 040. В этом правиле у нас есть ключевое слово keep-state, соответственно правило попадает в динамическую таблицу “keep-state”. Кроме того, так как у нас есть skipto 800 попадаем на правило 800. Правило 800 транслирует IP адрес пакета из локального во внешний, после чего выпускает его.
Ответный пакет от внешнего сервера попадает в начало списка наших правил. В этот раз он совпадает с правилом 014 и IP адрес его пункта назначения транслируется обратно в его адрес в локальной сети. Затем он попадает на check-state и выпускается в локальную сеть.
Следующий пакет от этого компьютера из локальной сети сразу попадает в check-state и выполняет skipto 800.
Добавим строчку в rc.conf c ключами для nat.
ee /etc/rc.conf
natd_flags="-m"
Ключ «m» будет пытаться по возможности сохранить номер порта уходящих пакетов. Файл rc.conf в итоге должен выглядеть примерно так:
hostname="" ifconfig_em0="inet 192.168.56.111" ifconfig_em1="DHCP" defaultrouter="192.168.0.110" sshd_enable="YES" dumpdev="AUTO" firewall_enable="YES" firewall_script=”/etc/rc.ipfw” named_enable=”YES” gateway_enable=”YES” natd_enable=”YES” natd_intetface=”em1” natd_flags="-m"
Перезапустим ipfw и nat.
service ipfw restart
Оставить комментарий