Raspberry Pi で ssh 通信が切れる場合の対応例
[履歴] [最終更新] (2016/04/06 23:08:43)
最近の投稿
注目の記事

ssh 通信が切れる

先日、無線 LAN が標準搭載された Raspberry Pi 3 が発売されましたね。それ以前は USB 無線子機などを利用して Wi-Fi 接続する必要がありました。私の保有する Raspberry Pi は少々古くて B+ モデルです。いろいろな人の記事をみて、どうやら PLANEX 無線LAN子機 GW-USNANO2A が評判がよさそうなので購入して設定してみたところ確かに無線通信できるようになりました (SSID やパスワード設定方法は省略)。

ところが困ったことに ssh 通信していると結構な頻度で通信が切れてしまいます。

いろいろな記事があるけれど

原因は主に二種類あるようです。

  • USB 無線子機が省電力モードに入ってしまう
  • ssh の仕様で一定期間通信がないと切断される

いろいろと検索すると省電力モードにしないための設定が出てきますが、私の環境ではどれを試してもうまくいきませんでした。Raspberry Pi の OS や無線子機によって有効だったり有効じゃなかったりする対処法ばかりでした。

もっと一般的な対処方法があります。

ssh -o ServerAliveInterval=1 pi@192.168.179.4

-o ServerAliveInterval=1 というオプションを付与するだけです。これは

~/.ssh/config

Host pi
  HostName 192.168.179.4
  User pi
  ServerAliveInterval 1

と ssh 設定ファイルを編集してから

ssh pi

としても同じです。パスワードはご存知のとおり raspberry ですね。

何が起きているのか

パケットキャプチャしてみましょう。

sudo tcpdump host 192.168.179.4

PC (192.168.179.3) から Raspberry Pi (192.168.179.4) に一秒ごとにパケットが送信されています。

00:51:55.399364 IP 192.168.179.3.55623 > 192.168.179.4.ssh: Flags [P.], seq 5334:5390, ack 6370, win 4096, options [nop,nop,TS val 399702904 ecr 217335], length 56
00:51:55.404845 IP 192.168.179.4.ssh > 192.168.179.3.55623: Flags [P.], seq 6370:6410, ack 5390, win 815, options [nop,nop,TS val 217436 ecr 399702904], length 40

このため無線 LAN 子機が省電力モードに切り替わることもないですし SSH がタイムアウトすることもありません。通信が途切れるときは以下のようなパケットキャプチャが得られます。

01:22:06.325687 ARP, Request who-has 192.168.179.4 tell 192.168.179.3, length 28

ARP で 192.168.179.4 の MAC アドレスを検索したときに Raspberry Pi が反応してくれていません。

ping を打ちつづけるという別の方法

ssh の途中で通信が切れることはなくなりましたが、ssh を閉じているときに USB 無線 LAN 子機が省電力モードに入ってしまうと今度はそもそも ssh できなくなってしまいます。USB 無線 LAN 子機を抜き差しすれば復活しますが、面倒です。かといって、汎用的に省電力モードを無効化できる方法も見当らない。どうしたらいいのか。ping を打ち続けるというのがシンプルでスマートな方法の一つです。

デフォルトゲートウェイに ping を打ちつづける

sudo ping 192.168.179.1

外部の適当なサーバーに ping を打ちつづける (怒られそう)

sudo ping www.example.com

これで bot などを動かしているときに通信ができなくなる事態を回避できますね。Raspberry Pi 起動時にこれが自動で実行され始めるように設定しておくと快適になりそうです。/etc/rc.local という Windows のスタートアップのようなファイルに以下の一行を exit 0 よりも前に追加してみましょう。sleep 30 は無線 LAN が利用できるようになるまでの待ち時間を適当に調整してください。

sleep 30 && nohup ping www.example.com > /tmp/ping.log 2>&1 &

再起動してから確認してみましょう。

tailf /tmp/ping.log

うまくいっていれば ping が継続実行されています。

64 bytes from 93.184.216.34: icmp_seq=1 ttl=50 time=130 ms
64 bytes from 93.184.216.34: icmp_seq=2 ttl=50 time=129 ms
64 bytes from 93.184.216.34: icmp_seq=3 ttl=50 time=131 ms
64 bytes from 93.184.216.34: icmp_seq=4 ttl=50 time=143 ms
64 bytes from 93.184.216.34: icmp_seq=5 ttl=50 time=146 ms
...
関連ページ
    「AWS IoT ボタン」を用いずにインターネット経由でスマホによるラジコン操作 スマートフォンから操作できるブルドーザーロボットです。前進、後退、回転が可能です。Qoosky WebSocket API を利用しています。制作費は Raspberry Pi が既に手元にあれば追加でおおよそ 1 万円です。センサー機能が搭載されていないため正確な操作はできませんが、学校や職場から自宅のロボットを