Построение межсетевого экрана на коммутируемом канале связи при помощи FreeBSD

$Date$

Эта статья описывает, как настроить межсетевой экран при помощи возможностей PPP по работе на коммутируемом канале связи с FreeBSD и IPFW, и, в частности, описывается настройка межсетевого экрана при использовании коммутируемого канала связи с динамически выделяемым адресом IP. Этот документ не описывает начальную настройку PPP-соединения.


1. Введение

Построение межсетевого экрана на коммутируемом канале связи при помощи FreeBSD

Этот документ предназначен для того, чтобы описать действия, требуемые для настройки межсетевого экрана при помощи FreeBSD в случае, когда IP-адрес выделяется динамически вашим провайдером. Хотя прилагались все усилия для того, чтобы сделать этот документ максимально информативным и правильным, все же присылайте свои комментарии и пожелания составителю.


2. Параметры ядра

Прежде всего вам нужно перекомпилировать ваше ядро FreeBSD. Если вам нужна более подробная информация о том, как это сделать, то лучше всего начать с раздела Руководства о конфигурации ядра. Вам нужно включить в ядро следующие параметры:

options IPFIREWALL

Включает межсетевой экран в ядре.

options IPFIREWALL_VERBOSE

Посылает сообщения о журналируемых пакетах в системный журнал.

options IPFIREWALL_VERBOSE_LIMIT=100

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

options IPDIVERT

Включает использование перенаправляющих сокетов, что будет показано ниже.

Имеется также еще несколько НЕОБЯЗАТЕЛЬНЫХ параметров, которые вы можете указать в ядре для достижения дополнительной безопасности. Для работы межсетевого экрана этого не требуется, но некоторые параноидально настроенные пользователи могут все же ими воспользоваться.

options TCP_RESTRICT_RST

Этот параметр блокирует все пакеты TCP RST. Это лучше использовать в системах, которые могут подвергаться флуд-атакам SYN (хорошим примером являются серверы IRC) или теми, кто не хочет быть легко подвергнутым сканированию портов.

options TCP_DROP_SYNFIN

При использовании этого параметра TCP-пакеты с полями SYN и FIN игнорируются. Это позволит избежать распознавания используемого на машине типа стека такими утилитами, как nmap, но при этом нельзя будет использовать расширения RFC1644. Если на машине будет работать веб-сервер, делать это НЕ рекомендуется.

Не перезагружайте машину сразу же после перекомпиляции ядра. Для завершения настройки межсетевого экрана нам, к счастью, достаточно будет выполнить перезагрузку всего один раз .


3. Изменение /etc/rc.conf для загрузки межсетевого экрана

Теперь нам нужно внести некоторые изменения в файл /etc/rc.conf для того, чтобы указать о включении межсетевого экрана. Просто добавьте следующие строки:

firewall_enable="YES"
firewall_script="/etc/firewall/fwrules"
natd_enable="YES"
natd_interface="tun0"
natd_flags="-dynamic"
 

Для получения более полной информации о том, что делают эти строки, взгляните на содержимое файла /etc/defaults/rc.conf и прочтите rc.conf(5)


4. Выключение механизма преобразования сетевых адресов в PPP

Может, вы уже используете встроенный в PPP механизм преобразования сетевых адресов (NAT). Если это ваш случай, то вам нужно это выключить, так как в этих примерах для тех же самых целей используется natd(8).

Если у вас уже есть блок директив для автоматического запуска PPP, то он, скорее всего, выглядит примерно так:

ppp_enable="YES"
ppp_mode="auto"
ppp_nat="YES"
ppp_profile="profile"
 

Если это так, то удалите строчку ppp_nat="YES". Вам также потребуется удалить все строчки nat enable yes и alias enable yes в файле /etc/ppp/ppp.conf.


5. Набор правил для межсетевого экрана

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

Теперь создадим каталог /etc/firewall. Перейдите в этот каталог и отредактируйте файл fwrules, который мы указали в rc.conf. Пожалуйста, отметьте, что вы можете изменить это имя на любое другое. В этом руководстве имя файла дается в качестве примера.

Давайте взглянем на пример файла для межсетевого экрана, и подробно опишем его содержимое.

# Firewall rules
# Written by Marc Silver (marcs@draenor.org)
# http://draenor.org/ipfw
# Freely distributable 


# Define the firewall command (as in /etc/rc.firewall) for easy
# reference. Helps to make it easier to read.
fwcmd="/sbin/ipfw"

# Force a flushing of the current rules before we reload.
$fwcmd -f flush

# Divert all packets through the tunnel interface.
$fwcmd add divert natd all from any to any via tun0

# Allow all data from my network card and localhost. Make sure you
# change your network card (mine was fxp0) before you reboot. :)
$fwcmd add allow ip from any to any via lo0
$fwcmd add allow ip from any to any via fxp0

# Allow all connections that I initiate.
$fwcmd add allow tcp from any to any out xmit tun0 setup

# Once connections are made, allow them to stay open.
$fwcmd add allow tcp from any to any via tun0 established

# Everyone on the internet is allowed to connect to the following
# services on the machine. This example shows that people may connect
# to ssh and apache.
$fwcmd add allow tcp from any to any 80 setup
$fwcmd add allow tcp from any to any 22 setup

# This sends a RESET to all ident packets.
$fwcmd add reset log tcp from any to any 113 in recv tun0

# Allow outgoing DNS queries ONLY to the specified servers.
$fwcmd add allow udp from any to x.x.x.x 53 out xmit tun0

# Allow them back in with the answers... :)
$fwcmd add allow udp from x.x.x.x 53 to any in recv tun0

# Allow ICMP (for ping and traceroute to work). You may wish to
# disallow this, but I feel it suits my needs to keep them in.
$fwcmd add 65435 allow icmp from any to any

# Deny all the rest.
$fwcmd add 65435 deny log ip from any to any
 

Теперь у вас есть полнофункциональный межсетевой экран, который разрешает соединения к портам 80 и 22, и отображает в журнале все остальные попытки соединения. Теперь у вас должна успешно пройти перезагрузка и ваш межсетевой экран должен нормально заработать. Если вы обнаружите, что это не так, у вас возникнут проблемы или у вас возникнут пожелания, пожалуйста, напишите мне письмо по электронной почте.


6. Вопросы

6.1. Почему вы используете natd и ipfw, когда можно использовать встроенные фильтры ppp?
6.2. Если во внутренней сети я использую такие адреса, как 192.168.0.0, то могу ли я добавить команду типа $fwcmd add deny all from any to 192.168.0.0:255.255.0.0 via tun0 к правилам межсетевого экрана для предотвращения попыток подключиться извне к машинам во внутренней сети?
6.3. Что-то здесь неправильно. Я следовал вашим указаниям вплоть до буквы, и теперь доступ заблокирован.

6.1. Почему вы используете natd и ipfw, когда можно использовать встроенные фильтры ppp?

Скажу честно, что определенной причины, объясняющей, почему я использую ipfw и natd вместо встроенных в ppp фильтров. В результате обсуждений этого вопроса с другими людьми я пришел к мнению, что, хотя ipfw является гораздо более мощным и гибким инструментом, чем фильтры ppp, но все, что он выигрывает в широте возможностей, проигрывает в легкости настройки. Одной из причин, по которой я его использую, является то, что я предпочитаю функции межсетевого экрана, реализуемые в ядре, а не в пользовательской программе.

6.2. Если во внутренней сети я использую такие адреса, как 192.168.0.0, то могу ли я добавить команду типа $fwcmd add deny all from any to 192.168.0.0:255.255.0.0 via tun0 к правилам межсетевого экрана для предотвращения попыток подключиться извне к машинам во внутренней сети?

Простой ответ выглядит как нет. Причиной этого является то, что natd выполняет преобразования для всего трафика, перенаправляемого через устройство tun0. До тех пор, пока это так, входящие пакеты будут направляться только на динамически назначенный IP-адрес, а НЕ во внутреннюю сеть. Однако заметьте, что вы можете добавить, например, правило $fwcmd add deny all from 192.168.0.4:255.255.0.0 to any via tun0, которое будет ограничивать коммуникации хоста в вашей внутренней сети с внешним миром через межсетевой экран.

6.3. Что-то здесь неправильно. Я следовал вашим указаниям вплоть до буквы, и теперь доступ заблокирован.

В этом документе предполагается, что вы работаете с программой ppp уровня пользователя, поэтому предлагаемый набор правил работает с интерфейсом tun0, который соответствует первому соединению, делаемому утилитой ppp(8) (известной также как user-ppp). Дополнительные соединения будут использовать устройства tun1, tun2 и так далее.

Вы должны также отметить, что программа pppd(8) использует другой интерфейс, ppp0, поэтому, если вы осуществляете соединение с помощью программы pppd(8), то должны заменить tun0 на ppp0. Быстрый способ изменить правила для межсетевого экрана показан ниже. Оригинальный набор правил будет сохранен в файле fwrules_tun0.

  % cd /etc/firewall
  /etc/firewall% su
  Password:
  /etc/firewall# mv fwrules fwrules_tun0
  /etc/firewall# cat fwrules_tun0 | sed s/tun0/ppp0/g > fwrules
  

Для того, чтобы узнать, используете ли вы ppp(8) или pppd(8), вы можете посмотреть вывод команды ifconfig(8) после установки соединения. Например, для соединения, выполняемого при помощи программы pppd(8), вы увидите нечто, похожее на следующее (показаны только относящиеся к делу строчки):

  % ifconfig
  (skipped...)
  ppp0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1524
     inet xxx.xxx.xxx.xxx --> xxx.xxx.xxx.xxx netmask 0xff000000
  (skipped...)
   

С другой стороны, для соединений, выполняемых посредством ppp(8) (user-ppp), вы должны увидеть нечто вроде следующего:

  % ifconfig
  (skipped...)
  ppp0: flags=8010<POINTOPOINT,MULTICAST> mtu 1500
  (skipped...)
  tun0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1524
    (IPv6 stuff skipped...)
     inet xxx.xxx.xxx.xxx --> xxx.xxx.xxx.xxx netmask 0xffffff00
     Opened by PID xxxxx
   (skipped...)
   

Этот, и другие документы, могут быть скачаны с ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/.

По вопросам, связанным с FreeBSD, прочитайте документацию прежде чем писать в <questions@FreeBSD.org>.
По вопросам, связанным с этой документацией, пишите <doc@FreeBSD.org>.
По вопросам, связанным с русским переводом документации, пишите в рассылку <frdp@FreeBSD.org.ua>.
Информация по подписке на эту рассылку находится на сайте проекта перевода.

Обновлено: 12.03.2015