вторник, 24 марта 2009 г.

Используем 2+ провайдера (вторая часть)

Продолжим настройку нашего шлюза, про который я говорил в предыдущей статье. Напомню, там мы настроили правила маршрутизации, теперь нам надо заняться iptables. Сейчас мы настроим сеть состоящую из шлюза и сервера. На шлюзе будет работать SSH и DNS, а сервер у нас будет виндовый на нем у нас RDP и SMTP. Сеть будет настроена таким образом, что через любой из внешних айпишников мы сможем подключаться к любому из серверов, а SMTP сервер будет выходить наружу через основного провайдера.
Ну и конечно, же начнем с переменных, причем вынесем следующие настройки в отдельный файл, это нам сильно пригодиться в будущем:


#!/bin/bash

export GLOBAL_ETH_PRIM=eth1
export GLOBAL_ETH_SEC=eth2
export GLOBAL_IP_PRIM=10.10.10.10
export GLOBAL_IP_SEC=20.20.20.20
export MARK_PRIM=10
export MARK_SEC=20


Назовем этот файл ipt_p1.conf. А содержит он данные о том, какой из интерфейсов является главным, а какой запасным (PRIM и SEC соответственно) и значения для маркировки пакетов.
Перейдем к основному файлу конфигурации iptables, назовем его ipt.conf. Запишем переменные ;-)


#!/bin/bash
IPTABLES=/sbin/iptables
MODPROBE=/sbin/modprobe


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


LOCAL_ETH=eth0
GLOBAL_ETH_P1=eth1
GLOBAL_ETH_P2=eth2
LOCAL_IP=192.168.0.1
LOCAL_NET=192.168.0.0/24
GLOBAL_IP_P1=10.10.10.10
GLOBAL_IP_P2=20.20.20.20


Тут мы описали конфигурацию нашей сети, по порядку: локальный интерфейс, интерфейсы, которые смотрят к провайдерам, локальный айпишник и подсеть, айпишники, которые выданы провайдерами.


SRV11=192.168.0.11
SRV12=192.168.0.12


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

. $1


Зацепили внешние настройки, в данном случае это будет наш файл ipt_p1.conf.
Хватит о скучном, приступим к настройке, причем попытаемся все сделать красиво:


echo "[+] Flushing existing iptables rules..."
$IPTABLES -F
$IPTABLES -F -t nat
$IPTABLES -F -t raw
$IPTABLES -F -t mangle
$IPTABLES -X
$IPTABLES -P INPUT DROP
$IPTABLES -P OUTPUT DROP
$IPTABLES -P FORWARD DROP


Очищаем все правила iptables, в первой строке говорим, что делаем, почему по английски, а чтобы не было проблем с кодировками. Последние три строчки устанавливают правила по умолчанию - все пакеты не подходящие под список правил будут просто отброшены.


$MODPROBE ip_conntrack
$MODPROBE iptable_nat


Загрузили модули ядра, которые будем использовать.
Теперь пройдемся по цепочкам iptables и заполним их необходимыми правилами:


echo "[+] Setting up INPUT chain..."

$IPTABLES -A INPUT -m state --state INVALID -j DROP
$IPTABLES -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT


Используя возможности модуля state мы отбрасываем некорректные пакеты и принимаем пакеты относящиеся к уже установленным соединениям либо ко вторичными соединениям (таким как передача данных в ftp).

$IPTABLES -A INPUT -p tcp --dport 22 --syn -m state --state NEW -j ACCEPT


Принимаем подключения по SSH отовсюду.

$IPTABLES -A INPUT -i $LOCAL_ETH -s $LOCAL_NET -j ACCEPT


Локальный трафик будет ходить без ограничений, хотя это не всегда правильно.

$IPTABLES -A INPUT -i lo -j ACCEPT


Тоже на localhost.
Продолжаем с цепочкой OUTPUT:


echo "[+] Setting up OUTPUT chain..."

$IPTABLES -A OUTPUT -m state --state INVALID -j DROP
$IPTABLES -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT


Эти правила аналогичны правилам в цепочке INPUT.

$IPTABLES -A OUTPUT -o $GLOBAL_ETH_PRIM -p udp --dport 53 -j ACCEPT


Мы разрешили работать нашему DNS серверу через основного провайдера

$IPTABLES -A OUTPUT -o $GLOBAL_ETH_PRIM -p tcp --dport 22 --syn -m state --state NEW -j ACCEPT


А также разрешили выходить наружу по SSH.

$IPTABLES -A OUTPUT -o $LOCAL_ETH -d $LOCAL_NET -m state --state NEW -j ACCEPT


Опять же на исходящий локальный трафик ограничений нет.
Переходим к обработке трафика из локальной сети:


echo "[+] Setting up FORWARD chain..."

$IPTABLES -A FORWARD -m state --state INVALID -j DROP
$IPTABLES -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT


Все те же два удобных правила.

$IPTABLES -A FORWARD -i $GLOBAL_ETH_P1 -d $SRV11 -p tcp --dport 25 --syn -m state --state NEW -j ACCEPT
$IPTABLES -A FORWARD -i $GLOBAL_ETH_P2 -d $SRV12 -p tcp --dport 25 --syn -m state --state NEW -j ACCEPT
$IPTABLES -A FORWARD -i $GLOBAL_ETH_P1 -d $SRV11 -p tcp --dport 3389 --syn -m state --state NEW -j ACCEPT
$IPTABLES -A FORWARD -i $GLOBAL_ETH_P2 -d $SRV12 -p tcp --dport 3389 --syn -m state --state NEW -j ACCEPT


Так у нас получается, что пакеты приходящие на первого провайдера пропускаются только на первый айпишник сервера, второго - на второй.


$IPTABLES -A FORWARD -i $LOCAL_ETH -s $SRV11 -j ACCEPT
$IPTABLES -A FORWARD -i $LOCAL_ETH -s $SRV12 -j ACCEPT


Разрашаем весь исходящий трафик с нашего сервера, опять же это не совсем правильно.
Далее идут правила NAT:


$IPTABLES -t nat -A POSTROUTING -s $SRV11 -p tcp --dport 25 -j SNAT --to-source $GLOBAL_IP_PRIM
$IPTABLES -t nat -A POSTROUTING -s $SRV12 -p tcp --dport 25 -j SNAT --to-source $GLOBAL_IP_PRIM


Все, что наш сервер попытается отправить по SMTP пойдет через основного провайдера.
И опять самое интересное нам осталось на последок. Переходим к PREROUTING, здесь то мы и воспользуемся возможностью маркировать пакеты, которая нам понадобится для маршрутизации вот в этих двух строчках:


ip rule add from $SRV11 fwmark 10 table T1
ip rule add from $SRV12 fwmark 20 table T2


Итак, наши правила:


$IPTABLES -t mangle -A PREROUTING -i $LOCAL_ETH -s $SRV11 -p tcp --dport 25 -j MARK --set-mark $MARK_PRIM
$IPTABLES -t mangle -A PREROUTING -i $LOCAL_ETH -s $SRV12 -p tcp --dport 25 -j MARK --set-mark $MARK_PRIM


Все пакеты уходящие с нашего внутреннего сервера на 25 порт мы маркируем значением $MARK_PRIM. Давайте проследим, что это нам дает: исходящий пакет маркируется значением 10, значит маршрутизироваться он будет по таблице T1, а соответствуя этой таблице пакет должен уйти через первого провайдера, в цепочке FORWARD есть разрешающее правило, поэтому пакет безпрепятственно проходит - все правильно это нам и требовалось.
Теперь нам надо разобраться с соединениями идущими к нам. Сначала, конечно же, должен отработать DNAT:


$IPTABLES -t nat -A PREROUTING -i $GLOBAL_ETH_P1 -d $GLOBAL_IP_P1 -p tcp --dport 25 -j DNAT --to-destination $SRV11
$IPTABLES -t nat -A PREROUTING -i $GLOBAL_ETH_P1 -d $GLOBAL_IP_P1 -p tcp --dport 3389 -j DNAT --to-destination $SRV11
$IPTABLES -t nat -A PREROUTING -i $GLOBAL_ETH_P2 -d $GLOBAL_IP_P2 -p tcp --dport 25 -j DNAT --to-destination $SRV12
$IPTABLES -t nat -A PREROUTING -i $GLOBAL_ETH_P2 -d $GLOBAL_IP_P2 -p tcp --dport 3389 -j DNAT --to-destination $SRV12


Вроде бы все правильно, проверяем: пакет приходит на внешний интерфейс шлюза, в зависимости от принадлежности интерфейса провайдеру, он перенаправляется на первый или второй айпишник внутреннего сервера, сервер отвечает с того же(!) айпишника, пакет на шлюзе маршрутизируется по основной таблице, проходит через FORWARD и отправляется через основного провайдера, а вот это уже не правильно, ведь пакет мог прийти и через запасного провайдера. Исправляем, добавляя правила:


$IPTABLES -t mangle -A PREROUTING -i $LOCAL_ETH -s $SRV11 -p tcp --sport 25 -j MARK --set-mark $MARK_PRIM
$IPTABLES -t mangle -A PREROUTING -i $LOCAL_ETH -s $SRV11 -p tcp --sport 3389 -j MARK --set-mark $MARK_PRIM
$IPTABLES -t mangle -A PREROUTING -i $LOCAL_ETH -s $SRV12 -p tcp --sport 25 -j MARK --set-mark $MARK_SEC
$IPTABLES -t mangle -A PREROUTING -i $LOCAL_ETH -s $SRV12 -p tcp --sport 3389 -j MARK --set-mark $MARK_SEC


Теперь на обратном пути мы маркируем пакеты в соответствии с адресом, с которого они отправляются. Далее в дело вступают таблицы маршрутизации T1 и T2, поэтому решение через какой интерфейс отправлять пакеты принимается правильное.
Все! Готово. Для применения правил выполняем команду "./ipt.conf ipt_p1.conf". Теперь наши сервера доступны, пока хотя бы один из провайдеров дает нам доступ в интернет.
Еще хотел рассказать, как можно переключаться между провайдерами и сделать парочку замечаний, но объем статьи и так уже слишком большой, видимо будет третья часть.

Скачать скрипты из первой и второй части.

Комментариев нет:

Отправить комментарий