IT News: Digital Camera, OS, Laptop, Smartphone, Smart TV, Sound...

The Author's Project by Valeri N.Kravchuk
Сайт проверен Dr.Web
Меню сайта
  • Главная страница
  • Информация о сайте
  • Дневник
  • Каталог файлов
  • Обратная связь
  • Каталог сайтов
  • FAQ
  • Доска объявлений
  • Форум
  • Фотоальбом
  • Категории раздела
    Автомобильные гаджеты, ремонт... [220]
    Безопасность IT [484]
    Блоки питания, Power Banks, зарядки... [489]
    Видеорегистраторы [220]
    Гаджеты для спорта и здоровья... [190]
    Гаджеты, аксессуары... [625]
    Измерительная техника, инструменты [444]
    Накопители данных [226]
    Нетбуки, Ноутбуки, Ультрабуки [679]
    Мультиварки, блендеры и не только... [158]
    Планшеты [758]
    Радар-детекторы [26]
    Роботы-пылесосы [37]
    Своими руками [353]
    Сети, сетевые технологии, оборудование... [267]
    Смартфоны [4963]
    Фотокамеры, объективы, искусство фотографии.. [542]
    Умный дом [47]
    Электронные книги [95]
    CB, LPD, PMR- связь... [169]
    DECT, IP-телефоны [18]
    Drones, boats, cars... [108]
    electric cars [35]
    GPS-навигаторы, трекеры... [51]
    Linux и не только [4380]
    mini computers и не только... [409]
    News IT, Это интересно, ликбез... [1112]
    Smart TV, UltraHD, приставки, проекторы... [414]
    Smart Watch [263]
    Sound: наушники, плееры, усилители... [616]
    Windows 10... [298]
    Windows 11 [28]
    Погода

  • Метеорадар БРЕСТ
  • Погода в Бресте от www.yr.no

    Яндекс.Погода БРЕСТ

  • Интересные ссылки

    COMPIZOMANIA

    Наш опрос
    Оцените мой сайт
    Всего ответов: 1338
    Статистика
    Анализ веб сайтов

    Яндекс.Метрика

    Рейтинг@Mail.ru Яндекс цитирования

    Russian America Top. Рейтинг ресурсов Русской Америки.

    eXTReMe Tracker

    Правильный CSS!


    Онлайн всего: 3
    Гостей: 3
    Пользователей: 0
    Locations of visitors to this page
    Форма входа
    Главная » 2013 » Октябрь » 29 » Переключения между провайдерами интернета на Debian 7
    17:27
    Переключения между провайдерами интернета на Debian 7

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

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

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

    Логика на первый взгляд простая:
    — пингуем какой-нибудь хост по очереди через разные интерфейсы
    — если пинг нестабильный, переключаемся на резервный канал.
    Вот только в реализации была поставлена цель сделать всё максимально гибко, например не ограничивать количество потенциальных провайдеров и впоследствии делать минимум телодвижений для перенастройки.
    Для начала посмотрим какие плюшки уже есть в системе
    В папке /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 
    Категория: Linux и не только | Просмотров: 668 | Добавил: laptop | Рейтинг: 0.0/0
    Всего комментариев: 0
    Добавлять комментарии могут только зарегистрированные пользователи.
    [ Регистрация | Вход ]
    Волк слабее льва и тигра, но в цирке волк не выступает!
    Волк слабее льва и тигра, но в цирке волк не выступает!
    Волк - единственный из зверей, который может пойти в бой на более сильного противника.
    Если же он проиграл бой, то до последнего вздоха смотрит в глаза противника. После этого умирает...

    Праздники сегодня

    Поиск
    Календарь
    Архив записей
    Друзья сайта
  • Официальный блог
  • JEEP - the best! Mercedes - the best! Автомобильный портал города Бреста: технические характеристики с фото, авторынок, автоспорт...
    Наша кнопка
    IT новости с моего лаптопа...

    Внимание!
    Администратор сайта laptop.ucoz.ru не несет ответственности за содержание рекламных объявлений. Все используемые на сайте зарегистрированные товарные знаки принадлежат своим законным владельцам! Используемая со сторонних источников информация публикуется с обязательными ссылками на эти источники.
    Copyright Valeri N.Kravchuk © 2007-2024