2016年6月7日火曜日

固定ipが無いmvno配下のraspberry piに、ngrokで割り振られるurlでsshログインする方法

便利だったので、備忘録を兼ねて共有します。

背景

mvnoのサービスによっては、グローバルIPがSIMごとに割り当てられないものがあります。
(自分の持っているDMMのSIMはグローバルIPが割り振られないタイプのようです。)

MVNO一覧表
http://www.mvno-navi.com/mvno-list

グローバルIPが割り当てられない場合、NATやファイヤーウォールなどのキャリアのシステムが立ちはだかるため、IPを指定してSIM配下の機器にアクセスすることが難しいです。
しかし、skypeやline電話のように、peer to peerの接続を確立すればデータのやりとりが可能です。


ngrokは、peer to peerのような通信でトンネルを作ることで、グローバルIPが割り当てられないSIM配下の機器へのアクセスを可能にするサービスです。

今回はngrokで割り振られたurlを使って、raspberry piにssh接続する方法を説明します。

使ったもの


  • raspberry piにsshで接続できるPC
  • raspberry pi
  • PIXELA LTE対応USBドングル PIX-100
  • DMMのSIM

PIXELAのドングル設定方法はこちら
Raspberry piでPIXELAのLTE対応USBドングルを使う方法

設定方法

ダウンロード・インストール

下記のページから、利用する環境に合ったngrokをダウンロードします。

https://ngrok.com/download

raspberry piはarmのcpuを使っているので、arm版をダウンロードしました。

ダウンロードしたngrokを展開して、どこに居ても呼び出せるように「/usr/local/bin」に配置しました。
unzip ngrok-stable-linux-arm.zip
sudo mv ngrok /usr/local/bin/

インストールがうまくいけば、下記のコマンドでバージョンが表示されます
ngrok -v

authtokenの取得

ngrokに会員登録して、authtokenを取得します。

https://dashboard.ngrok.com/auth

apikeyの設定

下記のコマンドで、authtokenを設定します。
ngrok authtoken [取得したauthtoken]

tcpのトンネルを作成

ssh接続のために、下記のコマンドでtcpのトンネルを作ります。
ngrok tcp 22

うまくいくと、下記のような情報が出ます。
ngrok by @inconshreveable

Tunnel Status                 online
Version                       2.1.1
Region                        United States (us)
Web Interface                 http://127.0.0.1:4040
Forwarding                    tcp://0.tcp.ngrok.io:18369 -> localhost:22

Connections                   ttl     opn     rt1     rt5     p50     p90
                              0       0       0.00    0.00    0.00    0.00

Forwardingに記述されているurlが、ssh接続に使用するurlです。

トンネルの情報はngrokへログインした後のページでも確認できます。
https://dashboard.ngrok.com/status

エンドポイントにリクエストを投げても確認できます。
curl localhost:4040/api/tunnels
{"tunnels":[{"name":"command_line","uri":"/api/tunnels/command_line","public_url":"tcp://0.tcp.ap.ngrok.io:18369","proto":"tcp","config":{"addr":"localhost:22","inspect":false},"metrics":{"conns":{"count":0,"gauge":0,"rate1":0,"rate5":0,"rate15":0,"p50":0,"p90":0,"p95":0,"p99":0},"http":{"count":0,"rate1":0,"rate5":0,"rate15":0,"p50":0,"p90":0,"p95":0,"p99":0}}}],"uri":"/api/tunnels"}

なお、トンネルのurlはngrokを起動する度に変わります。

PCからsshでアクセス

作成したトンネルの情報を元に、urlからsshでアクセスします。
今回の接続先は「tcp://0.tcp.ngrok.io:18369」なので、PCから下記のコマンドでssh接続できます。

ssh pi@0.tcp.ngrok.io -p 18369

sshでログインできました!


configファイルを利用

ngrokはconfigファイルでトンネルを仲介するサーバーの地域や、トンネルの詳細を設定できます。
こうしておくと、ngrokのコマンドに毎回sshの設定を渡さなくて良くなるので、便利だと思います。

~/.config/ngrok/ngrok.yml
version: "2"
authtoken: [取得したauthtoken] region: ap tunnels: http-default: proto: http addr: 80 ssh: proto: tcp addr: 22

configファイルに記述した内容は、下記のコマンドで実行できます。

configファイルに記述した全てのトンネルを作る場合
ngrok start --all

特定のトンネルだけを作る場合(ngrok start [トンネル名])
ngrok start ssh

boot後にngrokを自動起動

raspberry piを起動する度にngrokのコマンドを実行しなくて良いように、ngrokの自動起動を設定します。

rc.localにコマンドを追加

下記の記述をrc.localのexit 0の前に追加します。

/etc/rc.local
..

# ↓を追加
sleep 30 && /usr/local/bin/ngrok start --all --config=/home/pi/.config/ngrok/ngrok.yml --log=stdout >> /dev/null &

exit 0;

記述内容の解説
「sleep 30 &&」
オフライン状態でngrokコマンドを実行すると処理が失敗するので、ネットワークが繋がるであろう30秒待ってから実行します。
有線LANでの接続ならsleep無しでも良いかもしれません。

「/usr/local/bin/ngrok」
boot直後は/usr/local/binがまだ読み込まれないので、ngrokを絶対パスで記述します。

「--config=/home/pi/.config/ngrok/ngrok.yml」
sudoとして実行されるため、/home/piにあるconfigファイルを読み込んでくれません。
そのため、--confのオプションでconfigファイルの絶対パスを渡します。

「--log=stdout >> /dev/null」
ngrokが出力するデータを破棄しています。

「&」
ngrokを別スレッドの処理にすることで/etc/rc.localのngrokに関する処理を終え、起動プロセスに/etc/rc.localの次の行を読み込ませています。

自動起動したngrokの止め方

プロセス番号を確認して、プロセスを止めます。

プロセス番号の確認
ps aux | grep ngr
root      2330  2.1  1.9 796304  8816 ?        Sl   03:29   0:28 /usr/local/bin/ngrok start --all --config=/home/pi/.ngrok2/ngrok.yml --log=stdout
pi        2405  0.0  0.3   3552  1732 pts/0    S+   03:51   0:00 grep --color=auto ngr

プロセスの停止「sudo kill -9 [プロセス番号]」
sudo kill -9 2330

以上です。
何かの参考になれば嬉しいです。

参考

ルーターを超えてリモートホストに接続できる ngrok(無料)を使って Raspberry Pi を IoT ハブにする方法
run ngrok in slient mode
How to set auto run after boot on raspberry pi?

変更履歴

2018.02.21
安定版がv2.2になっていたので、v2.0のバグやv2.1ベータ版に関する説明を削除しました。
rc.localのコマンドに「&」を追加して、別プロセスで動かすようにしました。
2022.04.25
ngrokを3.0.2に更新したら「Error reading configuration file '/home/asuki/.ngrok2/ngrok.yml': `version` property is required.」とエラーが出たので、「nrock config upgrade」実行で増えた「version: "2"」を追加しました。
2022.08.06
ngrok 3.0.6でconfig add-authtokenコマンドを実行したら、configファイルのパスが「~/.config/ngrok/ngrok.yml」になったので、「~/.ngrok2/ngrok.yml」から変更しました。
オフライン時に実行すると失敗するため、起動直後実施コマンドにsleepを追加しました。

0 件のコメント :