Рассмотрим далее построение шлюза компании, выполняющего функции фаерволла. Шлюз будет построен на базе ОС Ubuntu Server 10.10. Итак, пусть имеется такая схема подключения корпоративной сети к Интернет:
Задачи, которые необходимо решить:
Важнейшая составляющая задачи построения шлюза состоит в необходимости маршрутизации компьютеров локальной сети через провайдеров: основная часть компьютеров будет маршрутизироваться через Провайдера 2 (Yota, в моем случае модем USB модель SAMSUNG ???), т.к. это дешевый канал, но и медленный, а один из компьютеров локальной сети должен выходить в Интернет через Провайдера 1 (ADSL) - быстрее чем Yota, но соответственно и дороже.
Этапы работы.
1) Установка ОС. Процесс установки подробно описан в сети, в частности вы можете посмотреть источник: http://www.howtoforge.com/perfect_setup_ubuntu_6.06 Некоторые замечания: я устанавливаю базовую версию ОС (т. е. без графической оболочки и т. п.). Все, что нужно, вы потом сможете самостоятельно доставить. Итак, считаем, что ОС поставлена.
2) Выполняем базовую настройку ОС.
Выполняем настройку сетевых интерфейсов /etc/network/interfaces:
# The loopback network interface auto lo iface lo inet loopback # WAN (ADSL) auto eth0 iface eth0 inet static address 192.168.1.10 netmask 255.255.255.0 network 192.168.1.0 broadcast 192.168.1.255 gateway 192.168.1.1 ##metric 100 dns-nameservers 192.168.1.1 ## dns-nameserver IP1 IP2 # WAN (WiMax) auto wimax0 iface wimax0 inet dhcp # LAN auto eth2 iface eth2 inet static address 192.168.0.250 netmask 255.255.255.0 network 192.168.0.0 broadcast 192.168.0.255
3) Установка драйвера модема Yota. Linux был выбран не случайно: на данный момент времени имеются корректно работающие драйвера под эту ОС для модема Yota, тогда как для FreeBSD ситуация плачевная: драйвер есть, однако пока только для Current (в котором есть libusb-1.0 ?), и работа его не стабильна (качество связи с провайдером низкое, иногда связь вообще пропадает). Итак, поставим драйвер для модема Yota. Для этого с адреса http://code.google.com/p/madwimax/ скачаем последнюю сборку драйвера (или можете скачать у нас здесь). Как устанавливать:
Если сборка и установка будет пройдена успешно, подключаем модем. При этом, в системе должно появиться новое сетевое устройство с именем wimax0:
# ifconfig | grep wimax wimax0 Link encap:Ethernet HWaddr 00:24:91:34:18:d7
4) Итак, ОС поставлена, ПО обновлено, драйвер модема поставлен. Включим режим маршрутизации.
Источники:
Выполняем:
sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward"
Добавляем в /etc/sysctl.conf:
net.ipv4.conf.default.forwarding=1 net.ipv4.conf.all.forwarding=1
5) Следующая задача состоит в настройке фаерволла iptables, который уже встроен в ядро. Источники:
Для начала, я сгенерировал правила со странички http://easyfwgen.morizot.net/gen/index.php. Это самый быстрый и простой способ «въехать» в фаерволл (т.к. я всегда работал с ipfilter во FreeBSD). Полученный код сохранил в текстовый файл, сделал его исполняемым. Выполнил. Проверил, что выполняются функции NAT. Замечания.
if [ "$SYSCTL" = "" ] then echo "1" > /proc/sys/net/ipv4/ip_forward else $SYSCTL net.ipv4.ip_forward="1" fi
Также, я закомментировал блок:
#if [ "$SYSCTL" = "" ] #then # echo "1" > /proc/sys/net/ipv4/conf/all/rp_filter #else # $SYSCTL net.ipv4.conf.all.rp_filter="1" #fi
Почему это сделано, я поясню ниже. Также закомментировал блок:
# if [ "$SYSCTL" = "" ] # then # echo "1" > /proc/sys/net/ipv4/conf/all/log_martians #else # $SYSCTL net.ipv4.conf.all.log_martians="0" #fi
Т.к. со всех сторон шлюза я получаю адреса из частной сети, фаерволл не пропускал такие пакеты при включенной опции net.ipv4.conf.all.log_martians.
$IPT -P INPUT DROP $IPT -P OUTPUT DROP $IPT -P FORWARD DROP
задает политику по умолчанию - т.е. все, что явно не разрешено, будет запрещено.
route del -net 0.0.0.0 dev eth0
Здесь я удалил маршрут по умолчанию к ADSL провайдеру (см. рис. выше), т.е. у меня остался всего один маршрут по-умолчанию к провайдеру Yota. Советую сразу команду по удалению маршрута по-умолчанию прописать в /etc/network/interfaces в группе настройки соответствующего интерфейса:
# WAN (ADSL) auto eth0 ... up route del -net 0.0.0.0 dev eth0 ...
Что это дает? Каждый раз при старте компьютера будет удаляться один маршрут по-умолчанию.
Дальше, отладив скрипт, проверив связность фаерволла и локальной сети с Интернет, выполняем скрипт с ключом save. При этом в отдельный файл будут записаны текущие правила фаерволла (в формате, читаемом iptables). Чтобы каждый раз при старте системы загружались сохраненные правила, прописываем в /etc/network/interfaces:
# WAN (ADSL) auto eth0 ... pre-up iptables-restore < /etc/iptables.rules.2
Я прописал в секции eth0, хотя это не имеет значения, т.к. правила содержат инструкции по фильтрации для каждого имеющегося в системе сетевого интерфейса.
6) Формирование таблиц маршрутизации
Источники:
Итак, на данный момент у нас имеется «полунастроенный» шлюз, который маршрутизирует весь трафик к Интернет только по одному каналу (в моем случае, Yota) (выше было объяснено, почему был удален один из маршрутов по умолчанию в случае, когда вы имеете подключение более, чем к одному провайдеру). Вначале было сказано, что важнейшей задачей является маршрутизация одного из компьютеров в локальной сети по другом каналу, т.е. нужно так настроить шлюз, чтобы он принимал решение, к какому из провайдеров направить очередной пакет из локальной сети. Займемся этим.
Для того, чтобы посмотреть текущую таблицу маршрутизации, выполните любую одну из двух команд:
ip route show route -n
По-умолчанию в Линукс имеется три таблицы маршрутизации: локальная, главная и по-умолчанию. Чтобы увидеть, какие таблицы маршрутизации имеются в системе, выполните команду ip rule list. Например, чтобы посмотреть, какие маршруты хранятся в таблице маршрутизации main выполните: ip route list table main. Кстати, по-умолчанию, ip route show и route -n выводят маршруты именно из этой таблицы. Наша задача состоит в том, чтобы создать новую таблицу маршрутизации, где будут храниться все маршруты для канала ADSL. Создадим новую таблицу, для этого добавим в конец файла /etc/iproute2/rt_tables строку в формате «число1 имя_таблицы». Здесь: число1 - порядковый номер таблицы, имя_таблицы - буквенное имя. Совет: чтобы не путаться дальше, лучше задать одинаковое числовое значение в обоих полях. К примеру, выполним команду:
echo 4 4 >> /etc/iproute2/rt_tables
Тем самым мы создали новую таблицу маршрутизации с именем и порядковым номером, равным 4. Далее выполним команды:
echo "Erase the route..." /bin/ip route flush cache /bin/ip route flush table 4 echo "Copy main routing table to adsl (ID 4) table" /bin/ip route show table main | grep -Ev ^default | while read ROUTE ; do ip route add table 4 $ROUTE ; done /bin/ip route add table 4 default via eth0
Первые две команды очищают кеш таблиц маршрутизации, третья команда копирует все содержимое главной таблицы маршрутизации в нашу только что созданную под номером 4, за исключением маршрута по-умолчанию. Действительно, зачем нам в новой таблице маршрутизации запись о маршруте по-умолчанию из главной таблицы, если мы хотим прописать новый маршрут по-умолчанию? Четвертая команда как раз добавляет запись о маршруте по-умолчанию для ADSL линии в таблицу 4.
Итак, мы хотим, чтобы наш компьютер в локальной сети с IP 192.168.0.90 выходил в сеть через ADSL провайдера, а все остальные компьютеры - через WiMax модем. В главной таблице маршрутизации у нас уже имеется маршрут по-умолчанию для провайдера Yota. Его мы «трограть» не будем. Но как нам сказать, что все, что идет от 192.168.0.90 должно идти через другой канал, т.е. другими словами, как привязать только что созданную таблицу маршрутизации к пакетам от 192.168.0.90? Делается это так (добавьте в конце файла с правилами iptables):
$IPT -t mangle -A PREROUTING -s 192.168.0.90/32 -j MARK --set-mark 0x4 /bin/ip rule add fwmark 4 table 4
Все, теперь все пакеты от 192.168.0.90 будут «привязаны» к новой таблице маршрутизации, где запись маршрута по-умолчанию говорит, что пакеты надо отсылать через сетевой интерфейс, соединенный с каналом ADSL.
Замечание.
#!/bin/sh # #if.up.sh echo "Erase the route..." INET_ADSL_GW="192.168.1.1" /bin/ip route flush cache /bin/ip route flush table 4 echo "Copy main routing table to adsl (ID 4) table" /bin/ip route show table main | grep -Ev ^default | while read ROUTE ; do ip route add table 4 $ROUTE ; done /bin/ip route add table 4 default via $INET_ADSL_GW /bin/ip rule add fwmark 4 table 4 /bin/echo 0 > /proc/sys/net/ipv4/conf/eth0/rp_filter /bin/echo 0 > /proc/sys/net/ipv4/conf/all/rp_filter
и поместил вызов в соответствующий блок в /etc/network/interfaces, т.о.:
# WAN (ADSL) auto eth0 iface eth0 inet static address 192.168.1.10 netmask 255.255.255.0 network 192.168.1.0 broadcast 192.168.1.255 gateway 192.168.1.1 ##metric 100 dns-nameserver 192.168.1.1 pre-up iptables-restore < /etc/iptables.rules.2 up /root/scripts/if.up.sh up route del -net 0.0.0.0 dev eth0
7) Принуждение записи логов IPTABLES в отдельный файл
Я думаю, что многие сталкивались с проблемой, как заставить писать Iptables в отдельный файл, а не системный syslog и пр. Вот решение:
touch /etc/rsyslog.d/iptables.conf
Прописываем /etc/rsyslog.d/iptables.conf:
:msg, contains, "fw: " -/var/log/iptables.log
$IPT -A bad_packets -p ALL -m state --state INVALID -j LOG --log-prefix "fw: Invalid packet: "
Т.е. Rsyslog будет отлавливать такие инструкции и помещать в отдельный файл.
chown syslog /var/log/iptables.log
/etc/init.d/rsyslog restart
TAG: