Because a FRITZ!Box did not work reliably on a DS-Lite connection, I wanted to reboot it automatically. With the current FRITZ!OS 7.29, many scripts and tips from the internet no longer work. This one does.
Prerequisites
This script requires curl and iconv to be installed on the OpenWRT router:
1 2 3 |
# install dependencies opkg update opkg install curl iconv |
Moreover, login credentials with permissions to reboot the FRITZ!Box router are required.
Since the new FRITZ!OS, the root user is called „fritz1234“, where 1234 is a random number. The password is printed on the bottom of the box as usual.
You can either look up the root username in the system menu or create a new account there.
Disclaimer & Credits
- TR-064 commands: @nicoh88
- Session login: @colinardo
- Wireshark-ing the webinterface: @luani
- AVM service interface: PDF
The script
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
#!/bin/sh # # Control upstream FRITZ!Box # # https://github.com/nicoh88/cron_fritzbox-reboot # https://administrator.de/tutorial/informationen-aus-dem-webinterface-einer-fritzbox-via-shellscript-auslesen-214598.html # https://avm.de/fileadmin/user_upload/Global/Service/Schnittstellen/AVM_Technical_Note_-_Session_ID_deutsch_Dez2020.pdf # # 2022 luani.de FRITZ_HOST="fritz.box" FRITZ_USER="fritz1234" FRITZ_PASSWORD="" # --- config done --- ACTION="$1" SID="0" # check prerequisites if [ ! -x "$(command -v curl)" ]; then echo "fritz-control error: curl is not installed, exiting" >&2 exit 1 fi if [ ! -x "$(command -v iconv)" ]; then echo "fritz-control error: iconv is not installed, exiting" >&2 exit 1 fi # Challenge/response login sid_login() { challenge=`curl --insecure -s "https://${FRITZ_HOST}/login_sid.lua" | sed 's/.*\([[:alnum:]]*\)<\/Challenge>.*/\1/'` md5_key=`echo -n "$challenge-$FRITZ_PASSWORD" | iconv -f ISO8859-1 -t UTF-16LE | md5sum -b | awk '{print substr($0,1,32)}'` SID=`curl --insecure -s -G -d "username=$FRITZ_USER" -d "response=$challenge-$md5_key" "https://${FRITZ_HOST}/login_sid.lua" | sed 's/.*\([[:alnum:]]*\)<\/SID>.*/\1/'` if [ $SID -eq 0 ] 2>/dev/null; then echo "Login failed (received empty session id)" >&2 exit 1 fi } sid_logout() { curl --insecure -s -X POST -d "sid=${SID}&xhr=1&no_sidrenew=0" -d "logout=1" "https://${FRITZ_HOST}/index.lua" -o /dev/null } # Enable GUI reboot and submit request sid_reboot() { curl --insecure -s -X POST -d "sid=${SID}&xhr=1" -d "page=reboot" -d "reboot=0" "https://${FRITZ_HOST}/data.lua" -o /dev/null state=`curl --insecure -s -X POST -d "sid=${SID}&xhr=1&no_sidrenew=1" -d "useajax=1" -d "ajax=1" "https://${FRITZ_HOST}/reboot.lua" | sed 's/.*"reboot_state":"\([[:alnum:]]*\)".*/\1/'` logger -t "fritz-control" "Sent LUA action 'reboot' @ '$FRITZ_HOST': reboot_state $state" if [ $state -ne 0 ]; then echo "Reboot failed (received invalid state '$state')" >&2 exit 1 fi } # send TR-064 command send_action() { location="$1" uri="$2" action="$3" response=$(curl --insecure -m 5 --anyauth -u "$FRITZ_USER:$FRITZ_PASSWORD" http://$FRITZ_HOST:49000$location -H 'Content-Type: text/xml; charset="utf-8"' -H "SoapAction:$uri#$action" -d "<!--?xml version='1.0' encoding='utf-8'?--><u:$action xmlns:u="$uri"></u:$action>" -s -o /dev/null -w "%{http_code}") logger -t "fritz-control" "Sent TR-064 action '$action' @ '$FRITZ_HOST': HTTP $response" if [ $response -ne "200" ]; then echo "TR-064 action '$action' failed (received unexpected HTTP status '$response')" >&2 exit 1 fi } # process commands case "$ACTION" in "reboot") send_action "/upnp/control/deviceconfig" "urn:dslforum-org:service:DeviceConfig:1" "Reboot" ;; "reconnect") send_action "/igdupnp/control/WANIPConn1" "urn:schemas-upnp-org:service:WANIPConnection:1" "ForceTermination" ;; "reboot-lua") sid_login sid_reboot sid_logout ;; *) echo "fritz-control usage:" echo -e "\tTR-064: reboot reconnect" echo -e "\tLUA/SID: reboot-lua" exit 1 ;; esac |
Final touches
Modify the lines FRITZ_HOST, FRITZ_USER, FRITZ_PASSWORD to match your environment.
1 2 3 4 5 6 7 8 9 |
# make executable chmod +x fritz-control.sh # TR-064 commands (may not work with all routers, TR-064 could be disabled): ./fritz-control.sh reboot ./fritz-control.sh reconnect # Session/Lua commands (mimics a click in the web interface, probably works): ./fritz-control.sh reboot-lua |
Automation
If you want to automate this, you can use e.g. crontab or extend my watchdog script:
1 2 3 4 5 |
config watchping 'upstream' option enabled '1' option host '8.8.8.8' # ping outside world option timeout '15' option command '/path/to/your/fritz-control.sh reboot-lua' |
Tested with OpenWRT 21.01