Edited at
SORACOMDay 17

SORACOM AirでPPP接続しているRaspberry PiをインターネットからSSHアクセスする

More than 3 years have passed since last update.


はじめに

SORACOM Air使ってますか?私は使っています。ただ、ラズパイ使いの方々に話を聞くと「SORACOM AirでPPP接続したラズパイにグローバルIPアドレスが付与されないためリモートでのメンテができないのでちょっと困る」というチラホラ聞きます 1

SORACOMの安川さんが以下のブログ記事でヒントを書かれていますが、安川さんによると現在(2015年12月現在)もリモートアクセスについて問い合わせが多いそうです(とSORACOM User Group #0で聞きました)。

今回は上記URLのヒントをヘチらせていただいて(=パクらせていただいて)中継サーバのポートフォワードによるSSHトンネリングを行う手順を示したいと思います。

当記事は長めで申し訳ないのですが

枯れたテクニックですので仕込むのはさほど難しくありません



概要

インターネット上でssh接続できるLinuxサーバを中継サーバとして、あらかじめラズパイからのSSH接続をポートフォワードを行いSSHリモートアクセスを実現する。中継サーバは、今回IDCFクラウドの仮想マシンを使います。お好みによりAWS EC2など別のIaaSサーバやVPSでも構いません。


  • 準備で使うコマンド


    • SORACOM AirでPPP接続したラズパイでは以下のautosshコマンドで中継サーバに接続しておきます。PPPPはSSHフォワードを行うポート番号、AAA.BBB.CCC.DDDは中継サーバのグローバルIPアドレスです。



$ autossh -M 0 -q -f -N -o "ServerAliveInterval 60" -o "ServerAliveCountMax 3"  -R PPPP:localhost:22 AAA.BBB.CCC.DDD


  • 接続で使うコマンド


    • 中継サーバにSSHログインしておきます。


    • 以下のsshコマンドでラズパイにトンネリングSSH接続を行います。



$ ssh pi@localhost -p PPPP

以上のコマンドを使って、実際の手順を紹介していきます。


準備 概要


  1. 中継サーバのIPアドレスを確認しSSHポートを開いておく

  2. SORACOM Airをつないだラズパイと中継サーバとが~/.ssh/configを使ってrootユーザで接続できるようにしておく


  3. ラズパイ側でautosshを用いて中継サーバに向けて自動接続&接続維持を行うようにしておく


  4. 中継サーバ側で、ラズパイからのSSH接続&ポートマッピングを確認する。



接続手順 概要


  1. 中継サーバにSSH接続を行う


  2. SSH接続を行った中継サーバで、SSHフォワードしているポートにSSH接続する


  3. その結果、SSHトンネリングによりラズパイにSSHリモートアクセスが行われる




詳細


準備の詳細

【前提:IDCFクラウド仮想マシンの場合】IDCFクラウドで「めちゃ楽ガイド」などを使ってUbuntuなどのLinuxサーバーが立ち上がっている状態を前提とします。「めちゃ楽ガイド」の手順で示されている仮想マシン、IPアドレス、SSH Keyのテキストファイルの情報が必要になります。

また、ご自身のPCでSSH KeyによるSSHアクセスができる状態にしておいてください。


中継サーバのIPアドレスの確認(IDCFクラウド仮想マシンの場合)

ご自身のPCなどからブラウザを起動し、IDCFのクラウドコンソールから「IPアドレス」をクリックします。ログインしていない場合は、IDCFクラウドにアクセスしてログインIDとパスワードを入力してログインします。



該当のIPアドレス名を確認し、IPアドレスをコピーしておきます。

IPアドレス名をクリックし、ファイヤーウォールの設定でSSHの22番ポートを設定します。



あわせて、ポートフォワードの設定でSSHの22番ポートを設定します。中継サーバとして使う仮想マシンを指定してください。ここでは「yoshiken0830」を指定しています。


SORACOM AirをつないだラズパイとIDCFクラウド仮想マシンとが~/.ssh/configを使ってrootユーザで接続できるようにしておく

SSH Keyのテキストファイル「raspi-sora.txt」をラズパイ側にアップロードします。ホームディレクトリ下の.sshディレクトリにアップロードします。SCPでファイル転送したりUSBメモリでコピーしたりもできますし、ラズパイにSSHでつないでいるのでviエディタでファイルを作ってペーストしたりします。

pi@raspi-air:~$ vi ~/.ssh/raspi-sora.txt

ご自身のPCにあるメモ帳やダウンロードした「raspi-sora.txt」を開き、全てを選択してコピーし、viで開いている~/.ssh/raspi-sora.txtファイルに貼り付け、保存します。

次に、ホームディレクトリ下の.sshディレクトリにconfigファイルを作成して、rootユーザでSSH keyを使ってアクセスできるようにします。

pi@raspi-air:~$ vi ~/.ssh/config

AAA.BBB.CCC.DDDはご自身のIDCFクラウド仮想マシンにアクセスするIPアドレスを入れてください。


~/.ssh/config

Host AAA.BBB.CCC.DDD

HostName AAA.BBB.CCC.DDD
IdentityFile ~/.ssh/raspi-sora.txt
User root

viエディタを保存・終了したら、動作確認のためsshでアクセスしてみましょう。

pi@raspi-air:~$ ssh AAA.BBB.CCC.DDD

以下の様なプロンプトがでればログインできています。ログインが確認できたらexitコマンドでログアウトしておきます。

root@yoshiken0830:~# 


ラズパイ側でautosshを用いて中継サーバに向けて自動接続&接続維持を行うようにしておく

あらかじめautosshコマンドをインストールしておきます。

pi@raspi-air:~$ sudo apt-get install autossh

次に/etc/init.dディレクトリに自動起動スクリプトsoracomair_autosshを作成します。

pi@raspi-air:~$ sudo vi /etc/init.d/soracomair_autossh

autosshコマンドを使って中継サーバのIPアドレスAAA.BBB.CCC.DDDに接続を行う様に設定します。AAA.BBB.CCC.DDDの部分をご自身のIDCFクラウド仮想マシンのIPアドレスに置き換えてください。

中継サーバとなるIDCFクラウド仮想マシンのポート番号8022番をラズパイ側のSSHサーバのポート22番にマッピングする指定を行っています。


/etc/init.d/soracomair_autossh

#!/bin/sh

### BEGIN INIT INFO
# Provides: soracomair_autossh
# Required-Start: $local_fs
# Required-Stop: $local_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: autossh tunnel
### END INIT INFO

start(){
echo -n "starting autossh...\n"
su -c 'autossh -M 0 -q -f -N -o "ServerAliveInterval 60" -o "ServerAliveCountMax 3" -R 8022:localhost:22 AAA.BBB.CCC.DDD'
return 0
}

stop(){
echo -n "stopping autossh...\n"
killall autossh
return 0
}
case $1 in
start)
start
;;
stop)
stop
;;
esac


起動スクリプトを作成・保存できたら、insservコマンドで各ランレベルの起動リンクを設定します。

pi@raspi-air:~$ sudo insserv -d /etc/init.d/soracomair_autossh

pi@raspi-air:~$ ls -l /etc/rc*.d/*autossh*
lrwxrwxrwx 1 root root (…中略…) /etc/rc0.d/K02soracomair_autossh -> ../init.d/soracomair_autossh
lrwxrwxrwx 1 root root (…中略…) /etc/rc1.d/K02soracomair_autossh -> ../init.d/soracomair_autossh
lrwxrwxrwx 1 root root (…中略…) /etc/rc2.d/S01soracomair_autossh -> ../init.d/soracomair_autossh
lrwxrwxrwx 1 root root (…中略…) /etc/rc3.d/S01soracomair_autossh -> ../init.d/soracomair_autossh
lrwxrwxrwx 1 root root (…中略…) /etc/rc4.d/S01soracomair_autossh -> ../init.d/soracomair_autossh
lrwxrwxrwx 1 root root (…中略…) /etc/rc5.d/S01soracomair_autossh -> ../init.d/soracomair_autossh
lrwxrwxrwx 1 root root (…中略…) /etc/rc6.d/K02soracomair_autossh -> ../init.d/soracomair_autossh

うまく設定できているようなら再起動します。

pi@raspi-air:~$ sudo reboot

再起動後、中継サーバとなるIDCFクラウド仮想マシン側で接続&ポートマッピングされているか確認してみましょう。


IDCFクラウド仮想マシン側で、ラズパイからのSSH接続&ポートマッピングを確認する。

ご自身のPCからIDCFクラウド仮想マシンにSSHアクセスを行います。netstatコマンドで22番、8022番ポートの状況を確認します。

root@yoshiken0830:~# netstat -lt

Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 localhost:smtp *:* LISTEN
tcp 0 0 *:1883 *:* LISTEN
tcp 0 0 localhost:8022 *:* LISTEN ←コレ!
tcp 0 0 *:ssh *:* LISTEN
tcp6 0 0 localhost:smtp [::]:* LISTEN
tcp6 0 0 [::]:1883 [::]:* LISTEN
tcp6 0 0 localhost:8022 [::]:* LISTEN
tcp6 0 0 [::]:ssh [::]:* LISTEN
root@yoshiken0830:~#

localhost:8022がLISTENであれば、ポートマッピングがうまく設定できているはずです。

8022番ポートにSSHで接続すれば、マッピングされたポートにフォワードされて、ラズパイにSSH接続ができるようになります。exitコマンドで中継サーバからログアウトしておくか、そのまま以下の接続手順を行います。


接続手順の詳細


中継サーバにSSH接続を行う

ご自身のPCから中継サーバにSSHアクセスを行います。Macだとターミナルからsshコマンドで。WinだとTera Termなどで。


SSH接続を行った中継サーバで、SSHフォワードしているポートにローカルSSH接続する。

以下のsshコマンドで、ラズパイにSSHアクセスを行う。

root@yoshiken0830:~# ssh pi@localhost -p 8022

pi@localhost's password: ←ラズパイのpiユーザのパスワード

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Fri Dec 18 12:01:40 2015 from ...
pi@raspi-air:~$


その結果、SSHトンネリングによりラズパイにSSHリモートアクセスが行われる

上記の様に、ラズパイのpiユーザのコマンドプロンプトが表示されればOKです。インターネットからSORACOM AirでPPP接続しているRaspberry PiをSSHアクセスすることができました!

お疲れ様です。


注釈





  1. SSHでリモートメンテする運用自体アカンのちゃう?とか、IoT時代のデバイスはSSHアクセスするようなモンではないんだよ〜とかのハナシもある訳ですが、現状ではそうせざるを得ない状況も少なからずあります。