bash

soracom SIMで通信中のラズパイにSSHで接続する

最近はラズベリーパイをつかってIoTデバイスを作ろうという試みをやっています。

ラズパイのキットはこれが調子いいです。

Raspberry Pi Zero WH Starter Kit 8GB
ケイエスワイ
売り上げランキング: 48,720

ラズベリーパイ、Linuxが搭載されていますし、無線LANの挙動も実に軽快なので、LAN内にいる時はSSH接続がとても簡単です。しかし、IoTデバイスというのは常にLAN内にあるものとも限らず、SIMカードを使ってスマホのように各キャリアが提供するネットワークを使ってインターネットにアクセスする必要もあります。

私はラズパイをインターネットに接続させるSIMとして、Soracomを選びました。
SoracomのSIMにはグローバルIPが割り振られておりません。
そしてIPが割り当てられていない以上、一般的なTCP/IP – DNSを使ったSSH接続はできないということになります。

とはいえ開発中、Docomoネットワークを使ってインターネットに接続するSIMを使ったラズパイに対して、SSH接続したいことは往々にしてよく起こります。
それができなければわざわざシーケンス制御のプログラムを書いて実行しなければならない、といったような。

ということで、SoracomのSIMをはじめとする、グローバルIPが割り振られていないSIMを使ってインターネットにアクセスをしているラズパイに対して、SSH接続をする方法(NAT超えSSH接続)をここに記しておきたいと思います。

使っているラズパイの条件は下記の通りです。

raspberry pi : Raspbian GNU/Linux 9.8 (stretch)
autossh : 1.4e
soracom sim : SORACOM Air SIM plan-D (SMS/data)
3G USBドングル : Abit AK-020

中継サーバーが必須

まずは中継サーバーを用意しましょう。
この方法は図のように、中継サーバーを介してラズパイにアクセスをすることになります。

スクリーンショット 2019 03 18 17 57 29

上にも書きましたがSoracom SIMを使ったラズパイの場合、グローバルIPが割当てられていないことで、通常のTCP/IPだけでは座標を特定することができないからです。

なので、SSHポートフォワーディング(SSHトンネル)という技術を使って、中継サーバーを介してラズパイにアクセスできるようにします。

簡単に順番に仕組みを説明すると

  1. ラズパイ、起動直後に中継サーバーに対してSSHポートフォワーディングをする
  2. Macbook、中継サーバーにSSHアクセスする
  3. 中継サーバーに入ったMacbook、ポートフォワーディング情報をもとに、ラズパイにアクセスする

ということです。

ポートフォワーディングというのは、SSH接続をする際に、接続先のサーバーの任意のポートと、接続元のデバイスの任意のポートに転送(同一化)させるというような技術です。

このケースの場合、(ラズパイのSSHポートは22番であるという前提とします)接続先の中継サーバーの4649番のポートを、接続元のラズパイの22番ポートに転送するということによって、中継サーバーにアクセスしたMacbookは中継サーバーの4649番ポートにssh接続をすることで、ラズパイに対してssh接続をするという仕組みを取ります。

実践

前提として中継サーバーに接続する際に使うユーザーを中継サーバー側で用意しておく必要があります。

このケースの例としてuserを使いますので、中継サーバー側で作成しておいてください

# adduser user

鍵の作成

この方法ではラズパイの起動直後に中継サーバーに対してSSH接続をしなければなりませんので、パスワードを入力することができません。そのため公開鍵暗号方式を使ってパスワードなしで接続できるようにします。

まずは、中継サーバー側のsshd_configのPubkeyAuthenticationyesに設定しておきましょう。

次にラズパイ側でssh接続のための鍵を作ります。


ssh-keygen -t rsa

(鍵の暗号化方式はどれがよいかという議論はありますが、ここでは省略、今回はrsaを採用します。)

あとは対話形式で鍵の作成が進んでいきますが、パスフレーズを聞かれるところでは何も入力せずに進んでください。


+---[RSA 2048]----+ 
|       ..  . ... |
|        ... o .  |
|        o. + * o |
|       . .. o & o|
|        S    = O |
|            ..+ o|
|          ..oooEo|
|           o*==+*|
|           .*@BO=|
+----[SHA256]-----+

こういう暗号のイメージが表示されたら鍵の作成は完了です。

~/.ssh/に
id_rsa 
id_rsa.pub
の2つのファイルが生成されています。

id_rsaが秘密鍵、id_rsa.pubが公開鍵です。
秘密鍵は絶対に人の手に渡らないように、ネットワークに流れることのないようにしましょう。

中継サーバーへ公開鍵の転送

出来上がった公開鍵を中継サーバーに送り、鍵を認証してもらいます。


ssh-copy-id user@192.168.0.100

#sshdのlistenポート番号を変更している場合は下記のように
ssh-copy-id user@192.168.2.30 -o port=10000

userと@以降のipについてはssh接続するユーザー名と接続先のホスト名またはIPアドレスを入力します。

コマンドが通ればパスワードを尋ねられますので、中継サーバー上でuserに設定しているパスワードを入力しましょう。公開鍵の転送が完了します。

この状態で


ssh user@192.168.0.100

と入力して、パスワードを聞かれずにサーバーにログインできれば成功です。

SSHポートフォワーディング

ラズパイから中継サーバーにログインする時に使うコマンドに、ポートフォワーディング用のオプションを追記します。


ssh -R 4649:localhost:22 user@192.168.0.100

-R 4649:localhost:22

というオプションを追加することで、中継サーバーの4649番ポートをラズパイの22番ポートに転送できます。

したがって上図に示しているMacbookは、中継サーバーにログインした後


ssh pi@localhost -o port=4649

とすることで、中継サーバーを経てラズパイにログインすることが可能になりました。

ラズパイから中継サーバーへssh接続の自動化

ラズパイの起動直後に中継サーバーへssh接続を自動化するには、ラズパイのcrontabに追記するのが良いのではないかと思います。


crontab -e

によってcrontabを開き、

@reboot ssh user@192.168.0.100

と書き込めば起動時に自動的に中継サーバーに接続しに行くようになります。

このとき、いくつかの設定を追加するのも良いかと思います。
具体的には ~/.ssh/config に下記のような設定を追加しておきます。


Host RelayServer
  HostName relay-server.com #中継サーバーのホスト名
  User user
  IdentityFile ~/.ssh/id_rsa
  
  StrictHostKeyChecking no
  UserKnownHostsFile /dev/null
  ServerAliveInterval 60
  ServerAliveCountMax 3
  ExitOnForwardFailure yes
  RemoteForward 4649 localhost:22

それぞれのオプションの説明をします。

HostNameは中継サーバーのアドレスです。
Userには中継サーバーにログインするユーザー名を入力します。
IdentityFileは秘密鍵の場所を書きます。

StrictHostKeyChecking no
UserKnownHostsFile /dev/null

によって、はじめて接続するホストの場合でも警告(fingerprint云々)を出さないようにしたり、known_hostsファイルに影響を与えることなく接続できます。

ServerAliveInterval 60
ServerAliveCountMax 3

このオプションによって、サーバーからのタイムアウトを回避します。
60秒毎にサーバーにメッセージを送り、ServerAliveCountMax の設定回数、3回まで繰りかえします。
もしサーバーが応答しなくなったら 180秒後に接続が切断されるようになるということですね。

ExitOnForwardFailure yes

このオプションによって、既にポートフォワード先のポートが空いてなかった場合はssh接続をせずに終了します。

RemoteForward 4649 localhost:22

このオプションで接続先の中継サーバーの4649番ポートに、接続元のラズパイの22番ポートに転送できます。

これらの設定が終われば、


ssh RelayServer

と入力するだけで上記で設定したオプションを踏まえたssh接続ができます。

自動で接続する際には -N -f オプションをつけてもいいです。それぞれ

-N は接続先でポートフォワーディングのみに利用する接続であることを明示するオプション

-f はバックグラウンドで実行することを明示するオプションです。

crontabの方にも
@reboot ssh -N -f RelayServer

と書いておくとこれらが自動で実行されます。

autosshのインストール

さらにautosshを使ってssh接続するという選択もあります。
普通のsshを使っても問題はないのですが、autosshの場合、セッションが何らかの原因で途切れてしまった場合、自動的に再接続をしてくれます。

autosshはsshと互換のあるコマンドですので、普段からautosshを使うのもありですね。


#apt-get install autossh

でインストールできます。

上記のことをautosshでやる場合、crontabには

@reboot autossh -M 0 -N -f RelayServer

と書きましょう。

-M 0 オプションは
autossh標準のsshコネクションモニタリングを無効にし、OpenSsh自体のモニタリングを有効にします。
OpenSsh自体のモニタリングとはServerAliveInterval 60や、ServerAliveCountMax 3などの設定のことです。
autosshのmanページで、これは推奨されています。

この方法でのSSH接続は信頼性があまり高くない

以上のことを実行すると、ラズパイ起動時に中継サーバーに自動で接続しにいき、そのセッションを使ってクライアント(macbook)からラズパイに接続しにいくことができるようになります。

しかし、ラズパイを再起動などすると、再接続までにとても時間がかかったりします(時間測ったら10分くらいかかりました)
その場合、中継サーバーをリブートしてから、ラズパイをリブートすると、すぐに接続できたりするのですが…

おそらく、ラズパイリブートする前にautosshの接続をきちんと切ってからリブートすればいいのかなあなんて今書きながら思いましたが、まだ試していません。

いずれにしろ、この方法を使ったSSH接続はあくまで開発途中での実験やデバッグに用いるのがよさそうです。

中継サーバー上のポートListenの履歴を、ラズパイが沈黙した後にすぐに削除するなどの施策を取ることができれば完全に安定させることができるのかも知れませんが。

なお、この記事を書くにあたって下記のサイトを参考にさせていただきました。
ありがとうございます。

SSH公開鍵認証でパスワード無しでログインする!ユーザも指定できる! | ぴぐろぐ

Soracom Airで繋がったデバイスにリモートからSSHする | DevelopersIO

OpenSSHの警告メッセージを出さないようにする方法 – Qiita

autossh(1): monitor/restart ssh sessions – Linux man page

SoracomのSMS SIMとラズパイを使ってiphoneとSMSの送受信をする前のページ

あるプログラムの変数を外部から操作したい場合の解決法次のページ

コメント

  • コメント (0)

  • トラックバックは利用できません。

  1. この記事へのコメントはありません。

最近の記事

Twitter

PAGE TOP