<!--
     The FreeBSD Russian Documentation Project

     $FreeBSDru: frdp/doc/ru_RU.KOI8-R/articles/dialup-firewall/article.sgml,v 1.2 2001/06/30 11:02:46 phantom Exp $

     Original revision: 1.7
-->

<!DOCTYPE article PUBLIC "-//FreeBSD//DTD DocBook V4.1-Based Extension//EN" [
<!ENTITY % man PUBLIC "-//FreeBSD//ENTITIES DocBook Manual Page Entities//EN">
%man;
]>

<article>
  <articleinfo>
    <title>Построение межсетевого экрана на коммутируемом канале связи при
      помощи FreeBSD</title>

    <authorgroup>
      <author>
	<firstname>Marc</firstname>
	<surname>Silver</surname>

	<affiliation>
	  <address><email>marcs@draenor.org</email></address>
	</affiliation>
      </author>
    </authorgroup>

    <pubdate>$FreeBSD$</pubdate>

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

  <sect1 id="preface">
    <title>Введение</title>
    
    <para>Построение межсетевого экрана на коммутируемом канале связи при
       помощи FreeBSD</para>
    
    <para>Этот документ предназначен для того, чтобы описать действия,
      требуемые для настройки межсетевого экрана при помощи FreeBSD в случае,
      когда IP-адрес выделяется динамически вашим провайдером.  Хотя
      прилагались все усилия для того, чтобы сделать этот документ максимально
      информативным и правильным, все же присылайте свои комментарии и
      пожелания <ulink
      URL="mailto:marcs@draenor.org">составителю</ulink>.</para>
   </sect1>

  <sect1 id="kernel">
    <title>Параметры ядра</title>
    
    <para>Прежде всего вам нужно перекомпилировать ваше ядро FreeBSD.  Если вам
      нужна более подробная информация о том, как это сделать, то лучше всего
      начать с <ulink
      URL="http://www.FreeBSD.org/handbook/kernelconfig.html">раздела
      Руководства о конфигурации ядра</ulink>.  Вам нужно включить в ядро
      следующие параметры:</para>

    <variablelist>
      <varlistentry>
	<term><literal>options IPFIREWALL</literal></term>

	<listitem>
	  <para>Включает межсетевой экран в ядре.</para>
	</listitem>
      </varlistentry>

      <varlistentry>
	<term><literal>options IPFIREWALL_VERBOSE</literal></term>

	<listitem>
	  <para>Посылает сообщения о журналируемых пакетах в системный
            журнал.</para>
	</listitem>
      </varlistentry>

      <varlistentry>
	<term><literal>options
	    IPFIREWALL_VERBOSE_LIMIT=<replaceable>100</replaceable></literal></term>

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

      <varlistentry>
	<term><literal>options IPDIVERT</literal></term>

	<listitem>
	  <para>Включает использование <emphasis>перенаправляющих</emphasis>
            сокетов, что будет показано ниже.</para>
	</listitem>
      </varlistentry>
    </variablelist>

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

    <variablelist>
      <varlistentry>
	<term><literal>options TCP_RESTRICT_RST</literal></term>

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

      <varlistentry>
	<term><literal>options TCP_DROP_SYNFIN</literal></term>

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

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

  <sect1 id="rcconf">
    <title>Изменение <filename>/etc/rc.conf</filename> для загрузки межсетевого
      экрана</title>
    
    <para>Теперь нам нужно внести некоторые изменения в файл
      <filename>/etc/rc.conf</filename> для того, чтобы указать о включении
      межсетевого экрана.  Просто добавьте следующие строки:</para>
    
    <programlisting>
firewall_enable="YES"
firewall_script="/etc/firewall/fwrules"
natd_enable="YES"
natd_interface="tun0"
natd_flags="-dynamic"
    </programlisting>

    <para>Для получения более полной информации о том, что делают эти строки,
      взгляните на содержимое файла <filename>/etc/defaults/rc.conf</filename>
      и прочтите &man.rc.conf.5;</para>
  </sect1>
  
  <sect1>
    <title>Выключение механизма преобразования сетевых адресов в PPP</title>
    
    <para>Может, вы уже используете встроенный в PPP механизм преобразования
      сетевых адресов (NAT).  Если это ваш случай, то вам нужно это выключить,
      так как в этих примерах для тех же самых целей используется
      &man.natd.8;.</para>

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

    <programlisting>
ppp_enable="YES"
ppp_mode="auto"
ppp_nat="YES"
ppp_profile="<replaceable>profile</replaceable>"
    </programlisting>

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

  <sect1 id="rules">
    <title>Набор правил для межсетевого экрана</title>
    
    <para>Теперь мы выполнили практически все.  Единственное, что осталось
      сделать, так это задать правила для межсетевого экрана, после чего мы
      можем выполнить перезагрузку, и межсетевой экран должен заработать.  Я
      понимаю, что в каждом конкретном случае потребуется набор правил, весьма
      отличающийся от предлагаемого.  Я всего лишь попытался написать набор
      правил, которые должны подойти большинству пользователей коммутируемого
      доступа.  Вы можете тривиально изменить их под ваши требования, взяв
      нижеследующие правила в качестве основы.  Но сначала рассмотрим основы
      закрытого межсетевого экрана.  Вы хотите запретить по умолчанию все, а
      затем открывать только то, что вам нужно.  Правила должны следовать в
      порядке, когда сначала идут разрешающие правила, а затем запрещающие.
      Полагаем, что вы добавите свои разрешающие правила, а затем все остальное
      будет запрещено. :)</para>

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

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

    <programlisting>
# 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 <replaceable>x.x.x.x</replaceable> 53 out xmit tun0

# Allow them back in with the answers...  :)
$fwcmd add allow udp from <replaceable>x.x.x.x</replaceable> 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
    </programlisting>

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

  <sect1>
    <title>Вопросы</title>
    
    <qandaset>
      <qandaentry>
	<question>
	  <para>Почему вы используете natd и ipfw, когда можно использовать
            встроенные фильтры ppp?</para>
	</question>
	
	<answer>
	  <para>Скажу честно, что определенной причины, объясняющей, почему я
            использую ipfw и natd вместо встроенных в ppp фильтров.  В
            результате обсуждений этого вопроса с другими людьми я пришел к
            мнению, что, хотя ipfw является гораздо более мощным и гибким
            инструментом, чем фильтры ppp, но все, что он выигрывает в
            широте возможностей, проигрывает в легкости настройки.  Одной из
            причин, по которой я его использую, является то, что я предпочитаю
            функции межсетевого экрана, реализуемые в ядре, а не в
            пользовательской программе.</para>
	</answer>
      </qandaentry>

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

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

      <qandaentry>
	<question>
	  <para>Что-то здесь неправильно.  Я следовал вашим указаниям вплоть до
            буквы, и теперь доступ заблокирован.</para>
        </question>

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

	  <para>Вы должны также отметить, что программа &man.pppd.8;
            использует другой интерфейс, <devicename>ppp0</devicename>,
            поэтому, если вы осуществляете соединение с помощью программы
            &man.pppd.8;, то должны заменить <devicename>tun0</devicename> на
            <devicename>ppp0</devicename>.  Быстрый способ изменить правила для
            межсетевого экрана показан ниже.  Оригинальный набор правил будет
            сохранен в файле <filename>fwrules_tun0</filename>.</para>

	  <screen>
	    &prompt.user; <userinput>cd /etc/firewall</userinput>
	    /etc/firewall&prompt.user; <userinput>su</userinput>
	    <prompt>Password:</prompt>
	    /etc/firewall&prompt.root; <userinput>mv fwrules fwrules_tun0</userinput>
	    /etc/firewall&prompt.root; <userinput>cat fwrules_tun0 | sed s/tun0/ppp0/g > fwrules</userinput>
	  </screen>

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

	  <screen>
	    &prompt.user; <userinput>ifconfig</userinput>
	    <emphasis>(skipped...)</emphasis>
	    ppp0: flags=<replaceable>8051&lt;UP,POINTOPOINT,RUNNING,MULTICAST&gt; mtu 1524</replaceable>
                    inet <replaceable>xxx.xxx.xxx.xxx</replaceable> --&gt; <replaceable>xxx.xxx.xxx.xxx</replaceable> netmask <replaceable>0xff000000</replaceable>
	    <emphasis>(skipped...)</emphasis>
          </screen>

	  <para>С другой стороны, для соединений, выполняемых посредством
            &man.ppp.8; (<emphasis>user-ppp</emphasis>), вы должны увидеть
            нечто вроде следующего:</para>

	  <screen>
	    &prompt.user; <userinput>ifconfig</userinput>
	    <emphasis>(skipped...)</emphasis>
	    ppp0: flags=<replaceable>8010&lt;POINTOPOINT,MULTICAST&gt; mtu 1500</replaceable>
	    <emphasis>(skipped...)</emphasis>
	    tun0: flags=<replaceable>8051&lt;UP,POINTOPOINT,RUNNING,MULTICAST&gt; mtu 1524</replaceable>
	            <emphasis>(IPv6 stuff skipped...)</emphasis>
                    inet <replaceable>xxx.xxx.xxx.xxx</replaceable> --&gt; <replaceable>xxx.xxx.xxx.xxx</replaceable> netmask <replaceable>0xffffff00</replaceable>
                    Opened by PID <replaceable>xxxxx</replaceable>
            <emphasis>(skipped...)</emphasis>
          </screen>
	</answer>
      </qandaentry>
    </qandaset>
  </sect1>
</article>
