Synology 進階: 寫個 shell script 來 reboot router

絕 大 部 分 的 router,都 沒 有 「上 唔 到 網 就 自 動 reboot」這 個 功 能 。這 個 功 能 一 般 叫 做 Keep Alive / Watchdog,在 dd-wrt 裡 面 就 有 。Keep Alive 功 能 其 實 不 一 定 會 reboot 你 的 router 的 ,有 部 分 其 實 只 是 會 redial / reconnect 某 個 連 線 ,例 如 在 PPPoE / VPN 的 情 況 。

要 是 你 的 router 本 身 沒 有 Keep Alive,又 不 能 安 裝 dd-wrt,那 怎 麼 辦 呢 ?其 實 只 要 寫 個 簡 單 的 script 在 電 腦 上 執 行 就 可 以 了 。

要 做 到 Keep Alive 的 效 果 ,首 先 ,你 要 有 一 台 長 開 的 電 腦 來 檢 查 能 不 能 上 網 ;其 次 ,你 的 router 要 支 援 telnet。

一 般 來 說 ,需 要 Keep Alive 的 人 ,就 是 希 望 Internet 長 時 間 不 斷 線 ,那 就 多 數 會 有 長 開 的 電 腦 設 備 了 ,例 如 Server / NAS 之 類 。

所 以 ,今 次 筆 者 就 教 大 家 寫 個 在 Synology NAS 上 面 執 行 的 script 吧 。因 為 Synology 的 操 作 系 統 是 Linux,所 以 我 們 就 一 起 學 學 Linux 的 Shell Script 吧 。

今 次 的 script 分 為 兩 個 部 分 。第 一 部 分 是 檢 查 網 絡 連 線 ,用 簡 單 的 ping 來 做 就 可 以 。如 果 是 想 檢 查 Internet 的 ,ping 一 個 大 型 website 就 可 以 了 (google, yahoo)。如 果 是 想 檢 查 VPN,就 ping VPN 另 一 邊 的 ip address 吧 。

#!/bin/sh
ping -q -c5 google.com > /dev/null
if [ $? -eq 0 ]
then
echo "ok"
else
echo "something is wrong"
fi

上 面 的 script,第 一 行 是 宣 告 這 個 scritp 是 用 什 麼 來 執 行 的 ,這 一 行 不 能 亂 改 。

第 二 行 就 是 一 個 ping 指 令 。後 半 段 的 > /dev/null 就 是 把 輸 出 送 到 null device,意 思 就 是 不 用 在 視 窗 顯 示 出 結 果 ,直 接 丟 掉 吧 。

第 三 行 開 始 ,用 了 一 個 if 來 判 斷 ping 是 否 執 行 成 功 。成 功 的 話 就 輸 出 ok,不 成 功 就 輸 出 something is wrong。

$? 是 一 個 系 統 變 數 ,它 的 值 就 是 上 一 個 指 令 的 執 行 結 果 ,如 果 是 0 就 代 表 執 行 成 功 。非 0 的 值 就 是 不 同 的 錯 誤 代 碼 。

Script 的 第 二 個 部 分 ,就 是 telnet 進 你 的 router 並 且 reboot。這 個 部 分 每 一 台 router 都 會 有 一 點 點 分 別 的 ,但 都 大 同 小 異 。

TL-ER604W

TL-ER604W

這 次 筆 者 示 範 用 的 是 一 台 Tp-link 的 TL-ER604W。這 個 系 列 的 router 的 telnet 算 是 比 較 麻 煩 的 ,除 了 打 開 telnet 連 線 時 要 登 入 之 外 ,要 能 成 功 執 行 reboot command 還 要 先 進 入 所 謂 的 Privileged mode。

首 先 我 們 telnet 進 入 router,用 的 就 是 web interface 一 樣 的 用 戶 名 稱 和 密 碼 。一 般 來 說 ,用 「help」或 者 「?」之 類 的 命 令 就 可 以 把 所 有 支 援 的 指 示 顯 示 出 來 。Router 說 明 書 裡 面 也 應 該 會 有 說 明 的 。

Telnet

Telnet

查 出 reboot 所 需 要 的 指 令 之 後 ,就 可 以 用 shell script 來 實 作 了 。

#!/bin/sh
{
sleep 10
echo admin
sleep 10
echo password
sleep 20
echo enable
sleep 10
echo admin
sleep 10
echo sys reboot
sleep 10
echo Y
sleep 10
echo disable
sleep 10
echo exit
} | telnet 192.168.1.1

上 面 的 script 比 起 之 前 更 簡 單 ,就 是 打 開 telnet 之 後 ,按 照 順 序 把 所 有 的 username、password、command 等 等 一 個 一 個 地 輸 入 進 去 。每 一 個 輸 入 之 間 就 等 待 10 秒 (登 入 那 一 下 會 比 較 慢 ,所 以 是 20 秒 ),確 保 router 有 非 常 足 夠 的 時 間 去 執 行 每 一 個 指 令 。

順 序 解 釋 的 話 ,首 先 是 登 入 名 (admin),然 後 是 登 入 密 碼 (password),然 後 要 進 入 privileged mode (enable),然 後 是 進 入 privileged mode 所 需 要 的 密 碼 (admin),然 後 就 是 reboot 的 指 令 (sys reboot),然 後 要 回 答 yes (Y),然 後 是 exit privileged mode (disable) 和 登 出 telnet (exit)。

但 正 如 我 前 面 說 過 ,你 的 router 的 telnet reboot 程 序 是 不 可 能 和 我 一 樣 的 ,所 以 要 按 照 你 自 己 的 情 況 來 修 改 。

其 實 在 shell script 用 telnet,正 常 人 都 應 該 用 expect 的 (#!/usr/bin/expect)。但 Synology NAS 要 安 裝 expect 比 較 麻 煩 ,升 級 DSM 時 又 可 能 要 重 裝 ,所 以 就 用 回 最 簡 單 的 shell script 算 了 。

將 以 上 兩 個 部 分 合 併 ,就 是 我 們 的 script 了 。

#!/bin/sh
ping -q -c5 google.com > /dev/null
if [ $? -eq 0 ]
then
echo -e "$(date)\t\tok" >> /volume1/homes/admin/log.txt
else
echo -e "$(date)\t\tSomething is Wrong, restart router" >> /volume1/homes/admin/log.txt
{
sleep 10
echo admin
sleep 10
echo password
sleep 20
echo enable
sleep 10
echo admin
sleep 10
echo sys reboot
sleep 10
echo Y
sleep 10
echo disable
sleep 10
echo exit
} | telnet 192.168.1.1
fi

這 個 shell script 會 先 檢 查 能 不 能 ping 通 google.com,如 果 不 能 ,它 就 會 用 telnet 登 入 router 然 後 reboot。

這 樣 的 shell script 當 然 是 當 一 個 cron job 來 執 行 的 ,所 以 那 些 output 應 該 要 另 外 放 入 一 個 log file 的 。

Log file

Log file

在 這 個 例 子 ,我 把 shell script 放 到 admin 帳 戶 的 home 目 錄 。檔 案 名 稱 就 是 restart-router.sh。( script 裡 面 的 log file 也 是 放 在 同 一 個 目 錄 )

在 DSM 5.0 以 後 ,Synology 的 NAS 要 增 加 一 個 cron job 變 得 非 常 之 容 易 。只 要 到 web interface 裡 面 的 control panel >> task scheduler 就 可 以 了 。

Task Scheduler

Task Scheduler

但 十 分 可 惜 的 是 ,Task scheduler 最 頻 密 只 可 以 設 定 成 每 小 時 執 行 一 次 。對 Keep Alive 這 一 類 功 能 來 說 大 概 是 不 夠 頻 密 的 。

Schedule

Schedule

於 是 ,我 們 就 要 ssh 進 入 synology 來 自 行 設 定 cron job 了 。Synology 本 身 是 沒 有 crontab 程 序 (/usr/bin/crontab) 的 ,我 們 要 自 己 去 修 改 crontab (/etc/crontab) 檔 案 。

Crontab

Crontab

在 我 的 crontab 檔 案 之 中 ,最 後 一 行 就 是 剛 剛 Task Scheduler 產 生 的 cron job (在 我 的 例 子 中 就 是 每 小 時 的 01 分 執 行 一 次 )。

要 新 增 一 個 cron job,我 們 可 以 直 接 在 crontab 檔 案 增 加 一 行 。

*/10 * * * * root /volume1/homes/admin/restart-router.sh

要 記 住 ,crontab 檔 案 裡 面 每 一 個 column 都 是 用 一 個 Tab 來 分 隔 的 ,不 能 用 space。在 Who 那 一 個 column (就 是 誰 在 執 行 那 一 個 cronjob),必 須 要 是 root。這 兩 者 搞 錯 了 的 話 ,cronjob 在 synology 重 啟 之 後 就 會 被 清 除 掉 。

上 例 中 */10 的 意 思 是 每 10 分 鐘 執 行 一 次 ,想 5 分 鐘 執 行 一 次 就 把 它 改 成 */5。

儲 存 好 crontab 檔 案 之 後 ,我 們 要 重 啟 一 次 crond 服 務 。

DSM 5.0 或 以 後 :
/usr/syno/sbin/synoservicectl --restart crond
DSM 4.3 或 以 前 :
/usr/syno/sbin/synoservice --restart crond

或 者 你 可 以 像 筆 者 一 樣 ,重 啟 一 次 Synology 就 可 以 了 (可 以 順 道 檢 查 重 啟 後 cronjob 還 在 不 在 )。

最 後 ,筆 者 多 附 上 一 個 D-Link router 的 Telnet reboot 順 序 ,給 諸 君 參 考 吧 。

{
sleep 10
echo admin
sleep 10
echo password
sleep 20
echo util reboot
sleep 5
echo .exit
} | telnet 192.168.1.1

注 : 以 上 TP-Link 和 D-Link router 都 是 使 用 原 廠 firmware 的 。

ctleung張 先 生 ,男 性 ,肖 龍 。
職 業 :I.T. Consultant
簡 介 :不 好 好 讀 書 ;七 尺 差 五 寸 ,手 長 過 膝 ,雙 耳 垂 肩 ;性 寬 和 ,寡 言 語 ,喜 怒 不 形 於 色 。據 說 少 時 曾 斬 白 蛇 於 鳳 凰 山 下 ……
This entry was posted in Computer & Network and tagged , , , , , , . Bookmark the permalink.

4 Responses to Synology 進階: 寫個 shell script 來 reboot router

  1. Patrick says:

    我家都是用TP Link ER604W 同synology, 想重複以上步驟。跟上面的圖一樣,已經set 左 Telnet Management Port 系23,download 左putty, 然後在putty 打 192.168.1.1 (router IP)。但系都出error: Network Error: connection time out.
    想問點先可以連去ER604W。謝謝

    • C.T. Leung says:

      connection time out,就是你的 client (你沒說,估計是一台電腦) 和 server (就是 router 的 telnet server) 連不通。連不通,一般都先是檢查 physical 連線,然後是網路設定,然後是 client 的設定,和 server 的設定。如果 ping 得通 server,大概物理連線和網路設定都沒問題 (是大概,不是一定)。

      Client 方面,防火牆 ( 例如 windows 防火牆 ) 會不會阻擋了 port 23 或者 putty 程序? putty 裡面你選好了 telnet 連線?putty 裡面的 telnet 設定你都沒改動過 (我在連 604W 用的都是預設值)?

      Server 方面,Remote Management 打開了麼 (active)?IP range 設定好了麼?

      回到你的問題,「點先可以連去ER604W」,說難也不算難,因為也不用什麼特別設定,全部用預設值就可以了(至少我個人的情況是如此)。說易也可能不易,因為就像上面所說,能夠設定的東西還是十分之多的,每個網路,每部電腦(例如防火牆的設定),每個 router 的設定都是不同的。

      如果你百分百肯定所有設定都沒錯,就把 client (例如重裝 windows) 和 server (router) 都 reset factory default 一次吧。

      • Patrick Lee says:

        QUOTE:“Server 方面,Remote Management 打開了麼 (active)?IP range 設定好了麼?”
        謝謝!終於成功了!在ER604W 的Remote Management裡有一個list of Subnet裡面寫:0.0.0.0/32, status: Inactive(這些都是預設的)。我把Inactive 改為active.之後就能用Putty telnet連線到192.168.1.1(Router)。
        我想問0.0.0.0/32的意思是什麼?Google 一下website把0.0.0.0/32解得好複雜,好似解any network 的意思。
        平時set 住0.0.0.0/32做active 會不會很危險(即容易比人進入router)?
        另外題外話,我知道ER604W做port forwarding系Advanced->NAT->Virtual Server裡面做。裡面有分internal port 及external port。想問有什麽分別?通常我都會set internal port 同external port做同一個number (e.g. IP Cam 192.168.1.140 port 8100, 我會將internal port 及external port 都set 做8100。系work的!但係不知是否正確做法)。
        謝謝

        • C.T. Leung says:

          那些 subnet mask 教學都千篇一律,你真看不懂我也沒有更好的方法。

          危不危險要你自己去評估,每個情況都不同,不能一概而論。

          工具,從來沒有所謂的「正確」用法,我只會建議你去多學習幾個用法。只有在你掌握了一件工具的所有用法之後,討論那種用法比較好才會有意義。

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>