Продолжим настройку нашего шлюза, про который я говорил в предыдущей статье. Напомню, там мы настроили правила маршрутизации, теперь нам надо заняться 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". Теперь наши сервера доступны, пока хотя бы один из провайдеров дает нам доступ в интернет.
Еще хотел рассказать, как можно переключаться между провайдерами и сделать парочку замечаний, но объем статьи и так уже слишком большой, видимо будет третья часть.
Скачать скрипты из первой и второй части.
Подписаться на:
Комментарии к сообщению (Atom)
Комментариев нет:
Отправить комментарий