【3分レシピ】ルーターの再起動アプリを Mac OSX で作る [Aterm編]

## TL; DR <sub><sup>（今北産業）</sup></sub>

Automator で新規「アプリケーション」を立ち上げ、[再起動用のシェル・スクリプト](#%E3%82%B7%E3%82%A7%E3%83%AB%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88%E6%AC%84%E3%81%AB%E3%82%B3%E3%83%94%E3%83%9A%E3%81%99%E3%82%8B%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88)を登録する。

<img width="100%" alt="スクリーンショット 2018-02-22 17.40.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/78776/21ce747b-0480-26c1-7fd6-3b8dbd900b47.png">

### シェルスクリプト欄にコピペするスクリプト

`password` と `ip_router` の値を自分の環境に変更してください。

```bash:bash
#!/bin/bash
clear; set -u

# -------------------------------
# Router settings
# -------------------------------
user='admin'
password=''
ip_router='192.168.0.1'

# -------------------------------
# Functions
# -------------------------------

function is_ip_up () {
    result=1
    ping -c 3 -t 3 -s 32 $1 > /dev/null;
    if [ $? -eq 0 ]; then
        #success
        result=0
    fi
    return $result
}

# -------------------------------
# Begin
# -------------------------------

echo "Running script to reboot router at ${ip_router}"

url_base="http://$user:$password@$ip_router"

if is_ip_up $ip_router; then
    echo "Router is up. Fetching files..."
else
    echo "Router is down."
    exit 1
fi

html_reboot=`curl -s "$url_base/reboot.htm" --compressed`

session_id=`echo "$html_reboot" \
    | grep hidden \
    | sed -e 's/.*hidden\" value=\"\([^\"]\+\)\".*/\1/g' \
    | grep -o '[0-9a-z]\{32\}'`

echo "SESSION_ID is: $session_id"
sleep 1

html_result=`curl -s "$url_base/boafrm/formReboot" \
    -H "Origin: $url_base" \
    -H "Referer: $url_base/reboot.htm" \
    --data "SESSION_ID=$session_id&reboot=%BA%C6%B5%AF%C6%B0+" \
    --compressed`

while is_ip_up $ip_router; do
    echo -en "\rShutting down router..."
    sleep 1
done

echo; echo "Now rebooting..."

while ! is_ip_up $ip_router; do
    echo -en "\rPinging... router is down"
    sleep 1
done

echo; echo "Router is up."
echo "Router rebooted."

exit 0
```

- [最新版ソース（`macOS`, `Ubuntu`, `Debian`, `Raspbian` 互換）](https://github.com/KEINOS/Rebooter_NEC_Aterm_WG1200Hx/blob/master/rebooter.sh) @ GitHub

## 動作検証済み環境

|項目 |内容|
|:--:|:---|
|ルーター| [NEC Aterm WG1200HS](http://www.aterm.jp/product/atermstation/product/warpstar/wg1200hs/)（[FW](http://www.aterm.jp/support/qa/qa/00044.html): v1.0.20）|
|OS| macOS HighSierra (OSX 10.13)|
|PC| MacBook Pro (Retina, 13-inch, Early 2015) |
|Bash| 3.2 |

- [シェルスクリプト](https://github.com/KEINOS/Rebooter_NEC_Aterm_WG1200Hx/blob/master/rebooter.sh)自体は Raspbian（Debian 8, jessie）+ bash v4.3.30 でも動作確認取れています。

## TS; DR <sub><sup>（kwsk）</sup></sub>

<img width="100%" alt="スクリーンショット 2018-02-22 17.40.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/78776/21ce747b-0480-26c1-7fd6-3b8dbd900b47.png">

### ルーターの再起動アプリの作り方

1. Automator でアプリケーションを新規作成する。
2. [ユーティリティ] - [シェルスクリプトを実行] アクションを右の欄にドラッグ＆ドロップする。
3. [上記スクリプト](#%E3%82%B7%E3%82%A7%E3%83%AB%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88%E6%AC%84%E3%81%AB%E3%82%B3%E3%83%94%E3%83%9A%E3%81%99%E3%82%8B%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88)をシェルスクリプト欄にコピペする。
4. `ip_router`, `user`, `password` の値を自分のルーターの環境に設定する。
5. 実行してみる。
6. 動いたら、「完了の通知」など良い感じに自分好みにアクションを追加したりカスタムして保存する。

- 恐らく大抵の NEC の Aterm 系のルーターなら動くと思いますが、他のルーターでも基本動作は同じだと思うのでスクリプトをいじってみてください。

### スクリプトの動作概要

1. `curl`でルーターの再起動画面のHTMLフォームを取得
    - `$html_reboot`にフォームを格納。ベーシック認証で取得するのがポイント
2. フォームに埋め込まれたセッション ID を`grep`と`sed`で取得
    - `$session_id`に格納。再起動のリクエスト（POST）に必要
3. セッション ID と共に 1 で取得したフォームの他の値も一緒に POST する
    - POST （`data`にアクセストークンを添えて`curl`）した結果は`$html_result `に格納
4. `ping`を飛ばし、ルーターのダウンを確認→待機→再アップを確認し、スクリプトを終了
    - `is_ip_up`関数の結果が「0」の場合はルーター起動中

### うまく行かない場合

スクリプト・ファイルにしてターミナルから実行して動作するか確認してみてください。

1. 適当なファイルに上記スクリプトをコピペ＆編集して保存
    ```
    $ vi /path/to/your/script/reboot.sh
    ```
    
2. 実行権限を与える

    ```
    $ chmod 0755 /path/to/your/script/reboot.sh
    ```

3. 実行しながらエラーを確認し修正する

    ```
    $ /path/to/your/script/reboot.sh
    ```

    - `set -e` などの [bash オプション](https://qiita.com/m-yamashita/items/889c116b92dc0bf4ea7d#-e)を付けてエラー箇所で止める。
    - `curl` 時に [`-v` オプション](https://qiita.com/takayukioda/items/edf371b3566bea64d046#-v-http%E3%83%AA%E3%82%AF%E3%82%A8%E3%82%B9%E3%83%88%E3%81%AE%E8%A9%B3%E7%B4%B0%E8%A1%A8%E7%A4%BA)を付けてHTML取得結果を出力しながら確認する。

## 所感

実家の WiFi ルーターを再起動するために [PHP でルータを再起動するスクリプトを書いた](https://github.com/KEINOS/Rebooter_NEC_Aterm_WG1200Hx)のですが、`curl` を２回叩くだけなので「シェルコマンドと Automator でアプリ化したら楽じゃね？」と思い `bash` で書いてみました。

昔、お客様先のオフィスやクライアントさんの会社で WiFi が不安定と相談された時、（余り良い解決策ではないのですが迅速な対応として）大半がルーターの再起動で直ったことから、調子が悪い時は電源の入れ直しを案内するより、こういったアプリの方が良いかもと、ふと思い出して記事を書いてみました。