Как оказалось, в гигабитном роутере TP-LINK TL-WR1042ND нет управления при помощи консоли. Но роутеры, как известно, иногда виснут. Точнее, сам роутер продолжает работать и откликаться на команды управления из админки и VPN показывает, что он подключен, но интернет при этом не доступен. Иногда это происходит по вине самого устройства, иногда проблемы со стороны провайдера, и перезагрузка часто решает проблему. При чем, желательно, чтобы это происходило автоматически. Поэтому было принято решение перегружать роутер при помощи HTTP GET запроса…
После непродолжительного исследования были найдены такие команды:
Разорвать VPN соединение:
http://login:pass@192.168.0.1/userRpm/StatusRpm.htm?Disconnect=Disconnect&wan=1
Подключить VPN:
http://login:pass@192.168.0.1/userRpm/StatusRpm.htm?Connect=Connect&wan=1
Перезагрузить роутер:
http://login:pass@192.168.0.1/userRpm/SysRebootRpm.htm?Reboot=1
Но, как оказалось, управлять этими командами роутером напрямую не получается. Они работают только при авторизации в админке роутера через браузер и то только можно увидеть их выполнение с помощью firebug, а напрямую, при вводе в адресную строку работает только команды дисконнекта/коннекта VPN. Команды срабатывают, но при этом все равно выдается ошибка. Перезагрузить роутер таким образом не получается.
Мгновенно выскакивает «You have no authority to access this router!» и ничего не происходит.
Самое интересное, что так:
http://login:pass@192.168.0.1/userRpm/StatusRpm.htm?Disconnect=Disconnect&wan=1
выдает ту же ошибку, но с некоторой задержкой, а запрос выполняется — т.е. wan отключается.
При этом в админку входит по ссылке с прописанной авторизацией: http://login:pass@192.168.0.1 и управление из админки дальше работает!
Перезагрузка из Linux
Меня больше интересовала перезагрузка из линукса, но такая команда не срабатывала:
wget --http-user=login --http-password=pass --post-data="reboot=true" http://192.168.0.1/userRpm/SysRebootRpm.htm
ошибка:
Connecting to 192.168.0.1:80... connected. HTTP request sent, awaiting response... 401 N/A Reusing existing connection to 192.168.0.1:80. HTTP request sent, awaiting response... 200 No headers, assuming HTTP/0.9 Length: unspecified Saving to: `SysRebootRpm.htm'
К тому же, при помощи wget не удавалось даже выполнить Disconnect/Connect VPN.
На русском форуме TP-LINK была открыта тема, но в результате обсуждения, решения найти не удалось.
Английская техподдержка на запрос «How i can reboot my device by bash script?»
ответила следующее: «this is not possible to reboot devices in a such way».
Ticket#2013101610000131
Решение все же было найдено. Не вдаваясь в подробности скажу что роутер при GET запросе проверяет:
- Http basic авторизацию.
- User-Agent браузера.
- Корректное поле рефер, которое всегда будет просто http://IP адресом роутера, т.к. роутер использует редиректы.
Cookie для авторизации не используются.
С этим всем отлично справляется команда curl.
Скрипт перезагрузки роутера
Итак, привожу скрипт перезагрузки роутера, который у меня получился:
#!/bin/sh WATCHED_IP="8.8.8.8" ROUTER_IP="192.168.0.1" USERNAME="login" PASSWORD="pass" # watch for remote host ping -q -c 1 "$WATCHED_IP" > /dev/null && exit # exit if router is down ping -q -c 1 "$ROUTER_IP" > /dev/null || exit curl --basic --user "$USERNAME:$PASSWORD" -A "Mozilla/4.73 [en] (X11; U; Linux 2.2.15 i686)" --refer "http://$ROUTER_IP" "$ROUTER_IP/userRpm/SysRebootRpm.htm?Reboot=reboot"
Соответственно, скрипт реконнекта VPN:
#!/bin/sh WATCHED_IP="8.8.8.8" ROUTER_IP="192.168.0.1" USERNAME="login" PASSWORD="pass" # watch for remote host ping -q -c 1 "$WATCHED_IP" > /dev/null && exit # exit if router is down ping -q -c 1 "$ROUTER_IP" > /dev/null || exit curl --basic --user "$USERNAME:$PASSWORD" -A "Mozilla/4.73 [en] (X11; U; Linux 2.2.15 i686)" --refer "http://$ROUTER_IP" "$ROUTER_IP/userRpm/StatusRpm.htm?Disconnect=Disconnect&wan=1" #sleep 1 curl --basic --user "$USERNAME:$PASSWORD" -A "Mozilla/4.73 [en] (X11; U; Linux 2.2.15 i686)" --refer "http://$ROUTER_IP" "$ROUTER_IP/userRpm/StatusRpm.htm?Connect=Connect&wan=1"
Поставил в cron скрипт реконнекта при отсутствии пинга dns гугля — проверка каждые 3 минуты.
Скрипт перезагрузки проверяет наличие интернета каждые 15 минут.
login:pass, конечно, нужно будет поставить свои. Файлы скриптов назвать, например, tplink_reboot.sh и tplink_reconnect.sh, сохранить на сервере, дать права на выполнение и добавить в планировщик.
Уже пару раз выручило:
tplink_reconnect.zip
tplink_reboot.zip
PS:
на форуме https://forum.tp-linkru.ru Scorokhod поделился своим вариантом перезагрузки роутера при помощи WGET, за что ему огромное спасибо:
wget --http-user=%login% --http-password=%password% --user-agent="Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36" --referer=http://%router_ip%/userRpm/SysRebootRpm.htm http://%router_ip%/userRpm/SysRebootRpm.htm?Reboot=1
Вместо «login», «password» и «router_ip» подставить соответственно логин, пароль и IP маршрутизатора без кавычек и процентов 
WGET для Windows можно взять здесь: http://gnuwin32.sourceforge.net/packages/wget.htm, качать нужно «Complete package, except sources — Setup».
Перезагрузка из Windows
Готовая сборка Wget + Bat скрипт для перезагрузки (только перегружает):
скачать tplink_reboot_wget.zip (подходит для большинства моделей Tplink, не только WR1042ND)
Перезагрузка из Android
(спасибо за этот код neolead)
Для андроид в данном изложении требуется root. Если нет рута.. то в конце checknet заменить на step1
—manual
Requirements:
Установить Busybox https://play.google.com/store/apps/deta … on.busybox
и Android Terminal emulator https://play.google.com/store/apps/deta … ndroidterm
—to do list
Перемонтировать/system на запись «su -c mount rw,remount /system»
Поместить допустим в /system/script,»su -c chmod 0777 /system/script/»
Дать скрипту права на исполнение «su -c chmod 0755 /system/script/ping2.sh»
Добавить в автозапуск в настройках терминала.
у меня работает в машине как переподключение,затем перезагрузка wifi после трёх фейлов…
-----ping2.sh
#!/system/bin/sh
pingip=8.8.8.8
login=admin #Username
password=admin #Password
router_ip=192.168.0.1 #Ip of router
sleep_time=30 #Time to next check
sleep_rbt_time=70 #Time to waiting of reboot
f1=10 #First pause in sec
f2=30 #Second pause in sec
increment=0
b64_auth=$(echo $login:$password | base64|rev|cut -c 2-|rev)
network=toyota #SSID name of wifi
while true
do
function checknet()
{
ssid=0
while [ "$ssid" != "$network" ]
do
ssid=$(su -c dumpsys wifi|grep "* ID:"|cut -f 2 -d \")
echo ssid=$ssid
echo network=$network
if [ "$ssid" = "$network" ]; then
echo "Correct Wifi Network"
else
echo "False Wifi Network,press Enter key"
read -rs
fi
done
}
function slp()
{
increment=0
echo "will sleep $sleep_time sec"
sleep $sleep_time #check again
}
function wifi_conn()
{
echo modem reconnect
printf "GET /userRpm/StatusRpm.htm?Disconnect=Disconnect&wan=1 HTTP/1.0\r\nReferer: http://$router_ip/userRpm/StatusRpm.htm\r\nUser-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.1.1650.63 Safari/537.36\r\nAccept: */*\r\nHost: $router_ip\r\nConnection: Keep-Alive\r\nAuthorization: Basic $b64_auth=\r\n\r\n"|nc -w 5 -i 1 $router_ip 80 >/dev/nul
printf "GET /userRpm/StatusRpm.htm?Connect=Connect&wan=1 HTTP/1.0\r\nReferer: http://$router_ip/userRpm/StatusRpm.htm\r\nUser-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.1.1650.63 Safari/537.36\r\nAccept: */*\r\nHost: $router_ip\r\nConnection: Keep-Alive\r\nAuthorization: Basic $b64_auth=\r\n\r\n"|nc -w 5 -i 1 $router_ip 80 >/dev/nul
}
function wifi_rst()
{
#echo LOGIN:$b64_auth=
increment=$(( $increment +1 ))
echo Reboot Times=$increment
if [ "$increment" -eq 3 ]; then
echo "We Already Reboot = $increment times"
echo "We Stop Rebooting"
read -rs $'Press any key to continue monitoring...\n' -n1 key
else
printf "GET /userRpm/SysRebootRpm.htm?Reboot=1 HTTP/1.0\r\nReferer: http://$router_ip/userRpm/SysRebootRpm.htm\r\nUser-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.1.1650.63 Safari/537.36\r\nAccept: */*\r\nHost: $router_ip\r\nConnection: Keep-Alive\r\nAuthorization: Basic $b64_auth=\r\n\r\n"|nc -w 5 -i 1 $router_ip 80 >/dev/nul
echo "Now reboot request was send,will sleep $sleep_rbt_time sec"
sleep $sleep_rbt_time
fi
}
checknet
if ping -c 1 $pingip >/dev/null
then
echo "all good step 1"
slp
else
if ping -c 1 $router_ip >/dev/null
then
echo Router is pinging - channel is down
else
echo Router is down - channel is down
increment = 3
wifi_rst
fi
echo Bad Ass step 1 - will wait $f1 sec!
sleep $f1 #give it a few seconds to complete
fi
if ping -c 1 $pingip >/dev/null
then
echo "all good step 2"
slp
else
echo Bad Ass step 2 - will wait $f2 sec!
sleep $f2 #give it a few seconds to complete
fi
if ping -c 1 $pingip >/dev/null
then
echo "all good step 3 "
slp
else
wifi_conn
echo Bad Ass step 3 - Reconnect!
wifi_conn
fi
if ping -c 1 $pingip >/dev/null
then
echo "all good step 4 "
slp
else
echo Bad Ass step 3 - Reconnect!
wifi_rst
fi
done
Скетч Arduino для плат на базе микроконтроллера ESP32
(спасибо за этот код p-a-h-a)
#include <WiFi.h>
#include <HTTPClient.h>
const char* IP_port = "http:// 192. 168. 0.1:80"; // Убрать пробелы, заменить на свой адрес
#define RouterLogin "admin"
#define RouterPassword "admin"
void setup() {
Serial.begin(115200);
WiFi.begin("ssid", "pass");
while (WiFi.status() != WL_CONNECTED) {
delay(500); Serial.print(".");
}
HTTPClient http;
http.begin(String(IP_port) + "/userRpm/SysRebootRpm.htm?Reboot=1");
http.setAuthorization(RouterLogin, RouterPassword);
http.addHeader("User-Agent","ESP32 wrower");
http.addHeader("Referer", String(IP_port) + "/userRpm/SysRebootRpm.htm");
Serial.printf("[HTTP] GET...code: %d\n", http.GET());
// Serial.println(http.getString()); // Выдаст вебстраничку ответа
http.end();
}
void loop() {}
Моему домашнему роутеру TL-WR940N уже не первый год. Работает он практически без нареканий, но иногда случаются зависания. При этом сам роутер не перегревается. После сброса питания снова работает великолепно, а иногда достаточно просто перезапустить соединение PPOE в web-интерфесе. Одна только в этом проблема, что в момент зависания меня часто не бывает дома, перезагрузить его некому, а доступ к домашнему компьютеру нужен. Над решением этой проблемы я задумался давно.
Одним из вариантов решения вопроса было приобретение китайской GSM розетки, которая прилетела из поднебесной с браком, и больше заказывать ее я не стал.
Встал вопрос, а может можно перегружать роутер командой с компьютера. Стоит отметить, что компьютер у меня включен почти круглосуточно. Ссылку на страницу перезагрузки я нашел довольно быстро. И тут возникла еще одна проблема, а как провести аутентификацию для запуски перезагрузки. Были рассмотрены решения под Linux, но у меня Windows. Был еще вариант с нестандартной прошивкой, но он тоже не пригодился. Потратив еще некоторое время, мне удалось побороть и эту проблему с помощью внешней утилиты wget. Скачать которую можно тут .
Результатом изысканий стал небольшой командный файл, который я включил в автозагрузку своего компьютера. Его задача каждые 10 минут проверить командой ping доступность какого-либо интернет ресурса. Если эта команда завершалась неудачей, то на роутер с помощью wget должна быть отправлена команда перезагрузки. Затем подождать 2 минуты, и снова проверять связь.
Вот текст моего командного файла r_test.bat:
@echo off
set router_ip=192.168.0.1
set test_adress=8.8.8.8
set routeruser=admin
set routerpassword=admin
:start_test
ping -n 1 %test_adress%
if %errorlevel%==1 (
echo ERROR -> REBOOT
"c:\Program Files (x86)\GnuWin32\bin\wget.exe" --http-user=%routeruser% --http-password=%routerpassword% --user-agent="Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.63 Safari/537.36" --referer=http://%router_ip%/userRpm/SysRebootRpm.htm http://%router_ip%/userRpm/SysRebootRpm.htm?Reboot=1
del SysRebootRpm.htm*.*
TIMEOUT /T 120
)
TIMEOUT /T 600
goto start_test
Отличное решение! У кого мобильный свисток+роутер знают как это «мучительно больно», если это все работает вне быстрой досягаемости .
Я в декабре нашел подобное решение на 10$-ой вайфай розетке SONOFF® S20.

Она перешивается в среде Arduino ide 1.8.5 следующим скриптом:
Код:
#include <ESP8266WiFi.h>
#include <ESP8266Ping.h>
const char* ssid = «ssid»; // подставить название своей сети WiFi
const char* password = «password»; //подставить пароль свой сети WiFi
//IPAddress ip(192, 168, 1, 70); //Node static IP
//IPAddress gateway(192, 168, 0, 1);
//IPAddress subnet(255, 255, 255, 0);
//const char* remote_host = «www.ya.ru»; //адрес для пинга
const IPAddress remote_ip(87, 250, 250, 242); // адрес для пинга
unsigned long previousMillis = 0;
const long interval = 300; //интервал между пингами в сек
const long T_ROUTER = 60; // время ожидания загрузки роутера в сек
const long T_RELAY = 5; // задержка от выключения реле до включения в сек
int PIN_RELAY = 12;
int PIN_LED = 13;
int PIN_BUTTON = 0;
int COUNT_PING = 0; //количество попыток при отсутствии пинга (не задается)
int COUNT_PING_MAX = 2; //максимальное количество отсутствия пинга до перезагрузки роутера
int COUNT_WIFI = 0; //счетчик попыток подключения к WiFi
int COUNT_WIFI_MAX = 60; //300; // Таймаут до перезагрузки роутера при отсутствии WiFi в сек
void setup()
{
pinMode(PIN_LED, OUTPUT);
pinMode(PIN_RELAY, OUTPUT);
pinMode(PIN_BUTTON, INPUT);
digitalWrite(PIN_RELAY, HIGH);
digitalWrite(PIN_LED, LOW);
Serial.begin(115200);
delay(10);
attachInterrupt(PIN_BUTTON, Click, FALLING);
}
void ConnectWIFI()
{
Serial.println(«Подключаюсь к WiFi»);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
// WiFi.config(ip, gateway, subnet);
while (WiFi.status() != WL_CONNECTED)
{
if (COUNT_WIFI <= COUNT_WIFI_MAX)
{
COUNT_WIFI++;
}
else
{
Serial.println();
Relay(); //перезагружаемся так как нет подключения к WiFi
Serial.println(«Подключаюсь к WiFi»);
}
//Serial.println(WiFi.status());
digitalWrite(PIN_LED, !digitalRead(PIN_LED)); //моргаем зеленым светодиодом
delay(1000);
Serial.print(".");
}
COUNT_WIFI = 0; // сбрасываем счетчик попыток подключения к WiFi
Serial.println();
Serial.print(«WiFi подключен, ip: „);
Serial.println(WiFi.localIP());
//Serial.println(WiFi.status());
digitalWrite(PIN_LED, LOW); // зажигаем зеленый светодиод
COUNT_PING = 0; // сбрасываем счетчик неуспешных пингов
}
void Relay()
{
if (digitalRead(PIN_RELAY) == HIGH)
{
digitalWrite(PIN_RELAY, LOW); //отключаем питание на розетке
Serial.println(“Реле ВЫключено»);
}
delay(T_RELAY*1000);
digitalWrite(PIN_RELAY, HIGH); //включаем питание на розетке
Serial.println(«Реле Включено, ждем загрузки роутера»);
delay(T_ROUTER*1000); // ждем загрузки роутера
COUNT_PING = 0; // сбрасываем счетчик неуспешных пингов
COUNT_WIFI = 0; // сбрасываем счетчик попыток подключения к WiFi
previousMillis = 0;
}
void Click()
{
digitalWrite(PIN_RELAY, LOW); //отключаем питание на розетке
Serial.println(«Реле выключено кнопкой»);
}
void loop()
{
if (WiFi.status() != WL_CONNECTED) // нет подключения к WiFi
{
ConnectWIFI(); //подключаемся к WiFi
}
unsigned long currentMillis = millis();
if (((currentMillis — previousMillis) >= interval*1000) && (digitalRead(PIN_RELAY) == HIGH) && (WiFi.status() == WL_CONNECTED))
{
previousMillis = currentMillis;
Serial.print(«Попытка пинга: „);
//Serial.println(remote_host);
Serial.println(remote_ip);
//if(Ping.ping(remote_host))
if (Ping.ping(remote_ip))
{ //пинг есть
Serial.println(“Пинг есть!!»);
COUNT_PING = 0;// сбрасываем счетчик неуспешных пингов
} else
{ // пинга нет
Serial.print(«Пинг отсутствует :( „);
COUNT_PING ++;
Serial.println(COUNT_PING);
}
}
if (COUNT_PING >= COUNT_PING_MAX) // если превышено количество попыток пинга перезагружаем роутер
{
Relay();
}
if (digitalRead(PIN_RELAY) == LOW) // нажата кнопка, перезагружаем роутер
{
Relay();
}
}
Суть работы заключается в следующем. Розетка подключается к домашней сети WiFi и с периодом 5 минут пингует сервер яндекса. При отсутствии пинга более двух периодов по 5 минут розетка отключает питание на 5 секунд, далее ждет 1 минуту для загрузки роутера и пытается пинговать опять. При отсутствии подключения к WiFi, так же перезагружает роутер.
При нажатии на кнопку, так же происходит отключение питания на 5 секунд для ручной перезагрузки роутера. Все временные интервалы можно настроить на свой вкус.
А это решение еще проще, но в копилку общих знаний думаю может быть кому тоже пригодиться.
Все подробности можно найти у автора отзыва на сайте mysku*ru. Я заказал и жду с бангуда розетку и с алиэкспресс адаптер-конвертор для прошивки.
Skip to content
Below is an example of the TP-Link router reboot script, I will test it on TL-WR720N 2.0 from Ubuntu Server.
#!/bin/sh ROUTER_IP="192.168.24.174" USERNAME="admin" PASSWORD="admin" # exit if router is down ping -q -c 1 "$ROUTER_IP" > /dev/null || exit curl --basic --user "$USERNAME:$PASSWORD" -A "Mozilla/4.73 [en] (X11; U; Linux 2.2.15 i686)" --refer "http://$ROUTER_IP" "$ROUTER_IP/userRpm/SysRebootRpm.htm?Reboot=reboot"
The contents of the script will be placed in a new file, for example, using the nano editor (“CTRL+X” to exit and “y” to save the changes):
nano file.sh
And make it executable:
chmod 777 file.sh
After this, we execute:
./file.sh
Similarly, you can perform other functions instead of rebooting.