#Ubuntu
#ssh

リモート農業 カメラサーバのsshトンネルが安定しない

Akiyagriにおけるカメラサーバ

リモートの空き家で育てている野菜の成長度合いを確認するために、リクエストに応じて写真を撮ってレスポンスするサーバ。
別のところに用意したサーバ(public IPが割り振られている)にsshトンネルをはり、サーバにあるスラックのbotサーバが逆sshを通じて写真をリクエストする。
ちなみに、このカメラサーバはUbuntu 16.04 Serverである。

sshトンネルを張る

ssh-tunnel.sh
ssh_tunnel() {
  while :
  do
    ssh -i $RSA_SECRET_KEY -R 4050:localhost:4050 $1 -N -o ServerAliveInterval=20 -o ServerAliveCountMax=3 >> $2 2>&1
  done
}

ssh_tunnel $PROXY_SERVER_USER@$PROXY_SERVER_HOST $SSH_LOG_FILE &

上記のスクリプトによって、botサーバがlocalhost:4050にリクエストを送ると、空き家においてあるサーバのlocalhost:4050につながるようになる。
以前は、sshトンネルを張ってからしばらく放置すると接続が勝手に死んでしまい、sshのプロセス自体は残っているが、逆ssh出来なく成るということが起こっていた。
ServerAliveCountMaxとServerAliveIntervalオプションをしっかり指定することで、一定期間放置するとタイムアウトして、sshのプロセスを一旦killして、再接続するように下のが上記のスクリプトである。

一晩置いたらトンネルが使えなくなる

実際に運用する前に、1ヶ月程度自宅でカメラサーバを走らせた。このときはsshトンネルが死ぬことはなかった。
systemctlに登録してあるので、sshトンネルは起動時に自動的に張られる。そこで、何度か再起動チェックも行っており、それも上手く行っていた。

しかし、いざ野菜を育てている空き家(銚子の方)に持っていったら、一晩でsshトンネルが使えなくなった。
ps aux | grep sshd をbotが動いているサーバで実行してみると、sshトンネルを受け付けているプロセスがない。

考えられる原因

  1. b-mobileのSIMカードが入ったWi-Fiルータが死んでいる(容量いっぱい)
  2. パソコンが電源にちゃんとつながっていいない
  3. スリープモードが発動した
  4. sshコマンドが何らかのエラーを吐き続けている。

1のルータが死んでいる説は、他のセンサデータのダウンロードが出来ているので可能性が低い(1ヶ月間の事前テスト環境と唯一違う部分なので一番あやしいと思ったのだが、、、)。
3のスリープモードは、 sudo systemctl mask sleep.target suspend.target hibernate.target hybrid-sleep.target
で無効にしているし、事前のチェックでも勝手にスリープモードになって繋がらなくなることはなかった。
2の電源につながっていない説に関しては、近くにあった電源タップに挿した記憶はある。しかし、そのタップが実はプラグインされていなかった可能性がある。
4については、Wi-Fiが不安定になったとあいまって生じた可能性を否定できない。せめて、リモートから再起動できれば。。。

引き続き原因究明。。。制御系は難しい。。。こういうの慣れている方がいれば
Chromeのリモートデスクトップとかって、どうやってここらへん保障しているのだろうか?

リモートホストから定期的にサーバにアクセスして、サーバが特定のステートを返したら指定のスクリプト(再起動スクリプトなど)を実行する仕組みをつくるといいかもしれない。

カメラサーバの状態

後日現地に赴いて様子みた。

root      1076  0.0  0.0   4504   932 ?        S    14:22   0:00 /bin/sh /usr/local/bin/reverse_ssh.sh
root      1077  0.0  0.0   4504   916 ?        S    14:22   0:00 /bin/sh /usr/local/bin/reverse_ssh.sh
root      3856  0.0  0.1  65508  5356 ?        Ss   14:22   0:00 /usr/sbin/sshd -D
root      5764  0.0  0.1  46984  5268 ?        S    14:31   0:00 ssh -i /home/matthew/.ssh/akiya_server -R 4040:localhost:22 ishige@akiyagri.akg.t.u-tokyo.ac.jp -N -o ServerAliveInterval=20 -o ServerAliveInterval=3
root      5776  0.0  0.1  46984  5300 ?        S    14:31   0:00 ssh -i /home/matthew/.ssh/akiya_server -R 4050:localhost:4050 ishige@akiyagri.akg.t.u-tokyo.ac.jp -N -o ServerAliveInterval=20 -o ServerAliveCountMax=3
root      5779  0.0  0.1  46984  5380 ?        S    14:31   0:00 ssh -i /home/matthew/.ssh/akiya_server -R 4041:localhost:22 ishige@akiyagri.akg.t.u-tokyo.ac.jp -N -o ServerAliveInterval=20 -o ServerAliveInterval=3
matthew   5829  0.0  0.1  46988  5424 tty1     R+   15:10   0:00 ssh -i .ssh/akiya_server -R 4444:localhost:22 -N ishige@akiyagri.akg.t.u-tokyo.ac.jp
root      5830  0.0  0.1 111300  7632 ?        Ss   15:10   0:00 sshd: matthew [priv]
matthew   5861  0.0  0.0 111300  3568 ?        S    15:10   0:00 sshd: matthew@pts/0
matthew   5878  0.0  0.0  12944   964 pts/0    S+   15:11   0:00 grep --color=auto ssh

sshのプロセスは生きているのにも関わらず、トンネルは使えていない模様。ちなみに、カメラサーバは電源が落ちていたようである。

systemctl status suspend.target

suspend.target - Suspend
   Loaded: loaded (/lib/systemd/system/suspend.target; static; vendor preset: enabled)
   Active: inactive (dead)
     Docs: man:systemd.special(7)

だったので、一応もう一度マスクをかける。念のため電源も確認する。

cat /sys/class/power_supply/AC/online
> 1

ちゃんとACアダプタのつながっている模様。

sshが吐き出しているログを見ると

/var/log/reverse-ssh-1
...
Warning: Identity file /home/***/.ssh/akiya_server not accessible: No such file or directory.
Permission denied (publickey,gssapi-keyex,gssapi-with-mic).

というログをひたすら吐き続けていた。sshトンネルを作るスクリプトは/usr/local/bin/にありrootで実行するので、一般ユーザ下に存在する秘密鍵を使うはまずいのかもしれない。そこで、秘密鍵を/usr/local/にコピーして、そこに置いた秘密鍵を使うように変更した。