ssh の トンネリング 機能を活用して、直接接続出来ない遠隔ホストへの踏み台を介した ssh 接続や scp ファイル転送、そしてLinuxやmacOSで簡易的なVPNを実現する sshuttle やAndroidアプリ ShellTun の使い方をまとめてみました。
sshの多段接続
以下の例のように遠隔地にある接続先ホストへsshで入りたい場合、ルータ上でカスタムポートでのポートフォワーディングを設定している踏み台ホストを介して接続することになるわけですが、これまで単純にステップ・バイ・ステップで接続していました。
1 2 3 4 5 |
$ ssh user@172.16.2.100 -p 8088 user@172.16.2.100's password: ******** user@192.168.9.10:~ $ ssh user@192.168.9.20 user@192.168.9.20's password: ******** user@192.168.9.20:~ $ |

図1.sshの多段接続例
これをsshのトンネルオプションを用いると、ワンライナーで多段接続が確立します。
1 2 3 4 5 |
$ ssh USERNAME@踏み台 -p NNNN -t ssh USERNAME@接続先 $ ssh user@172.16.2.100 -p 8888 -t ssh user@192.168.9.20 user@172.16.2.100's password: ******** user@192.168.9.20's password: ******** user@192.168.9.20:~ $ |
さらに、繋ぎ方を予め~/.ssh/configファイルに定義しておけば、通常のsshと同程度の呼び出し方で済むので、頻繁に使うことの多い時などは便利です。
1 2 3 4 5 6 7 8 9 10 11 |
$ cat ~/.ssh/config #Host 接続先 # ProxyCommand ssh -A -t USERNAME@踏み台 -p NNNN nc 接続先 22 Host 192.168.9.20 ProxyCommand ssh -A -t user@172.16.2.100 -p 8888 nc 192.168.9.20 22 $ ssh user@192.168.9.20 Pseudo-terminal will not be allocated because stdin is not a terminal. user@172.16.2.100's password: ******** user@192.168.9.20's password: ******** user@192.168.9.20:~ $ |
UbuntuのファイルマネージャNautilusもこの設定ファイルを参照するので、他の場所へ接続の入力BOXで、
1 |
sftp://user@192.168.9.20/ |
とすれば踏み台経由でファイル操作が可能になります。
scpの多段ファイル転送
同様にsshを用いたファイル転送コマンドscpでも、ProxyCommandを使って多段ファイル転送することが出来ます。
今まではまず、カスタムポートでポートフォワーディングが設定されている踏み台ホストへ、scpで転送していました(scpのポート指定は大文字の -P であることに注意)。
1 2 3 4 |
scp -rp -P 8888 filename user@172.168.2.100:filename -r : Recursively 再帰的なコピー -p : Preserve タイムスタンプやパーミッション情報の保持 |
そしてさらに踏み台ホストからバケツリレーする必要があるので本当に手間取ります。これがProxyCommandでsshトンネリングを介したファイル転送は、少し長くなりますが次のようなワンライナーで可能です(ProxyCommandの中で使うカスタムポート指定はsshのオプションなので、小文字 -p になる)。
1 2 |
$ scp -rp -o "ProxyCommand ssh USERNAME@踏み台 -p NNNN -W %h:%p" コピー元パス USERNAME@接続先:コピー先パス $ scp -rp -o "ProxyCommand ssh user@172.16.2.100 -p 8888 -W %h:%p" filename user@192.168.9.20:filename |
sshベースの簡易VPN : sshuttle
LinuxやmacOSでは、このsshトンネリング機能を使った簡易VPNツールsshuttleを使って、簡単にVPNを張ることができます。
インストールもパッケージマネージャaptから行えるので簡単です。以降、Ubuntu 18.04を例に話を進めます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
$ sudo apt install sshuttle パッケージリストを読み込んでいます... 完了 依存関係ツリーを作成しています 状態情報を読み取っています... 完了 アップグレード: 0 個、新規インストール: 0 個、再インストール: 1 個、削除: 0 個、保留: 5 個。 71.9 kB のアーカイブを取得する必要があります。 この操作後に追加で 0 B のディスク容量が消費されます。 取得:1 http://hk.archive.ubuntu.com/ubuntu bionic-updates/universe amd64 sshuttle all 0.78.3-1ubuntu1.1 [71.9 kB] 71.9 kB を 1秒 で取得しました (59.8 kB/s) (データベースを読み込んでいます ... 現在 278056 個のファイルとディレクトリがインストールされています。) .../sshuttle_0.78.3-1ubuntu1.1_all.deb を展開する準備をしています ... sshuttle (0.78.3-1ubuntu1.1) で (0.78.3-1ubuntu1.1 に) 上書き展開しています ... sshuttle (0.78.3-1ubuntu1.1) を設定しています ... man-db (2.8.3-2ubuntu0.1) のトリガを処理しています ... doc-base (0.10.8) のトリガを処理しています ... doc-base ファイルを 1 個変更 を処理中... scrollkeeper をドキュメントとして登録しています... |
GitHubにある執筆時点の最新版はv1.1です。さすがに四年前のUbuntuではだいぶ古いバージョンがインストールされましたが、特に問題無く使えています。
使い方はsshと同様の接続先表記の後ろに、適用したいネットワークサブネットを付記するだけ。全トラフィックを図1の踏み台へ向けて、ルーティングさせるのは次の要領です。
1 |
$ sshuttle -r user@172.16.2.100:8888 0/0 |
一部のバージョンでは、ssh接続先までルーティングされてしまうバグがあってエラーになることから、私はいつも次のようにして接続先を除外して使っています。
1 |
$ sshuttle -r user@172.16.2.100:8888 0/0 -x 172.16.2.100 |
全てのトラフィックではなく、例えば接続先のLANサブネットのみをトンネルに入れる場合は次の通り。
1 |
$ sshuttle -r user@172.16.2.100:8888 192.168.9.0/24 -x 172.16.2.100 |
Gnomeターミナルからsshuttleを実行する次のようなショートカットを作っておいて、必要な時にダブルクリック一発で繋がるようにしています。
1 |
コマンド : gnome-terminal -e "sshuttle -r user@172.16.2.100:8888 192.168.9.0/24 -x 172.16.2.100" |
ローカルの管理者パスワード入力の後、接続先のパスワードを入力すれば接続が確立します。このターミネルウィンドウを閉じてしまうと、接続は切れてしまうので注意。また、 Ctrl+C でも接続を終わらせることが出来ます。
Android向けssh VPNアプリ : ShellTun
AndroidではShellTunというアプリで、簡単にssh VPNを実現することが出来ます。
設定はまず接続先サーバをShellTun側で用意しているものから、Custom Serverとして、
edit から基本的な接続先情報を入力。今回の例のようにカスタムポートを使用するには、
Stealth Settings でStealth Tunnelを有効にした上で、ポート番号をセットします。
アプリメインでCONNECTをタップして次のような画面になれば、接続は確立しています。