HN 日本語サマリー

← 一覧へ戻る
インフラ・DevOps

SSHトンネルの実践ガイド: ローカルおよびリモートポートフォワーディング

A Practical Guide to SSH Tunnels: Local and Remote Port Forwarding (labs.iximiuz.com)

42 pointsby signa1112 コメント

要約

このガイドは、SSHトンネルの基本的な概念と、ローカルポートフォワーディングおよびリモートポートフォワーディングの具体的な使用方法を視覚的に分かりやすく解説しています。SSHが今日の開発環境でどのように内部VPCエンドポイントへのアクセス、リモート開発VMのポート公開、ローカルサーバーの外部公開などに役立つかを、実用的なコマンド例とともに紹介しています。

全文翻訳

このチュートリアルは、iximiuz Labsチームによって作成されました。 ネットワーク、Linuxに関するチュートリアル 最終更新日: 2026年6月24日 SSHトンネルの実践ガイド: ローカルおよびリモートポートフォワーディング Ivan Velichko著 SSHポートフォワーディングをクリーンで視覚的な方法で解説。ローカルポートフォワーディングとリモートポートフォワーディングの使用方法。調整が必要なsshd設定。正しいフラグを記憶する方法。 SSHは、今日でも広く使われている古い技術のもう一つの例です。来四半期には非推奨になる運命にある何十ものクラウドネイティブツールやAIエージェントフレームワークをマスターするよりも、いくつかのSSHのコツを学ぶ方が長期的にはるかに有益であるかもしれません。 この技術の中で私のお気に入りなのがSSHトンネルです。標準ツールのみを使用し、多くの場合、たった一つのコマンドで以下のことを達成できます。 公開されたEC2インスタンスを介して内部VPCエンドポイントにアクセスする。 ローカルブラウザでリモート開発VMのlocalhostポートを開く。 ホーム/プライベートネットワーク内の任意のローカルサーバーを外部に公開する。 ブラウザのデバッグポートをリモートのサンドボックス化されたコーディングエージェントにトンネルする。 他にもたくさん😍 しかし、私が毎日SSHトンネルを使用しているにもかかわらず、正しいコマンドを思い出すのにいつも時間がかかります。ローカルトンネルにするべきか、リモートトンネルにするべきか?フラグは何だ?local_port:remote_portか、それとも逆か?そこで、私はついにこれを理解しようと決心し、一連のラボと視覚的なチートシートを作成することになりました。 完全版 8.8MB このチュートリアルに含まれるラボは、4つのホストが3つのネットワークに接続された付属のプレイグラウンド上で実行されます。 internal - ホームネットワーク192.168.0.0/24上のデバイス(ホームラボボックス、NAS、プリンター)。公開ネットワークからは到達できません。 local - あなたのワークステーション。ホームネットワーク192.168.0.0/24と公開ネットワーク203.0.113.0/24の両方に存在します。 remote - 公開ネットワーク203.0.113.0/24上にあり、プライベートVPC 172.16.0.0/24にも接続されている、公開向けの踏み台/ゲートウェイ。 private - VPC 172.16.0.0/24上の内部専用サービス(データベース、OpenSearchクラスタ)。公開ネットワークからは到達できません。 localからremoteへは、ホスト名またはIPアドレスでsshできます。ローカルホストのキーはすでにリモートマシン上で信頼されています。 ``` ssh remote ssh 203.0.113.30 ``` ローカルポートフォワーディング 私が最もよく使うものから始めます。多くの場合、リモートマシンのlocalhostまたはプライベートインターフェースでサービスがリッスンしていることがありますが、そのリモートマシンへはパブリックIP経由でしかSSHできません。そして、このポートにローカルマシンからアクセスすることがどうしても必要になります。いくつかの典型的な例を挙げます。 お気に入りのUIツールを使用して、ラップトップからプライベートなリモートデータベース(MySQL、Postgres、Redisなど)にアクセスする。 ブラウザを使用して、プライベートネットワークにのみ公開されているWebアプリケーションにアクセスする。 サーバーのパブリックインターフェースに公開せずに、ラップトップからコンテナのポートにアクセスする。 上記のすべてのユースケースは、単一のsshコマンドで解決できます。 ``` ssh -L [local_addr:]local_port:remote_addr:remote_port [user@]sshd_addr ``` -Lフラグは、ローカルポートフォワーディングを開始することを示します。実際に意味するのは次のとおりです。 ローカルマシンで、SSHクライアントがlocal_portでリッスンを開始します(おそらくlocalhost上ですが、GatewayPorts設定によって異なります)。 このポートへのすべてのトラフィックは、SSH接続したリモートマシンからアクセスされるremote_addr:remote_portに転送されます。 図では次のようになります。 プロのヒント: ssh -f -N -L を使用して、ポートフォワーディングセッションをバックグラウンドで実行します。 ラボ1: ローカルポートフォワーディングにSSHトンネルを使用する 👨‍🔬 このラボは上記の図の設定を再現します。リモートホストは127.0.0.1:80にバインドされたWebサーバーを実行しており、これをローカルワークステーションからアクセスしたいと考えています。 サービスはループバックインターフェースにバインドされているため、ネットワーク経由では到達できません。ローカルホストから、リモートホストのパブリックアドレスにアクセスしてみてください。 ``` curl 203.0.113.30:80 # remote.public ``` ``` curl: (7) Failed to connect to 203.0.113.30 port 80 after 0 ms: Could not connect to server ``` しかし、リモートホストの内部からは、全く同じサービスが正常に動作します。 ``` curl localhost:80 ``` ``` Hello from the remote host (localhost-only service). ``` そして、ここがポイントです。ローカルホストに戻り、リモートのlocalhost:80をローカルのlocalhost:8080に、ローカルポートフォワーディングを使用してバインドします。 ``` ssh -f -N -L 8080:localhost:80 203.0.113.30 ``` これで、ワークステーションのローカルポートでWebサービスにアクセスできるようになります。 ``` 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 ``` 踏み台ホストを使ったローカルポートフォワーディング 最初は分かりにくいかもしれませんが、ssh -L コマンドは、SSHサーバー自体だけでなく、任意の (!) マシン上のリモートポートにローカルポートを転送できます。remote_addrとsshd_addrが同じ値である場合とそうでない場合があることに注目してください。 ``` ssh -L [local_addr:]local_port:remote_addr:remote_port [user@]sshd_addr ``` プライベートな宛先にアクセスするために使用されるリモートSSHサーバーは、通常、踏み台(bastion)またはジャンプホスト(jump host)と呼ばれます。私が頭の中でこのシナリオを視覚化する方法は次のとおりです。 私はよく上記のトリックを使用して、踏み台ホストからはアクセスできるが、自分のラップトップからはアクセスできないエンドポイント(例: プライベートおよびパブリックインターフェースを持つEC2インスタンスを使用して、OpenSearchクラスターやVPC内に完全にデプロイされた他のサービスに接続する)を呼び出します。 ラボ2: 踏み台ホストを使ったローカルポートフォワーディング 👨‍🔬 このラボは上記の図の設定を再現します。リモートターゲットサービスは、即席のVPCネットワーク(172.16.0.40:80)内のプライベートホストで実行されており、以前のリモートホストが、それに到達できる公開向けの踏み台(ジャンプホスト)として機能します。 ローカルワークステーションはVPCへのルーティングを持たないため、プライベートホストと直接通信できません。ローカルホストから: ``` curl --connect-timeout 3 172.16.0.40:80 # private.vpc ``` ``` curl: (28) Connection timed out after 3002 milliseconds ``` 一方、リモート踏み台はVPCに接続されており、プライベートホストに到達できます。したがって、私たちは踏み台を介してローカルポートを直接プライベートサービスに転送します。ローカルホストから: ``` ssh -f -N -L 8081:172.16.0.40:80 203.0.113.30 ``` 動作を確認します - まだローカルホスト上で: ``` curl localhost:8081 ``` ``` Hello from the private VPC host (172.16.0.40). ``` 転送ターゲット(172.16.0.40)とSSHサーバー(203.0.113.30)が異なるマシンであることに注目してください。踏み台が接続を受け入れ、私たちの代わりにプライベートホストへの2番目のホップを開きます。 同じ目標を達成するための、もう少し冗長な(しかしより明示的で柔軟な)方法です。 ``` ssh -f -N -L localhost:8081:172.16.0.40:80 203.0.113.30 # local remote via ``` リモートポートフォワーディング もう一つの人気のある(しかし逆の)シナリオは、ローカルサービスを一時的に外部に公開したい場合です。もちろん、そのためには公開向けのイングレスゲートウェイサーバーが必要になります。良いニュースは、SSHデーモンが動作している任意の公開サーバーをそのようなゲートウェイとして使用できることです。 ``` ssh -R [remote_addr:]remote_port:local_addr:local_port [user@]gateway_addr ``` 上記のコマンドは、ssh -L と比較しても複雑に見えません。しかし、落とし穴があります… デフォルトでは、上記のSSHトンネルは、リモートアドレスとしてゲートウェイのlocalhostのみを使用することを許可します。言い換えれば、ローカルポートはゲートウェイサーバーの内部からのみアクセス可能になります。これは、ほとんどの場合、あなたが実際に必要としているものではないでしょう。例えば、私は通常、ゲートウェイのパブリックアドレスをリモートアドレスとして使用して、ローカルサービスをパブリックインターネットに公開したいと考えます。そのためには、SSHサーバーをGatewayPorts yes設定で構成する必要があります。 リモートポートフォワーディングは次の目的に使用できます。 ラップトップから開発サービスをパブリックインターネットに公開し、簡単なデモを行う。 ホームラボをパブリックインターネットに公開する (f