Я тут периодически пишу про всякие штуки, с использованием shell-скриптов и разных linux-утилит - в частности, чтобы лишний раз продемонстировать, что в линуксе не обязательно требуется "найти программу которая умеет делать ХХХХХ" - во многих случаях у вас уже есть всё необходимое, нужно только знать как использовать.
Вот, например, такая задача. У меня выход в интернет через роутер Keenetic. Роутеры эти неплохие, умеют, в частности, вести контроль работоспособности нескольких подключений, автоматически переключаться между ними.
Отвалилось соединение по каналу А - переходим на канал Б. Восстановилось - переходим обратно. Очень удобная функция.
До недавнего времени работало идеально, в том смысле что всё происходило само собой, и об обрыве канала А я узнавал только из воплей в местном чате.
Но с некоторого времени провайдер Б начал блокировать что не надо, и создавать проблемы на ровном месте, а поэтому потребовалось принимать некоторые меры безопасности.
Но для этого надо отлавливать факт переключения. И как это сделать, если роутер не умеет об этом как-либо оповещать?
Первый вариант был на основе анализа маршрута трассировки трафика. Схема рабочая, но проблема в том, что сами провайдеры меняют свои маршруты, и постоянно поддерживать актуальность, что к чему относится, порядком надоело.
Но роутер понимает telnet! А там - нечто вроде CLI-админки, где с помощью тех или иных команд можно узнать текущее подключение, или сделать что-нибудь еще.
Нужно только написать скрипт, который будет этим заниматься.
Но для начала - нужно зайти вручную:
telnet 192.168.1.1 Trying 192.168.1.1... Connected to 192.168.1.1. Escape character is '^]'. Login: XXXXX Password: ******** THIS SOFTWARE IS A SUBJECT OF KEENETIC LIMITED END-USER LICENCE AGREEMENT. BY USING IT YOU AGREE ON TERMS AND CONDITIONS HEREOF. FOR MORE INFORMATION PLEASE CHECK https://keenetic.com/legal (config)> show internet status enabled: yes reliable: yes gateway-accessible: yes dns-accessible: yes host-accessible: yes internet: yes gateway: interface: PPPoE0 address: 0.0.0.0 failures: 0 accessible: yes excluded: yes hosts: host: name: google.com failures: 0 resolved: no accessible: no ....
Ключевая информация тут interface: PPPoE0 - это и есть канал А.
Канал Б называется по-другому.
Оставалось написать пару скриптов. Первый из них, get_current_interface, - использует программу expect, которая работать примерно как chat для ppp: ожидает определенные строки и выводит другие в ответ.
#!/usr/bin/expect -f spawn telnet 192.168.1.1 23 expect "Login:" send "XXXXXX\r" expect "Password:" send "passssss\r" expect "(config)>" send "show internet status\r" expect -re {interface:\s+([^\n\r ]+)} set log $expect_out(1,string) set fh [open "/var/log/current_gw" "w"] puts $fh $log close $fh
В данном случае скрипт вводит логин, пароль, команду, в строке #10 вылавливает название интерфейса, в строке #11 присваивает это значение переменной log, потом открывает файл, записывает в него текущее значение и завершает работу.
Теперь в файле /var/log/current_gw находится название текущего интерфейса.
Осталось написать скрипт, который будет всё это запрашивать:
#!/bin/bash data_file=/var/log/current_gw # получим старое значение old=$(cat $data_file) # получим новое значение get_current_interface > /dev/null new=$(cat $data_file) if [ "x$old" != "x$new" ];then if [ "x$new" = "xPPPoE0" ];then # что-то делаем полезное 1 elif [ "x$new" = "xCdcEthernet0" ];then # что-то делаем полезное 2 fi fi
Теперь вызываем его по крону, и проверяем, что изменилось. Если изменилось — принимаем меры, если нет — ничего делать не надо.
В принципе по той же схеме можно много чего из роутера извлечь, если потребуется. И не только из него — мало ли, где требуется интерактивное взаимодействие со вводом команд...
