Переключения между провайдерами интернета на Debian 7 из песочницы
В последних дистрибутивах 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
При манипуляциях с интерфейсами через 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
Настройки
Тут всё должно быть понятно. Интерфейсы LAN, WAN можно дописывать сколько угодно. В списке WAN первый — самый приоритетный, далее по убыванию.
Отдельно файл с функциями.
Тут мы имеем:
— импорт настроек из /etc/default/network-scripts
— ведение логов (log, warn),
— запуск команд с записью в лог параметров и результатов работы
— update_local_redirect() добавляет маршруты на 80 порт мимо transparent proxy
— update_squid() добавляет правило для самого transparent proxy (запускается в /etc/init.d/squid3 — это единственный системный скрипт, в который пришлось влезть)
Тут и далее используется технология, придуманная мной несколько лет назад с переменными $ADD и $INS для iptables. Позволяет писать правило только в одном месте, и потом его добавлять-удалять, изменяя только эти переменные.
— Сохраняем new_routers и new_ip_address в файл (потом понядобятся)
— default route разрешаем только для приоритетного интерфейса
— Добавляем static route для сайтов с биллингом провайдеров. Локалка провайдера мне не нужна, но её тоже можно добавить. Идентификация по DNS серверам.
— для режима RENEW добавил перенастройку (если вдруг у провайдера что-то изменится), но пока не тестировал.
Правила firewall. Для общих таблиц пишем в момент pre-up и post-down, для NAT — в post-up и pre-down.
Тут всё просто: пингуем в порядке приоритета. Нашли лучший — переключаемся. Если что, пишем в лог.
Ну и напоследок
Симлинки
/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