(495) 925-0049, ITShop интернет-магазин 229-0436, Учебный Центр 925-0049
  Главная страница Карта сайта Контакты
Поиск
Вход
Регистрация
Рассылки сайта
 
 
 
 
 

Переключения между провайдерами интернета на Debian 7

Источник: habrahabr
woooody

В последних дистрибутивах Linux довольно много всяких полезных плюшек в папке /etc, однако мало кто ими грамотно пользуется. Здесь я расскажу про часть из них применительно к последней стабильной версии Debian, и приведу пример реализации переключения на резервный канал.
Все попытки найти банальную автопереключалку приводили к связке из 1-2 скриптов, написанным "под себя" и мало поддающимися настройке. К dhcp не был привязан ни один из них, а значит любые манипуляции на стороне провайдера требовали вмешательство в настройки. Сам писал такие в свое время, но вот теперь решил на новой системе оформить это красиво - так, как это задумывали разработчики Debian, а именно - меняем файлы конфигурации, добавляем свои скрипты и не трогаем те, что нам предоставила система.

Итак, имеем:
- два кабеля от двух провайдеров, оба выдают IP по dhcp
- свежесобранный сервер под управлением debian wheezy с тремя сетевухами (возможно потом добавлю еще)
- желание чтоб инет не пропадал (работа не ждет!). Балансировку и т.п. оставим на потом.

Логика на первый взгляд простая:
- пингуем какой-нибудь хост по очереди через разные интерфейсы
- если пинг нестабильный, переключаемся на резервный канал.
Вот только в реализации была поставлена цель сделать всё максимально гибко, например не ограничивать количество потенциальных провайдеров и впоследствии делать минимум телодвижений для перенастройки.
Для начала посмотрим какие плюшки уже есть в системе
В папке /etc/network нас интересует файл interfaces и папки if-down.d, if-post-down.d, if-pre-up.d, if-up.d.
root@ns:/etc/network# cat interfaces # This file describes the network interfaces available on your system # and how to activate them. For more information, see interfaces(5). # The loopback network interface iface lo inet loopback # The primary network interface iface eth0 inet static address 192.168.104.1 netmask 255.255.255.0 iface eth1 inet dhcp iface eth3 inet dhcp
При манипуляциях с интерфейсами через ifup/ifdown на папочки натравливается run-parts, и скриптам в них доступны следующие переменные окружения: IFACE, LOGICAL, ADDRFAM, METHOD, MODE, PHASE, MODE, VERBOSITY, PATH
При старте системы сначала запускаются скрипты из папки if-pre-up.d (по одному разу для каждого интерфейса, но перед ними идет IFACE="--all", потом поднимаются интерфейсы и запускаются скрипты из папки if-up.d и IFACE="--all" идет уже в конце. При ifup ethX запускается по одному разу только для ethX (без "-all"). Аналогично if-down.d и if-post-down.d при ifdown и выключении системы.
Система позволяет назначить для каждой операции и для каждого интерфейса свой скрипт, но вносить похожие изменения каждый раз в 10 из 20 скриптов в мои планы не входило, поэтому будем писать один большой скрипт и расставим на него симлинки изо всех четырех папок. Понять, откуда он запущен, можно по переменным окружения.

Однако нам еще надо узнать информацию о шлюзах, которая пришла по dhcp. На этот случай тоже есть папки со скриптами /etc/dhcp/dhclient-enter-hooks.d и /etc/dhcp/dhclient-exit-hooks.d
Последовательность запуска такая:
- опросили сервер dhcp
- запустили содержимое папки dhclient-enter-hooks.d
- настроили сетевые параметры (ip, DNS, шлюз,…)
- запустили содержимое папки dhclient-exit-hooks.d
Скриптам тоже доступны разные полезные переменные (параметры, которые пришли от dhcp сервера), часть из которых нам надо будет сохранять.

После нескольких вечеров получилось следующее:
Все скрипты лежат в папке /etc/network/scripts. Из разных папок туда ведут симлинки
Настройки - /etc/default/network-scripts
Временые файлы кладем /var/lib/dhcp
Логи пишутся в файл /var/log/network-scripts.log
Настройки
# cat /etc/default/network-scripts # Configuration file for /etc/network/scripts/* # Host to ping for autoroute HOST_TO_PING="4.2.2.1" # Number of pings to check the connection PING_COUNT=5 # list of LAN interfaces IFLAN="eth0" # WAN prio from first to last IFWAN="eth1 eth3" # open ports from WAN zone WAN_PORTS_OPEN=""
Тут всё должно быть понятно. Интерфейсы LAN, WAN можно дописывать сколько угодно. В списке WAN первый - самый приоритетный, далее по убыванию.
Отдельно файл с функциями.
# cat /etc/network/scripts/functions #!/bin/sh DHCPLIB="/var/lib/dhcp" LOGDIR="/var/log" LOGFILE="$LOGDIR/network-scripts.log" HOST_TO_PING="4.2.2.1" PING_COUNT=3 SQUID_PORT="3128" IFLAN="" IFWAN="" WAN_PORTS_OPEN="" . /etc/default/network-scripts # Local variables DEFAULTWAN=${IFWAN% *} log() { DATE=`date` echo "$DATE $@" >> $LOGFILE } warn() { log "WARNING: $@" echo "WARNING: $@" } cmd() { $@ RES=$? log "$RES - $@" return $RES } get_ip() { IP=`ip addr list $1 / grep " inet " / head -n 1 / cut -d " " -f 6 / cut -d / -f 1` } update_local_redirect() { for i in $IFLAN; do cmd iptables -t nat $INS PREROUTING -i $i -p tcp --dport 80 -d $1 -j ACCEPT done } update_squid() { case $1 in start) ADD="-A" INS="-I" ;; stop) ADD="-D" INS="-D" ;; *) ADD="-C" INS="-C" esac for i in $IFLAN; do # transparent proxy cmd iptables -t nat $ADD PREROUTING -i $i -p tcp --dport 80 -j REDIRECT --to-port $SQUID_PORT done }
Тут мы имеем:
- импорт настроек из /etc/default/network-scripts
- ведение логов (log, warn),
- запуск команд с записью в лог параметров и результатов работы
- update_local_redirect() добавляет маршруты на 80 порт мимо transparent proxy
- update_squid() добавляет правило для самого transparent proxy (запускается в /etc/init.d/squid3 - это единственный системный скрипт, в который пришлось влезть)
Тут и далее используется технология, придуманная мной несколько лет назад с переменными $ADD и $INS для iptables. Позволяет писать правило только в одном месте, и потом его добавлять-удалять, изменяя только эти переменные.
# cat /etc/network/scripts/route-enter #!/bin/sh . /etc/network/scripts/functions log "$0 route-enter ${interface} ${reason} ${new_routers}" # security bugfix new_host_name=${new_host_name//[^-.a-zA-Z0-9]/} # save routers to special file echo -n ${new_routers} > $DHCPLIB/routers.${interface} echo -n ${new_ip_address} > $DHCPLIB/ip_address.${interface} case ${interface} in $DEFAULTWAN) # by default enable routers only for first WAN interface ;; *) # and clear it for others unset new_routers ;; esac
- Сохраняем new_routers и new_ip_address в файл (потом понядобятся)
- default route разрешаем только для приоритетного интерфейса

# cat /etc/network/scripts/route-exit #!/bin/sh . /etc/network/scripts/functions log "$0 route-exit ${interface} ${reason}" update_routes() { cmd route $ADD -host $HOST_TO_PING gw ${routers} # identyfy providers by DNS addresses case $DNS in *82.193.96*) DESTIP=`resolveip -s stat.ipnet.ua` cmd route $ADD -host $DESTIP gw ${routers} ;; *193.41.63*/*192.168.11.1*) DESTIP=`resolveip -s my.kyivstar.ua` cmd route $ADD -host $DESTIP gw ${routers} ;; *) warn "route-exit - unknown DNS ${new_domain_name_servers} specified" ;; esac } case ${reason} in BOUND) ADD="add" DNS=${new_domain_name_servers} # use saved-to-file value due to $old_routers can be cleared for some interfaces by other script routers=`cat $DHCPLIB/routers.${interface}` update_routes ;; RELEASE) # No need to delete routes during release # ADD="del" # routers=${old_routers}` # update_routes ;; PREINIT) ;; RENEW) if [ "$old_routers" != "$new_routers" ]; then ADD="del" DNS=${old_domain_name_servers} routers=${old_routers} update_routes ADD="add" DNS=${new_domain_name_servers} routers=`cat $DHCPLIB/routers.${interface}` update_routes fi if [ "$old_ip_address" != "$new_ip_address" ]; then ADD="-D" INS="-D" update_local_redirect ${old_ip_address} ADD="-A" INS="-I" update_local_redirect ${new_ip_address} fi ;; *) warn "route-exit - unknown reason ${reason} used" ;; esac
- Добавляем static route для сайтов с биллингом провайдеров. Локалка провайдера мне не нужна, но её тоже можно добавить. Идентификация по DNS серверам.
- для режима RENEW добавил перенастройку (если вдруг у провайдера что-то изменится), но пока не тестировал.

# cat /etc/network/scripts/firewall #!/bin/bash . /etc/network/scripts/functions get_ip $IFACE log "$0 $IFACE $LOGICAL $ADDRFAM $METHOD $MODE $PHASE $VERBOSITY $IP" case $MODE in start) INS="-I" ADD="-A" echo -n $IP > $DHCPLIB/ip_address.$IFACE ;; stop) INS="-D" ADD="-D" echo -n > $DHCPLIB/ip_address.$IFACE ;; *) INS="-C" ADD="-C" warn "Wrong MODE:$MODE" ;; esac case $IFACE in --all) case $PHASE in pre-down/post-up) # skip proxy for local addresses for j in $IFLAN $IFWAN; do get_ip $j update_local_redirect $IP done ;; post-up/pre-down) ;; esac ;; lo) ;; *) if [[ "$IFLAN" == *$IFACE* ]]; then # LAN case $PHASE in pre-up/post-down) cmd iptables $INS INPUT -p tcp -i $IFACE --dport 22 -j ACCEPT ;; post-up/pre-down) ;; *) warn "Wrong PHASE:$PHASE" ;; esac fi if [[ "$IFWAN" == *$IFACE* ]]; then # WAN case $PHASE in pre-up/post-down) # by default close all input connections cmd iptables $ADD INPUT -p tcp -i $IFACE --dport 1:10000 -j DROP cmd iptables $ADD INPUT -p udp -i $IFACE --dport 1:10000 -j DROP # open ports from list for PORT in $WAN_PORTS_OPEN; do cmd iptables $INS INPUT -p tcp -i $IFACE --dport $PORT -j ACCEPT done ;; post-up/pre-down) cmd iptables -t nat $ADD POSTROUTING -o $IFACE -j MASQUERADE ;; *) warn "Wrong PHASE:$PHASE" ;; esac fi ;; esac
Правила firewall. Для общих таблиц пишем в момент pre-up и post-down, для NAT - в post-up и pre-down.

# cat /etc/network/scripts/autoroute #!/bin/sh # Script for cron to monitor WAN interfaces # and (in future) SQUID status . /etc/network/scripts/functions CURRENT_ROUTE_DEV=`ip route show / grep default / awk '{print $5}'` unset ROUTE_GOOD PING_RESULTS="" for i in $IFWAN; do if [ -z $ROUTE_GOOD ]; then PING_RESULT=`ping -c$PING_COUNT -q $HOST_TO_PING -I $i / grep 'packet loss' / awk '{print $6}'` # If no route t host then set to 100% loss if [ -z $PING_RESULT ]; then warn "$0 No route to host $HOST_TO_PING on $i" PING_RESULT='100%' fi if [ $PING_RESULT = '0%' ]; then ROUTE_GOOD=$i if [ -z $CURRENT_ROUTE_DEV ]; then log "$0 Adding default route to $i" cmd route add default gw `cat $DHCPLIB/routers.$i` elif [ $CURRENT_ROUTE_DEV != $i ]; then log "$0 Change default route from $CURRENT_ROUTE_DEV to $i" cmd route del default cmd route add default gw `cat $DHCPLIB/routers.$i` fi else log "$0 loss $PING_RESULT on $i" fi fi PING_RESULTS="$PING_RESULTS $PING_RESULT" done if [ -z $ROUTE_GOOD ]; then warn "$0 lost all internet connections ($PING_RESULTS loss)" fi
Тут всё просто: пингуем в порядке приоритета. Нашли лучший - переключаемся. Если что, пишем в лог.

Ну и напоследок
# cat /etc/cron.d/autoroute PATH="/usr/bin:/bin:/usr/sbin:/sbin" */5 * * * * root /etc/network/scripts/autoroute
# cat /etc/logrotate.conf / tail # system-specific logs may be configured here /var/log/network-scripts.log { weekly missingok rotate 7 compress }

Симлинки
/etc/dhcp/dhclient-enter-hooks.d/route-enter -> ../../network/scripts/route-enter /etc/dhcp/dhclient-exit-hooks.d/route-exit -> ../../network/scripts/route-exit /etc/network/if-pre-up.d/firewall -> ../scripts/firewall /etc/network/if-down.d/firewall -> ../scripts/firewall /etc/network/if-up.d/firewall -> ../scripts/firewall /etc/network/if-post-down.d/firewall -> ../scripts/firewall

Ссылки по теме


 Распечатать »
 Правила публикации »
  Написать редактору 
 Рекомендовать » Дата публикации: 06.12.2013 
 

Магазин программного обеспечения   WWW.ITSHOP.RU
Stimulsoft Reports Server Team 10 users
IBM DOMINO COLLABORATION EXPRESS AUTHORIZED USER ANNUAL SW SUBSCRIPTION & SUPPORT RENEWAL
CAD Import .NET Professional пользовательская
Quest Software. Toad for Oracle Development Suite
Allround Automation Direct Oracle Access Standard license
 
Другие предложения...
 
Курсы обучения   WWW.ITSHOP.RU
 
Другие предложения...
 
Магазин сертификационных экзаменов   WWW.ITSHOP.RU
 
Другие предложения...
 
3D Принтеры | 3D Печать   WWW.ITSHOP.RU
 
Другие предложения...
 
Новости по теме
 
Рассылки Subscribe.ru
Информационные технологии: CASE, RAD, ERP, OLAP
CASE-технологии
OS Linux для начинающих. Новости + статьи + обзоры + ссылки
Реестр Windows. Секреты работы на компьютере
Один день системного администратора
Каждый день новые драйверы для вашего компьютера!
Компьютерная библиотека: книги, статьи, полезные ссылки
 
Статьи по теме
 
Новинки каталога Download
 
Исходники
 
Документация
 
 



    
rambler's top100 Rambler's Top100