はじめに
Secure Shell (SSH) は単なるリモートターミナルアクセスのためのツールではなく、強力なネットワークユーティリティでもあります。SSHトンネリング(SSHポートフォワーディングとも呼ばれます)を使用すると、ローカルのネットワークトラフィックをセキュアなSSH接続経由でリモートホストにルーティングできます。
その核心的な考え方は、別のマシンの接続性を「借りる」という点にあります。トンネル自体がどこからともなく新しいネットワーク到達性を作り出すわけではなく、リモートホストの場所とアクセス権を再利用するものです。
この技術は、システム管理者、開発者、セキュリティ専門家によって、厳格な企業ファイアウォールの回避、レガシーアプリケーションのトラフィック暗号化、そしてパブリックインターネットに直接公開されていない隠れた内部サービスへのアクセスなどに広く利用されています。
この実験では、SSHポートフォワーディングの2つの主要なタイプについて、その概念と実践的な応用方法を学びます。
- ローカルポートフォワーディング (
-L): ローカルマシンのポートをリモートの宛先に転送します。 - リモートポートフォワーディング (
-R): リモートサーバーのポートをローカルマシンに転送します。
ネットワークトポロジーの理解
このステップでは、用意されたシミュレーション環境のネットワーク構成を確認します。
SSHトンネリングを練習するために、複数のマシンが存在するシナリオが必要です。今回は単一の仮想マシン環境で作業しているため、ローカルシステム (127.0.0.1) 上の異なるネットワークポートを使用して複雑なネットワークトポロジーをシミュレートしています。
シミュレーションの概念図は以下の通りです。あなたの「ローカルマシン」は現在のターミナルセッションを表します。「踏み台ホスト(Bastion Host)」または「エッジサーバー」は、127.0.0.1:2222 でSSHを公開するDockerコンテナとしてシミュレートされています。「内部サービス」は、同じプライベートDockerネットワーク上の 172.31.0.20:80 で動作するWebサーバーです。概念的には、このサービスは企業ネットワークの奥深くにあり、ファイアウォールによってブロックされているため、踏み台ホストからしかアクセスできないと想定してください。最後に、「ローカルサービス」はLabEx VM上のポート 8000 で動作するWebサーバーです。これは、個人のラップトップで動作しており、インターネット上の誰かと共有したい開発用サーバーだと考えてください。
シミュレートされたサービスが動作しているか確認しましょう。URLを使用してデータを転送するためのコマンドラインツールである curl を使用します。
まず、ポート 8000 で動作している「ローカルサービス」を確認します。
curl http://127.0.0.1:8000
Local Developer Machine Data という出力が表示されるはずです。
内部サービスは、意図的にLabEx VM上で直接公開されていません。次のステップでSSHトンネルを通じてアクセスします。
以降のステップでは、SSHトンネリングを使用してこれらのサービスへのアクセス方法を操作し、現実世界のファイアウォール回避シナリオをシミュレートします。
ローカルポートフォワーディングの設定 (-L)
このステップでは、ローカルポートフォワーディングを設定します。
あなたが自宅にいて、社内の内部ダッシュボード(172.31.0.20:80 のサービス)にアクセスする必要があると想像してください。ファイアウォールが外部からその内部アドレスへの直接アクセスをブロックしていますが、特定のエッジサーバー(踏み台ホスト)へのSSH接続は許可されています。
ローカルポートフォワーディングを使用すると、ローカルマシン上でポートを開き、そのローカルポートに送信されたトラフィックをSSHトンネル経由で宛先に安全に転送できます。
ローカルポートフォワーディングの構文は ssh -L [local_port]:[destination_host]:[destination_port] [user]@[ssh_server] です。
ローカルフォワーディングは、「リモートサービスをローカルにあるかのように見せる」と理解するのが最も簡単です。
シミュレートされたSSH踏み台ホストを経由して、ローカルポート 8080 を内部サービス (172.31.0.20:80) に転送します。また、2つの追加フラグを使用します。-N フラグはSSHにリモートコマンドを実行しないように指示するもので、ポート転送のみを行いたい場合に便利です。-f フラグはSSHをバックグラウンドで実行するように指示し、ターミナルを継続して使用できるようにします。
以下のコマンドを実行してトンネルを作成します。
ssh -N -f -L 8080:172.31.0.20:80 \
-o StrictHostKeyChecking=no \
-o UserKnownHostsFile=/dev/null \
-i ~/project/pivot_key -p 2222 pivot@127.0.0.1
トンネルはバックグラウンドで静かに動作しています。
それでは、トンネルをテストしましょう。内部のDockerアドレスに直接アクセスする代わりに、新しく開いたローカルポート 8080 にアクセスします。SSHトンネルがこのリクエストをキャッチして暗号化し、踏み台ホストに送信します。踏み台ホストはそれを 172.31.0.20:80 に転送します。
curl http://127.0.0.1:8080
Secret Internal Corporate Data という出力が表示されるはずです。これで、概念上のファイアウォールを回避することに成功しました!
リモートポートフォワーディングの設定 (-R)
このステップでは、リモートポートフォワーディングを設定します。
あなたがローカルのラップトップ(ポート 8000 のサービス)でWebアプリケーションを開発していると想像してください。進捗をクライアントに見せたいのですが、あなたのラップトップはホームルーター(NAT)の背後にあり、パブリックIPアドレスを持っていません。
リモートポートフォワーディングは、パブリックなSSHサーバーに接続し、そのリモートサーバー上でポートを開くことでこれを解決します。そのリモートポートに到達したトラフィックは、SSHトンネルを通ってあなたのローカルマシンに転送されます。
リモートポートフォワーディングの構文は ssh -R [remote_port]:[local_host]:[local_port] [user]@[ssh_server] です。
リモートフォワーディングは視点を反転させ、「ローカルサービスをリモート側から到達可能にする」というものです。
ローカルサービス (127.0.0.1:8000) を踏み台ホストのポート 8081 に公開します。
以下のコマンドを実行してリモートトンネルを作成します。
ssh -N -f -R 8081:127.0.0.1:8000 \
-o StrictHostKeyChecking=no \
-o UserKnownHostsFile=/dev/null \
-i ~/project/pivot_key -p 2222 pivot@127.0.0.1
トンネルがバックグラウンドで確立されました。踏み台ホストは現在ポート 8081 でリッスンしています。誰かがリモートサーバーのポート 8081 にアクセスすると、トラフィックはあなたのローカルポート 8000 に送り返されます。
踏み台ホストコンテナ経由で転送されたサービスにクエリを投げてテストしてみましょう。
docker exec bastion_host curl -s http://127.0.0.1:8081
Local Developer Machine Data という出力が表示されるはずです。これで、ローカルサービスをリモートサーバーに公開することに成功しました!
内部Webサービスへのアクセス
最後のステップでは、作成したトンネルを使用してデータをダウンロードし、プロジェクトディレクトリ内のファイルに保存することで、理解を深めます。
デフォルトのプロジェクトディレクトリにいることを確認してください。
cd ~/project
まず、ローカルポートフォワーディングトンネル(ポート 8080)を使用して内部の企業データを取得し、internal_data.txt という名前のファイルに保存します。curl の -o フラグを使用して出力先ファイルを指定します。
curl http://127.0.0.1:8080 -o internal_data.txt
次に、リモートポートフォワーディングトンネル(ポート 8081)を使用して、踏み台ホスト経由でローカルの開発者データを取得し、remote_data.txt という名前のファイルに保存します。
docker exec bastion_host curl -s http://127.0.0.1:8081 > remote_data.txt
最後に、cat コマンドを使用して、ダウンロードしたファイルの内容を確認します。
cat internal_data.txt
cat remote_data.txt
Secret Internal Corporate Data
Local Developer Machine Data
転送されたポート経由でこれらのファイルを正常にダウンロードできたことで、SSHトンネルがエンドポイント間でトラフィックを安全にルーティングしていることが証明されました。
まとめ
おめでとうございます!「SSHトンネリングとポートフォワーディング」の実験を無事に完了しました。
この実験では、SSHトンネリングの概念と、それがネットワーク制限を回避するためにどのように利用できるかを学びました。ローカルポートフォワーディング (-L) を設定して、踏み台ホスト経由でローカルトラフィックをルーティングし、隠れた内部サービスに安全にアクセスする方法を習得しました。さらに、リモートポートフォワーディング (-R) を設定して、ローカルの開発サービスをリモートサーバーに公開し、ローカルのNATやファイアウォールを回避することに成功しました。最後に、-N および -f フラグを使用してSSHトンネルをバックグラウンドで静かに実行する方法を学びました。
これらのスキルは、安全なシステム管理、リモート開発、そして複雑なネットワークトポロジーを安全にナビゲートするために不可欠です。



