
2026/06/20 12:55
SSH トンネルの実際的なガイド:ローカルとリモートのポート転送について
RSS: https://news.ycombinator.com/rss
要約▶
Japanese Translation:
本テキストは、成熟した SSH テクノロジーを活用し、直接のファイアウォールポートを開放せずに内部ネットワークへの安全なアクセスを実現するための、SSH トネリングの実用的なガイドを提供します。内部ホームネットワーク、ローカルワークステーション、パブリックバジオン、プライベート VPC から構成される 4 ホストのラボトポロジーを用い、本ガイドは主な転送モードである Local(
-L)、Remote(-R)、および Dynamic(-D)の 3 つをカバーします。各モードに対する具体的なコマンド構文(例えば、ローカルポートをリモートサービスにマップする場合や、パブリックゲートウェイ経由でローカルサーバーを公開する場合など)の詳細を説明するとともに、柔軟なインターネットルーティングのための SOCKS プロキシの概念を導入します。また、持続的なバックグラウンドセッションを作成するための -f -N フラグの使用法を強調し、クライアント側およびサーバー側のリスニング振る舞いを区別するために local:remote versus remote:local のような助記詞を提供します。本文
SSH トンネルの活用と完全ガイド
SSH は、今日もなお広く利用されている「古代の技術」です。長期的な視点で見れば、クラウドネイティブツールや一時的なフレームワークを習得するよりも、SSH のいくつかのコツを覚える方が有益かもしれません。その魅力の核心は、標準的なツールと単一コマンドで多様なネットワークアクセスを実現できる点にあります。
SSH トンネルによる実現可能な機能
標準的な SSH コマンドだけで、以下のようなことができます:
- 公開 IP を持つ EC2 インスタンスを通じて、内部 VPC エンドポイントにアクセスする。
- リモート開発 VM の localhost ポートをローカルのブラウザ上でオープンにする。
- ホーム/プライベートネットワーク上の任意のローカルサーバーを外部世界へ公開する。
- ブラウザのデバッグポートをリモートのサンドボックス化されたコーディングエージェントへとトンネル化する。
💡 注意: 正解のコマンド(フラグやポート順序)を思い出すのは難しいです。「
か-Lか?」「ローカル/リモート側への方向性は?」といった悩みをよく抱えます。-R
このチュートリアルでは、その難題に挑んで完成させたLab(実習)とビジュアルなチートシートを紹介し、一連の技術解説を行います。
Lab 環境構成
本チュートリアルで紹介する Lab は、4 つのホストが 3 つのネットワークに接続された設定で動作します:
- internal: ホームネットワーク(
)上のデバイス(ホームラベルク、NAS、プリンターなど)。パブリックネットワークからは到達不可能。192.168.0.0/24 - local: ワークステーション。ホームネットワークとパブリックネットワーク(
)の両方に存在します。203.0.113.0/24 - remote: パブリックネットワーク上のパブリック・バーストン(ゲートウェイ)。同時に、プライベート VPC(
)にも接続されています。172.16.0.0/24 - private: VPC 上の内部専用サービス(データベース、OpenSearch クラスターなど)。パブリックネットワークからは到達不可能。
基本的な SSH 接続
ローカルからホスト名または IP アドレスでリモートへの SSH を実行できます(キーは既に信頼されています):
ssh remote ssh 203.0.113.30
ローカルポートフォワード(Local Port Forwarding)
私が最も頻繁に使用する機能です。リモートマシンの localhost でリスニングしているサービスを、パブリック IP を通じてアクセスしたい場合に活躍します。
代表的な使用例
- UI ツールを使って、ノートパソコンからプライベートなリモートデータベース(MySQL、Postgres、Redis など)にアクセスする。
- ブラウザを使用して、プライベートネットワークのみで公開されている Web アプリケーションにアクセスする。
- サーバーのパブリックインタフェースを介さずに、ノートパソコンからコンテナのポートにアクセスする。
これらは単一の SSH コマンドですべて解決できます:
ssh -L [local_addr:]local_port:remote_addr:remote_port [user@]sshd_addr
動作原理
フラグ: 「ローカルポートフォワードを開始する」ことを示します。-L- ローカルの SSH クライアントが
でリスニングを開始します(通常はlocal_port
)。localhost - アクセスされたトラフィックは、SSH 接続先のリモートマシン (
) へ転送されます。remote_addr:remote_port
🚩 Pro Tip: バックグラウンドで実行するには
ssh -f -N -L を使用してください。
Lab 1: SSH トンネルを使用したローカルポートフォワード 👨🔬
- 環境: リモートホスト(
)には、ローカルループバックアドレス203.0.113.30
にバインドされた Web サーバーがあります。127.0.0.1:80 - 課題: サービスがループバックのみを参照しているため、ネットワークから直接アクセスできません。
手順
-
直接アクセス不可を確認(ローカルホストから):
curl 203.0.113.30:80 # remote.public # 接続失敗 (Could not connect to server) -
リモート側では動作する(コンソール経由):
Hello from the remote host (localhost-only service).
-
SSH トンネルによる迂回(ローカルホストから): リモートの
をローカルのlocalhost:80
にバインドします。localhost:8080ssh -f -N -L 8080:localhost:80 203.0.113.30 -
アクセス成功(ローカルホストから):
curl localhost:8080 # Hello from the remote host (localhost-only service).
より明確な指定:
ssh -f -N -L localhost:8080:localhost:80 203.0.113.30 # local remote via
バーストンホストを使用したローカルポートフォワード
remote_addr と sshd_addr が異なる場合(バーストンホストを経由する場合)も同様に動作します。
- シナリオ: VPC 内のプライベートホスト (
) をアクセスしたいが、ローカルからは VPC ルートが存在しない。172.16.0.40 - 解決策: バーストンホスト (
) を経由してポートをフォワードする。203.0.113.30
Lab 2: バーストンホストを使用したローカルポートフォワード 👨🔬
-
直接アクセス不可(プライベート IP):
curl --connect-timeout 3 172.16.0.40:80 # private.vpc # タイムアウト -
バーストン経由のポートフォワード:
ssh -f -N -L 8081:172.16.0.40:80 203.0.113.30 # local remote via -
アクセス成功:
curl localhost:8081 # Hello from the private VPC host (172.16.0.40).
リモートポートフォワード(Remote Port Forwarding)
ローカルのサービスを、外部世界(パブリックインターネット)からアクセス可能にしたい場合に使用します。これには、
GatewayPorts yes を設定したゲートウェイサーバーが必要です。
ssh -R [remote_addr:]remote_port:local_addr:local_port [user@]gateway_addr
注意点:GatewayPorts 設定
デフォルトでは、リモートポートフォワードは SSH サーバーの
localhost への接続のみを許可します。パブリック IP を使うためには、sshd_config に GatewayPorts yes を追加する必要があります。
使用例
- デモ用サービスをインターネットへ公開する。
- ホームサーバー上のアプリケーションを開発中のエージェントからアクセスできるようにする。
- ブラウザのデバッグポートを外部環境へトンネル化する。
Lab 3: SSH トンネルを使用したリモートポートフォワード 👨🔬
- 環境: ローカルホスト (
) に Web サーバーがあり、これをパブリックゲートウェイ経由で公開したい。localhost:80 - 設定: ゲートウェイ側で
を有効化済み。GatewayPorts yes
手順
-
ローカルからの直接アクセス不可:
curl --connect-timeout 3 203.0.113.20:80 # Failed to connect -
リモートポートフォワードの設定:
ssh -f -N -R 0.0.0.0:8080:localhost:80 203.0.113.30 # remote local via -
VPC 内(外部から)からのアクセス:
curl 172.16.0.30:8080 # remote.vpc # Hello from your local workstation (localhost-only service).
ホーム/プライベートネットワークへのリモートポートフォワード
ローカルホストが「ジャンプホスト」として機能するシナリオです。ホームネットワーク内のサービス(SSH クライアント側にある)を、外部のゲートウェイを通じて公開します。
Lab 4: ホーム/プライベートネットワークからのリモートポートフォワード 👨🔬
- 環境: ホームネットワーク内のデバイス (
) を公開したい。192.168.0.10:80 - 課題: 外部からはこの IP に直接到達できない(ルートを持たない)。
手順
-
外部からの直接アクセス不可:
curl --connect-timeout 3 192.168.0.10:80 # internal.home # タイムアウト -
リモートポートフォワードの設定: ローカルホストを介して、外部 IP (
) が内部デバイスのアドレスを解決するようにします。203.0.113.30ssh -f -N -R 0.0.0.0:8081:192.168.0.10:80 203.0.113.30 # remote local via -
VPC 内からのアクセス検証:
curl 172.16.0.30:8081 # remote.vpc # Hello from the internal home-network host (192.168.0.10).
ダイナミックローカルポートフォワード(Dynamic Local Port Forwarding)
ssh -L のように固定された宛先に接続するのではなく、SSH クライアント自体をSOCKS プロキシに変換します。これにより、複数の宛先に動的にアクセス可能になります。
ssh -D [local_addr:]local_port [user@]sshd_addr
特徴
- ローカル SOCKS プロキシを開始し(デフォルト
)、その経由で任意のアドレスへ接続できます。localhost - 柔軟性: 特定の宛先を事前に指定せず、SOCKS プロトコルを通じて動的にホストとポートを選択可能です。
- 用途:
- バーストンホストを介して VPC 内の全 API にアクセスする。
- 1 つのトンネルで複数の内部 Web アプリを表示する。
🚩 Pro Tip:
ssh -f -N -D を使用してバックグラウンド実行します。
Lab 5: SSH トンネルを使用したダイナミックポートフォワード 👨🔬
- 環境: Lab 2 のバーストンシナリオを使用。
- 手順:
- 直接アクセス不可を確認:
curl --connect-timeout 3 172.16.0.40:80 # タイムアウト - SOCKS プロキシを開始(ポート
):1080ssh -f -N -D 1080 203.0.113.30 # remote.public - プロキシ経由で VPC 内のサービスにアクセス(
はcurl
フラグが必要):--socks5-hostnamecurl --socks5-hostname localhost:1080 172.16.0.40:80 # via private.vpc # Hello from the private VPC host (172.16.0.40).
- 直接アクセス不可を確認:
単一の
コマンドで、個別のトンネル(-D)を何回も設定する手間が省けます。ssh -L
ダイナミックリモートポートフォワード(Dynamic Remote Port Forwarding)
ssh -R のダイナミックモードです。これにより、**SSH サーバー側(ゲートウェイ)**で SOCKS プロキシとして機能させます。
ssh -R [bind_address:]port [user@]gateway_addr
特徴
- リモート SOCKS プロキシ: ゲートウェイ上でプロキシを開始し、そこからアクセス可能なすべてのホストを公開します。
- 事前設定不要:
を固定せずに、クライアント側から到達可能な全てのアドレスへ接続可能。local_addr:local_port - 要件: OpenSSH 7.6 以上のバージョンが必要(通常のパブリック IP での動作には
も必要)。GatewayPorts yes
🚩 Pro Tip:
ssh -f -N -R を使用してバックグラウンド実行します。
Lab 6: SSH トンネルを使用したリモートダイナミックポートフォワード 👨🔬
-
環境: Lab 4 のホームネットワークシナリオを使用(外部 IP が内部 IP を経由してアクセス)。
-
手順:
- 外部からの直接接続不可:
curl 192.168.0.10:80 # internal.home # Failed to connect - ゲートウェイをプロキシとして開始(ポート
):1080ssh -f -N -R 0.0.0.0:1080 203.0.113.30 # remote.public
※
を指定することで、特定の外部 IP (bind_address:port
) からアクセス可能になります。0.0.0.0- VPC 内からプロキシ経由でアクセス:
curl --socks5-hostname 172.16.0.30:1080 192.168.0.10:80 # via internal.home # Hello from the internal home-network host (192.168.0.10).
- 外部からの直接接続不可:
まとめ:コマンドの一覧と覚え方(Mnemonics)
SSH トンネリングのコマンドを覚えるための簡単な復習です。
| 種類 | コマンド | 動作の説明 |
|---|---|---|
| ローカルポートフォワード | | リモートのサービスを、ローカルのポートで利用可能にします。 |
| リモートポートフォワード | | ローカルのサービスを、リモートのポートで利用可能にします。 |
| ダイナミックローカル | | ローカルの SSH クライアントを SOCKS プロキシに変換します。 |
| ダイナミックリモート | (宛先なし) | リモートの SSH サーバー (sshd) を SOCKS プロキシに変換します。 |
💡 覚えやすい助詞(Mnemonics)
- ローカルポートフォワード (
):-L- Local で始まるので、新しいポートを開くのはSSH クライアント側です。
- 形式:
ssh -L <local_port>:<remote_addr>:<remote_port> <gateway>
- リモートポートフォワード (
):-R- Remote で始まるので、新しいポートを開くのは**SSH サーバー (sshd)**側です。
- 形式:
ssh -R <remote_port>:<local_addr>:<local_port> <gateway>
重要なポイント: メモは常に
またはssh -L local:remoteのように記述し、左側(最初のポート)が新しいリスニングポートとなります。ssh -R remote:local
関連リソース
学習を深めるための有益な外部資料:
(注: リンクはプレースホルダー的な記述であり、最新の情報を確認してください)
このチートシートが、SSH トンネルをマスターするお手てになれば幸いです 🧙♂️