sshのコネクションはどうしても切れてしまうことがあるので、それを阻止するためにautosshを使ってみました。
まず、sshのコマンドラインを簡素にするため、MQTTブローカへの接続設定を書いたconfigファイルを用意します。
sshのコンフィギュレーション
まずは、sshの接続のコマンドラインを簡略化するためにconfigファイルを設定します。
設定を隠蔽できる(シェルスクリプトなどにパラメタを書かなくてもいい)というてんで良いかなと思います。
|
|
ポート番号などは適宜設定してください。
こうすることで、ssh -f -N Broker
のコマンドでトンネリング設定ができます。
ここで、公開鍵はパスフレーズ無しで作ったものを指定します。セキュリティのため、ブローカのssh設定にはポート制限やIP制限、コマンドを実行しないなどの処置を必ずとる必要があります。設定の具体例(「パスフレーズなしでの接続方法とセキュリティ設定」)
さらに、これが切れたとき自動的に再接続するため、autosshを導入します。
|
|
autosshを使ってトンネリングを設定するには
とします。
-M0 : 接続が切れているかどうかを確認するためのポート指定です。0は切断確認をポートではしないようにする設定です。
-f : 実行をバックグラウンドに移行します。
-N : sshへのオプションです。
autosshはsshを起動してそのプロセスを監視するプロセスを起動するコマンドです。
-Mオプションについては以下のように解説があります。
specifies the base monitoring port to use. Without the echo port, this port and the port immediately above it ( port + 1) should be something nothing else is using. autossh will send test data on the base monitoring port, and receive it back on the port above. For example, if you specify “-M 20000”, autossh will set up forwards so that it can send data on port 20000 and receive it back on 20001.
Alternatively, a port for a remote echo service may be specified. This should be port 7 if you wish to use the standard inetd echo service. When an echo port is specified, only the specified monitor port is used, and it carries the monitor message in both directions.
Many people disable the echo service, or even disable inetd, so check that this service is available on the remote machine. Some operating systems allow one to specify that the service only listen on the localhost (loopback interface), which would suffice for this use.
The echo service may also be something more complicated: perhaps a daemon that monitors a group of ssh tunnels.
Setting the monitor port to 0 turns the monitoring function off, and autossh will only restart ssh upon ssh’s exit. For example, if you are using a recent version of OpenSSH, you may wish to explore using the ServerAliveInterval and ServerAliveCountMax options to have the SSH client exit if it finds itself no longer connected to the server. In many ways this may be a better solution than the monitoring port.
ということなので、0を指定するとsshがexitした時に再起動します。接続はServerAliveIntervalとServerAliveCountMaxだけ待って応答が来なければexitするので、その場合sshが再起動されるという事でしょう。「この方法がポートモニタするより良い方法だ」といっているので、そうすることにします。
sshのデフォルト設定ではServerAliveInterval
は0になっている(確認のメッセージを送らない)ようなので、適宜設定する必要があります。
これがまたちょっと厄介ですね。あまり頻繁にパケットを送ると電話回線などプレミアムな回線を使っているときにコストがかさみます。本来はきちんとTPOで設定する必要があると思いますが、とりあえず30秒ぐらいに設定しておきます。
|
|
ServerAliveCountMax
は3がデフォルトのようですので、応答がなくなったあと1分30秒で切断されるようになります。
これで、ちゃんと接続できるか確認してみます。
|
|
Okですね。
さらに、keepalive確認のパケットがどのように出ているか確認してみます。
IPアドレスは下記のようになっています。
192.168.0.XXX クライアント
192.168.0.YYY サーバ
|
|
30秒ごとに何かしらのパケットをやり取りしていることがわかりました。設定通りです。
さらに、途中で回線を切断してみます。
|
|
という感じになりました。何回か試して見ましたが、切断前のコネクションをリセットするやり取りがない場合が多いかもしれません。さらに、alive確認のパケットは2往復でなく1往復半という事もありました。
無事sshの再起動も確認出来ました。
接続確認のためのパケットのサイズは、今回の実験では360byteぐらいでした。もしこの設定(30秒に1回)だとすると1日で1Mbyteぐらいの通信量です。
最近の安いデータ通信用のSIMにとってみれば大したデータ量ではないかもしれませんね。