Форум Сервер Дома
Продвинутый рестарт (smart reboot) 3G\4G модема Huawei E3372 в режиме Hilink через роутер с прошивкой OpenWrt
OpenWrt — встроенная операционная система, основанная на ядре Linux, и предназначенная, в первую очередь, для домашних маршрутизаторов. Основные компоненты включают в себя ядро Linux, util-linux, uClibc или musl и BusyBox. Размер всех компонентов оптимизирован в связи с тем, что в большинстве домашних маршрутизаторов сильно ограничен объём памяти.
Продвинутый рестарт (smart reboot) 3G\4G модема Huawei E3372 в режиме Hilink через роутер с прошивкой OpenWrt
Об этой эпопее читайте Есть ли жизнь без Ростелекома? Есть! Прощай, Ростелеком! А сейчас расскажу как подключить 3G\4G модем в режиме Hilink к роутеру с OS OpenWrt и настроить бесперебойный доступ в интернет.
Имеется модем, разблокированный под любого оператора Huawei E3372h-153. Модем работает в режиме Hilink (определяется как сетевая карта).
Была задача подключить его к роутеру и раздавать интернет всем устройствам, подключенных к маршрутизатору. Модель роутера не имеет значения. Лишь бы был хотя бы 1 USB порт и прошивка OpenWrt. Ну и нужен доступ в интернет для скачивания необходимых пакетов. Раньше я поднимал точку доступа на смартфоне, а на роутере поднимал Wi-Fi клиента, теперь пользуюсь скриптом для создания локального репозитория пакетов для OpenWRT [WINDOWS].
Заходим по ssh (через Putty, например) в систему роутера и устанавливаем необходимые пакеты. Можно то же самое проделать через web-интерфейс.
opkg update opkg install kmod-usb-net-cdc-ether usb-modeswitch curl reboot
Предварительно нужно отключить NAT в модеме. Для этого подключаем модем к компьютеру, заходим в веб-интерфейс по адресу Для просмотра ссылок Вы должны быть авторизованы на форуме. и настраиваем как на картинке:
Подключаем модем к роутеру.
Дожидаемся перезагрузки роутера и заходим в веб-морду. Нам нужно создать новый интерфейс.
Сеть —> Интерфейсы —> Добавить новый интерфейс.
- Назначаем имя интерфейсу. Имя произвольное.
- Назначаем протокол. DHCP-клиент. Модем сам выдаст роутеру IP-адрес.
- Выбираем наш модем как сетевое устройство, которое определилось в роутере. В моём случае это eth1. У меня уже создан интерфейс с именем МТС, который привязан к eth1, так что не обращайте на это внимания.
- Применяем.
- Далее нам нужно перейти на вкладку «Настройки межсетевого экрана».
- Выбрать зону wan. Она всегда красным цветом.
- Кликнуть на кнопку «Сохранить и применить»
Всё, уже можно пользоваться. Некоторое время. До первого недоумения: «КУДА ДЕЛСЯ ИНТЕРНЕТ. «
Не знаю как обстоят дела у других владельцев 3\4G модемов, но у меня иногда «отваливается интернет». Захожу в веб-морду модема, а там всё ОК. Линк есть, даже трафик бежит. Жидкий, но он есть, а интернета НЕТ.
В 99% помогает простое отключение и включение соединения. В редких случаях нужно перезагружать модем. Но проще передёрнуть модем в USB.
У меня роутер висит на стене, как раз за монитором. Каждый раз заходить в веб-морду модема (вставать и лезть за монитор) как-то лениво. Да и «толстые» торренты качаю иногда.
Что-то надо придумать для автоматического «передёргивания модема».
Что первое пришло в голову — пакет watchcat OpenWrt.
Но там, если «отвалился» интернет тупо перезагружается роутер. А это долго.
По крайней мере мой гигабитный TP-Link TD-W8970 v1.2 перезагружается довольно нерасторопно.
Приходила мысль перешить модем в Stick (классический USB-модем) и рулить им через AT-команды .
Покопал инфу в интернете и пришёл к выводу: встать и передёрнуть модем в роутере — быстрее и проще, чем прошить модем, а потом организовать автоматику через AT-команды.
Решение нашлось. У Huawei-ев в режиме Hilink есть API. Например, если в браузере перейти по ссылке Для просмотра ссылок Вы должны быть авторизованы на форуме. на экране появится ряд чисел
901 5 9 3 0 0 10.111.217.135 212.188.31.152 212.188.31.153 0 2 1 46 5 -1 0 hilink 0 0 0
opkg update opkg install curl
curl -s -X GET http://192.168.8.1/api/monitoring/status
Потратив изрядное количество времени в поиске информации, всё-таки нашёл объяснение такого поведения API модема. Всё дело в безопасности. Чтобы не было несанкционированного доступа к API модема. То есть для нормального ответа API модема нам нужно как-то легализовать свои запросы.
Пишем команду в консоли роутера:
curl -s -X GET http://192.168.8.1/api/webserver/SesTokInfo
SessionID=tJnebnySHLlP+whNsVwHn5yJMFizfddRGJZwH7lea4Es69qnk40CUaYQ0h0jr06EriRBZ8glcZGg/wRuQCPRofm0l1YxFefLhLLZRwX9QO700PIkCkKOB2IxEXPyrGlV tuY0erY9OgnafggIYylBN2mm+cI/mntb
Чтобы API модема нормально принимала команды, нужно предварительно и перед каждой командой запрашивать данные сессии и внедрять содержимое тегов и в тело запросов.
Путём метода «научного тыка», несчётного количества проб и ошибок я написал небольшой скрипт, который позволяет управлять модемом через API.
Пока только пинг гугловского DNS и три варианта реакции на отсутствие ответа.
1. Отключение и включение линка в модеме.
2. Если не помогло — перезагрузка модема.
3. Если и это не помогло — перезагрузка роутера.
Алгоритм пока сырой. Но пользоваться уже можно.
#!/bin/ash # самая первая строка не ошибка! #functions getToken() < SesTokInfo=$(curl -s -X GET http://192.168.8.1/api/webserver/SesTokInfo) #получаем данные export SesInfo=$(echo "$" | grep SesInfo | cut -d ">" -f2 | cut -d "<" -f1) #получаем SesInfo export TokInfo=$(echo "$" | grep TokInfo | cut -d ">" -f2 | cut -d " # checkLink() < export LIMIT=$1 for i in $(seq 0 $LIMIT) do if ping -W 5 8.8.8.8 -c 1 >> /dev/null; then export LinkOFF=0 #uci set system.led_wps.trigger='none' #uci commit #echo "none" > /sys/class/leds/tdw89x0:green:wps/trigger break; else logger "No internet connection. Wait. " sleep 1 fi export LinkOFF=1 done > # getStatusLink() < getToken StatusAll=$(curl -s -X GET http://192.168.8.1/api/monitoring/status -H "Cookie: $SesInfo" -H "__RequestVerificationToken: $TokInfo") export statusLink=$(echo "$" | grep ConnectionStatus | cut -d ">" -f2 | cut -d " # setLinkOFF() < getToken # отключаем соединение curl http://192.168.8.1/api/dialup/mobile-dataswitch -H "Cookie: $SesInfo" -H "__RequestVerificationToken: $TokInfo" -H "Content-Type: application/x-www-form-urlencoded; charset=UTF-8" -H "Referer: http://192.168.8.1/html/home.html" --data "0 " > # setLinkON() < getToken # включаем соединение curl http://192.168.8.1/api/dialup/mobile-dataswitch -H "Cookie: $SesInfo" -H "__RequestVerificationToken: $TokInfo" -H "Content-Type: application/x-www-form-urlencoded; charset=UTF-8" -H "Referer: http://192.168.8.1/html/home.html" --data "1 " > rebootModem() < #reboot getToken curl http://192.168.8.1/api/device/control -H "Cookie: $SesInfo" -H "__RequestVerificationToken: $TokInfo" -H "Content-Type: application/x-www-form-urlencoded; charset=UTF-8" -H "Referer: http://192.168.8.1/html/home.html" --data "1 " logger "3G modem rebooting" > #begin #Проверяем подключен ли модем if [ X"$(ls /sys/class/net | grep eth1)" != X"" ]; then checkLink 1 if [ X"$LinkOFF" == X"0" ]; then if [ -f "/etc/router" ]; then rm -rf /etc/router fi exit 0; else #uci set system.led_wps.trigger='heartbeat' #uci commit #echo "heartbeat" > /sys/class/leds/tdw89x0:green:wps/trigger getStatusLink if [ X"$" == X"901" ]; then setLinkOFF sleep 10 # ждём 10 секунд fi getStatusLink if [ X"$" == X"902" ]; then setLinkON fi fi checkLink 10 if [ X"$LinkOFF" == X"0" ]; then logger "3G modem reconnected" exit 0; else rebootModem fi checkLink 20 if [ X"$LinkOFF" == X"0" ]; then logger "3G modem rebooted" exit 0; else logger "Router reboot" if [ ! -f "/etc/router" ]; then touch /etc/router #uci set system.led_wps.trigger='heartbeat' #uci commit reboot fi fi fi
Итак. Чтобы использовать данный скрипт, нам нужно настроить cron и создать расписание, по которому он будет запускаться.
touch /etc/crontabs/root ln -sf /etc/crontabs/root /etc/crontab /etc/init.d/cron start /etc/init.d/cron enable
Sun Sep 1 07:26:50 2019 cron.info crond[2481]: crond (busybox 1.28.4) started, log level 5
Теперь нам нужно разместить скрипт в файловой системе роутера и создать расписание запуска сценария.
В OpenWrt по-умолчанию в целях экономии размера прошивки нет продвинутого текстового редактора. Только vi с минимальным функционалом. Так что будет проще и быстрее залить готовый файл скрипта в роутер любым удобным способом. Например, WinSCP из-под Windows
Удобнее всего размещать скрипты в каталоге /etc
После копирования файла в файловую систему роутера, нам нужно установить атрибуты скрипта на исполнение. Можно сделать тем же WinSCP.
Осталось написать и запустить задание для cron. Быстрее всего это можно сделать через консоль (Скрипт будет запускаться каждую минуту — значение «*/1»).
echo -e "*/1 * * * * sh /etc/m.sh\n" >> /etc/crontab /etc/init.d/cron restart
P.S. Как я уже упоминал, скрипт написан «на коленке». Есть что оптимизировать и дополнить. Например, добавить мигание индикаторами при обрыве линка. В скрипте эти строки есть, но закомментированы. Если хотите сделать себе индикацию, пишите, указав версию прошивки и модель роутера.
Зайчатки разума
У меня дома подключен интернет от Beeline, но периодически с ним возникают проблемы. Что тому виной — не могу понять. Периодически коннект разрывается, роутеру выдаётся по DHCP новый IP адрес, l2tp отрабатывает, получает свой адрес, но до шлюза через l2tp интерфейс пакеты идут только в одну сторону. Обратно приходит порядка 60 байт чего-то (не успел поймать), затем тишина. Решил написать небольшой простой скрипт, который будет проверять интернет и если его нет более 5ти минут, будет перезагружать роутер.
Скрипт я положил в /opt/inenchecker и выдал права на исполнение (chmod +x /opt/inetchecker):
#!/bin/sh # Rebooting router if internet connection disappeared %limit% seconds ago limit=300 checkcount=2 checkaddress='8.8.8.8' d='/tmp/disconnected' if ! ping -c "$checkcount" "$checkaddress"; then if [ -f "$d" ]; then dtime=`cat "$d"` diff=$(( `date +%s` - $dtime )) if [ "$diff" -gt "$limit" ]; then echo "Last internet connection: $(date -d @"$dtime" "+%F %T"), $diff second ago, rebooting. " reboot fi else echo "Internet connection failed, saving timestamp" date +%s > "$d" fi else if [ -f "$d" ]; then rm $d fi fi
В данном скрипте limit — это ограничение в секундах, т.е. в данном случае 5 минут, checkaddress — адрес, на который будет уходить пинг, а checkcount — количество icmp пакетов пинга. В случае, если пинг не прошел, в /tmp создаётся файл с таймстемпом. Если при повторном запуске выяснилось, что соединение восстановилось и пинг проходит, а текущий таймстемп отличается менее, чем на limit, файл с таймстемпом удаляется. Если таймстемп был позднее, чем limit секунд назад, роутер будет перезагружен. Скрипт прописан в кроне (crontab -e):
Evgeniy Shumilov — evgeniy.shumilov@gmail.com
Generated with bashblog, a single bash script to easily create blogs like this one
Автоматическая перезагрузка роутера на OpenWrt
Есть у меня роутер Wi-Fi TP-Link TL-WR842ND, я в него для большей функциональности, стабильности и прочего зарядил прошивку OpenWrt.
Прошивка OpenWrt имеет массу преимуществ, хоть с ней устройство и работает намного стабильнее, но все-таки подвисания иногда случаются, особенно если клиентов около 5-10 устройств и работа без перезагрузок и через UPS. У меня было пару раз что не выдавались по DHCP IP адреса, лечилось перезагрузкой. Чтобы избежать разных «боков» я решил сделать автоматическую перезагрузку роутера раз в сутки. Можно конечно и реже, но чтобы без мороки мне кажется в самый раз.
Задача: автоматическая перезагрузка роутера через планировщик задач прошивки OpenWrt
Решение: Заходим в вебинтерфейс управления роутером — раздел System — Scheduled Tasks и создаем задачу — перезагружаться в 7:05 каждый день (предварительно не забудьте правильно указать свой часовой пояс и проверить время), время можно выбрать любое нужно (первая цифра минуты, второй столбец часы).
Делаем Submit и перезагружаем роутер классическим способом чтобы изменения вступили в силу.
Все, теперь надеюсь можно вообще забыть где он стоит и никаких разрывов с ноября :-).
Фразы: перезагрузка роутера по расписанию, перезапуск по cron, планировщик задач OpenWrt