From: procool <procool@procool.ru.>
Newsgroups: email
Date: Mon, 27 Feb 2007 14:31:37 +0000 (UTC)
Subject: Настройка маршрутизатора на базе FreeBSD сервера
Список источников
Глава1: настройка роутинга пакетов из одной сети в другую, firewall
Глава2: настройка трансляции адресов
Глава3: настройка доступа к internet через выданный внешней сетью шлюз, для внутренней сети.
Список источников
По адресу http://procool.ru/interesting/gw_sett.txt можно скачать текст статьи.
Процесс установки и базовую настройку системы я опущу, так как
она не входит в данный раздел.
Предположим, что эти действия уже произведены, система поставлена,
но не настроена под шлюз.
ГЛАВА 1.
Предлагаю описать задачу:
Настроить простой шлюз предназначенный для роутинга пакетов из одной сети в
другую.
Предположим, что у нас есть две сети, и сетевые карты на шлюзе соответственно:
rl0: 10.10.10.0/24
rl1: 192.168.0.0/16
Для начала нам необходимо настроить локальную сеть на интерфейсах rl0 и rl1 в
соответствии с указанным ТЗ.
Для этого воспользуемся программой ifconfig:
Зададим на эти интерфейсы первые адреса из этих подсетей, предположив что они
свободны:
Для уверенности стоит удостоверится что оба интерфейса видят сеть. Об этом
можно судить по статусу интерфейса "active" при положительном и "no carrier"
при отрицательном исходе этого вопросa при просмотре через утилиту
/sbin/ifconfig
Можно так же проверить наличие сети послав несколько ICMP запросов заведомо
известным поднятым в этих сетях серверам, например ping утилитой. При этом
удостоверьтесь - принимают ли такие пакеты доверенные серверы использованные
для тестирования.
Если устройства подняты а ICMP пакеты не доходят - то возможно сеть
неисправна, но есть так же большая вероятность того что сервер на который они
отсылаются - блокирует их и не отвечает. Возможно так же что на нашем шлюзе
уже стоит firewall и не дает доступа отсылать эти пакеты. Часто в последнем
случае можно видеть сообщение о невозможности отправки пакета из-за отсутствия
доступа.
Для того что бы компьютер мог использоваться в роли маршрутизатора, в ядре
нужно разрешить пересылку пакетов между интерфейсами. Во FreeBSD для этого
нужно выполнить команду:
sysctl net.inet.ip.forwarding=1
Теперь, стоит настроить роутинг между интерфейсами rl0 и rl1.
Проставив шлюзом на подсеть 192.168.0.0/16 машину с ip адресом
10.10.10.1 компьютеры из сети 10.10.10.0/24 смогут обращаться к сети
192.168.0.0/16, и, в свою очередь, компьютеры подсети 192.168.0.0/16,
проставив у себя шлюзом машину с ip адресом 192.168.0.1 смогут обращаться в
подсеть 10.10.10.0/24, чего мы и добивались.
Настройка сети выполнена руками и при первой же перезагрузке системы -
потеряет свою силу. Потому рекомендую сделать возможной её автоматическую
установку при старте системы.
Можно написать sh скрипт в котором просто указать все выполненные нами
программы, но ...
Система FreeBSD - система стандартов, она спроектирована так чтобы если
другой администратор пришел на ваш шлюз - ему стало понятно что где и почему,
и не возникало лишних вопросов. Это часть идеологии этой системы, и потому я
думаю, стоит её придерживаться.
Принято настройки сетевых интерфейсов указывать в загрузочном файле
/etc/rc.conf Вот в таком виде:
Разрешить пересылку пакетов между интерфейсами можно добавив в этот же файл
запись:
gateway_enable="YES" # Set to YES if this host will be a gateway.
Кстати, в большинcтве дистрибутивов Linux того же самого можно добиться,
указав в файле /etc/sysconfig/network:
FORWARD_IPV4="yes"
Что бы применить настройки внесенные в /etc/rc.conf можно вызвать программу
netstart:
/etc/netstart
FIREWALL
Собственно, тема огненной стены не может быть пропущена в этом разделе - как
никак базовая защита системы от внешних воздействий, атак, взломов.. И не
только системы, но и сети которая стоит за нашим шлюзом, т.е. речь идет не
просто о фаерволе на эту машину - речь идет о фаерволе на всю подсеть!
Есть много типов фаерволов, - например iptables, IpFilter, PF(Pocket Filter) -
кстати очень хорошая система, общепринятая в OpenBSD и портированная во
FreeBSD.
Здесь мы остановимся на фаерволе ipfw как на наиболее простом и удобном,
несложном в настройке и надежном, стабильном и быстром средстве, которое
работает на уровне ядра и являет собой дефолтовый фаервол системы вот уже
много лет.
Для того чтобы ipfw смог работать - необходимо включить его поддержку в ядре.
Можно пойти простым путем и динамически подгрузить требуемый модуль ipfw.ko
при помощи системной утилиты kldload:
/sbin/kldload ipfw.ko
Для автоматизации этого процесса при перезагрузке системы можно
воспользоваться средствами её загрузчика,
а именно конфигурационным файлом /boot/loader.conf прописав там:
Второй вариант - пересобрать ядро с поддержкой вышеуказанного модуля.
Это более надежный и правильный на мой взгляд метод.
Перед пересборкой ядра в его конфигурационный файл следует включить опции
поддержки фаервола:
options IPFIREWALL
Здесь же, с верой в будущее и осознанием настоящего - подумайте - возможно
вам в последствии захочется настроить трансляцию адресов на сервере (NAT -
Networke Address Translation)? Если так - то включите и эту поддержку заранее:
options IPDIVERT
Способов пересборки ядра - много. Я пользуюсь наиболее простым из них:
cd /usr/src
make kernel
Еще рекомендуется редактировать конфиг ядра в другом файле, да бы случайно не
запортить дефолтовый конфиг GENERIC.
Для этого стоит скопировать имеющийся GENERIC в отдельный файл, назовем его
MYCONF и собрать его из него:
cd /usr/src/sys/i386/conf
cp GENERIC MYCONF
... включаем опции в конфиг ...
cd /usr/src
make kernel KERNCONF=MYCONF
Если страшно собирать и устанавливать ядро в одну строку(последнюю в
приведенном листинге), - можно её разделить на две:
make buildkernel KERNCONF=MYCONF
make installkernel KERNCONF=MYCONF
Можно сделать по handbook-у, через /usr/sbin/config MYCONF
Но не забудьте при этом переменную MYCONF определить в /etc/make.conf :
cd /usr/src/sys/i386/conf
/usr/sbin/config MYCONF
cd ../compile/MYCONF (cd ../../compile/MYKERNEL for FreeBSD versions prior to 5.0)
make depend
make
make install
- но по моему всё это лишняя работа.
Подробнее о сборке ядра - не здесь. Читайте handbook если интересно.
После сборки ядра (или во время), или после поднятия модуля если вы всё таки
решили пойти таким путем, в конфигурационном файле /etc/rc.conf стоит
определить загрузку фаервола следующей записью:
firewall_enable="YES"
Здесь же можно определить тип фаервола.
В наличии имеются несколько типов, в частности открытый, закрытый, и заданный
через файл.
Открытый тип (open) - это когда по умолчанию всё разрешено, другими словами
allow all from any to any;
Это правило ставится в конец всех других, и перед ним можно указать несколько
исключений закрывающих то что требуется.
Второй тип - обратный первому. Закрытый (close) тип фаервола более безопасен в
плане безопасности системы (но более опасен в плане неграмотности её
настройки, особенно если настройка удаленная), - идея в том чтобы открыть
только то что требуется, и всё остальное закрыть.
Здесь последним правилом ставится следующее: deny all from any to any;
Зависит от конфигурации ядра, но по умолчанию во freebsd профелируется
закрытый тип.
Тип фаервола из файла - Это когда все необходимые правила задаются
пользователем из файла, который читается при загрузке системы.
Следует помнить о том что к всем прочитанным правилам после перечтения файла,
присоединится еще одно - запрещающие всё, как и в закрытом типе.
Указывается тип фаервола следующим образом в /etc/rc.conf:
firewall_type="<ТИП>"
Где тип open, close или путь к файлу соответственны описанным выше типам.
В первых двух случаях можно написать какой -либо shell скрипт который сам
задаст требуемые правила, но мы пойдем иным путем.
Мы будем использовать файл с правилами, в котором для начала напишем allow all
from any to any чтобы для начала удовлетворить любым запросам.
Итак, добавим правило в файл настроек, назовем его /etc/firewall.conf :
echo add 100 allow all from any to any >/etc/firewall.conf
Если компилировали ядро - то загружаем систему, если подгружали модуль то пробуем
/etc/netstart
ГЛАВА 2.
В этой главе предлагаю рассмотреть настройку уже настроенного нами
маршрутизатора пакетов между сетями
в качестве шлюза одной сети в другую с учетом трансляции адресов.
Данная тема понадобится возможно тем кто стремится настроить шлюз для
маленькой сети в интернет, и хочет скрыть за ним компьютеры своей внутренней
сети.
Задача: На базе начальных условий настроить систему трансляции адресов так,
чтобы внутренняя сеть видела и могла обращаться к любому адресу внешней сети,
от имени(ip) настраиваемого нами шлюза, а внешняя сеть, в свою очередь, не могла
определить с какого адреса внутренней сети поступает запрос, и отвечала
обратно шлюзу же, который бы транслировал адреса обратно.
Предположим так же что у нас настроена система роутинга, настроен фаервол ipfw,
поднят демон routed.
Есть много систем позволяющих транслировать ip адреса различных подсетей от
своего имени.
Частные наиболее популярные случаи это natd и ipnat.
natd - очень хорошая система, но у неё есть один серьезный недостаток.
Все соединения открывающиеся в системе - проходят через отдельный демон natd,
что может сильно нагрузить систему при больших объемах трафика.
ipnat не страдает этой проблемой, так как встроен в ядро системы, потому
предлагаю использовать именно его.
Для конфигурации ipnat нужно создать соответствующий конфигурационный файл с
настройками - правилами по которым эта система будет работать.
Назовем его: /etc/ipnat.rules
И внесем туда следующие строки:
map rl1 from 10.10.10.0/24 to 192.168.0.0/16 -> 192.168.0.1/32 proxy port ftp ftp/tcp
map rl1 from 10.10.10.0/24 to 192.168.0.0/16 -> 192.168.0.1/32
Расшифровка первой записи:
переименовать исходящий адрес пакета идущего через внешний rl1 интерфейс с
адреса принадлежащего подсети 10.10.10.0/24 в сеть 192.168.0.0/16 - в адрес
"192.168.0.1" - правило действительно для всех ftp соединений.
Последние - специальное допущение сделанное в рамках использования ftp
протокола.
Расшифровка второй записи:
переименовать исходящий адрес пакета идущего через внешний rl1 интерфейс с
адреса принадлежащего подсети 10.10.10.0/24 в сеть
192.168.0.0/16 - в адрес "192.168.0.1" - правило действительно для всех
соединений не попавших под предыдущие правило.
После проведенного действия следует подгрузить модуль ipl.ko:
ipl - IP packet log device, после которого станет доступно устройство
/dev/ipnat необходимое для работы ipnat:`
- o принадлежности флагов подробнее читайте man ipnat;
Проверим вступившие в оборот правила командой:
/sbin/ipnat -l
Результат выполнения должен быть примерно таким:
List of active MAP/Redirect filters:
map rl1 from 10.10.10.0/24 to 192.168.0.0/16 -> 192.168.0.1/32 proxy port ftp ftp/tcp
map rl1 from 10.10.10.0/24 to 192.168.0.0/16 -> 192.168.0.1/32
List of active sessions:
Для включения поддержки ipnat-а в /etc/rc.conf можно внести следующие строки:
Вообще, рекомендуется настроить фаервол для безопасности внутренней сети и
ограничения к ней подключений из внешней сети. Как это сделать - я возможно
напишу позднее, а на данном этапе можно обойтись и без этого:)
ГЛАВА 3.
Задача:
На основе установленной системы настроить доступ к глобальной сети через
выданный внешней сетью шлюз, для внутренней сети.
IP адрес выделенного во внешней сети шлюза: 192.168.10.10
Выполнить эту задачу не просто, а очень просто!
Достаточно определить по умолчанию маршрут на который будут отсылаться все
пакеты адресованные подсети не имеющий отношения к нашим ( ни к внутренней, ни
к внешней ).
После этого надо будет настроить ipnat на трансляцию адресов еще и туда, и
наша задача будет выполнена.
Первую часть сделать проще простого - нужно просто добавить маршрут по
умолчанию "default" (0.0.0.0), и сделать это можно программой route:
/sbin/route add default 192.168.10.10
Здесь мы указали в качестве следующей точки - выданный нам внешней сетью
сервер 192.168.10.10.
Если на наш шлюз придет пакет, адрес назначения которого не будет относиться
ни к одной из определенных на наших интерфейсах ( rl0 rl1 ) сетей, - то этот
пакет наш шлюз направит именно на "внешний шлюз", - а тот уже сам разберется
что с ним делать. По идее он его передаст на уровень выше, и так пакет будет
передаваться от шлюза к шлюзу, пока не дойдет до цели.
Чтобы автоматизировать процесс выставления роутера по умолчанию - можно
прописать запись о нем в всё тот же пресловутый конфигурационный файл
/etc/rc.conf:
defaultrouter="192.168.10.10"
И тогда, при загрузке системы, маршрут будет вступать в силу.
Посмотреть его можно при помощи утилиты netstat передав ей параметр "r", что
бы она показала таблицу роутинга в системе:
Теперь, добавим в /etc/ipnat.rules строки для того чтобы научить наш шлюз
транслировать через себя пакеты проходящие в глобальную сеть.
Сделать это можно по образу и подобию предыдущих записей:
map rl1 from 10.10.10.0/24 to 0.0.0.0/0 -> 192.168.0.1/32 proxy port ftp ftp/tcp
map rl1 from 10.10.10.0/24 to 0.0.0.0/0 -> 192.168.0.1/32