SSHを使ったリモート接続の世界に興味はありますか?前回の記事では、SSHキーの作成、基本的な接続コマンド、そしてローカルポートフォワーディング(-L)を紹介しました。今回は、SSHのもう一つの強力な機能である リバースポートフォワーディング(Reverse Port Forwarding)、つまり -R オプションを詳しく見ていきましょう。

-L が「自分のPCから外部へトンネルを掘って、外部のリソースにアクセスする」仕組みだとすれば、-R はその逆です。「外部(リモート側)から自分のPCへ向かうトンネルを作り、内部のリソースへ到達できるようにする」。言い換えるなら、外側の世界に“入口”を用意するような機能です。


リバースポートフォワーディングとは?(-R の概要)



一般に、リモートサーバー(Server A)からローカルマシン(Client B)へ直接接続するのは簡単ではありません。Client B がプライベートIPの内側にいたり、ファイアウォールで守られていたり、固定IPを持たないことが多いからです。

そこで -R を使うと、Client B が Server A に SSH 接続を張るのと同時に、Server A 側に“待ち受けポート”を作り、そこへのアクセスを SSH トンネル経由で Client B の指定ポートへ転送できるようになります。

流れはシンプルです。

  1. Client B(自分のマシン)Server A(外部サーバー)へ SSH 接続します。
  2. 接続時に -R を指定し、「Server A の X 番ポートに来た通信を、Client B の Y 番ポートへ流してほしい」と伝えます。
  3. すると、誰かが Server A の X 番ポートへアクセスしたとき、その通信は SSH トンネルを通って Client B の Y 番ポートへ転送されます。

つまり Client B が Server A に「外から私に入って来られる入口を作って」とお願いするイメージです。

SSHリバースポートフォワーディングフローチャート: 外部要求がサーバーを経由してローカルに転送される構造


-R コマンドの構成

リバースポートフォワーディングの基本形は次の通りです。

ssh -R [リモート_ポート]:[対象_ホスト]:[対象_ポート] [リモート_サーバー_ユーザー]@[リモート_サーバー_アドレス]

各要素の意味は以下の通りです。

  • ssh: SSHクライアントを起動するコマンド
  • -R: リバースポートフォワーディング(リモート側に待ち受けを作る)
  • [リモート_ポート]: Server A 側で待ち受けるポート番号。外部からここに来た通信がトンネルに入ります。
  • [対象_ホスト]: Client B 側で到達させたい宛先ホスト。多くの場合は localhost(Client B 自身)です。
  • [対象_ポート]: Client B 側で動いているサービスのポート番号。最終的にここへ届きます。
  • [リモート_サーバー_ユーザー]@[リモート_サーバー_アドレス]: SSH 接続先の Server A のユーザーとアドレス。トンネルの入口となるサーバーです。

例: Client B の 8080 番で動くWebサーバーへ、Server A の 8888 番ポート経由でアクセスしたい場合:

# Client B(自分のマシン)で実行
ssh -R 8888:localhost:8080 user@server_a_public_ip

この接続が確立している間、別のマシンから http://server_a_public_ip:8888 にアクセスすると、実際には Client B の localhost:8080 に到達します。


リバースポートフォワーディングはいつ役立つ?(開発での活用例)



-R は、通常のSSH接続だけでは解決しづらい場面で真価を発揮します。特に開発中の「ローカル環境を外部とつなぐ」用途で便利です。

1. NAT/ファイアウォール配下のローカル開発サーバーを一時公開

  • 状況: 自宅や社内ネットワークで開発中のWebアプリ(例:localhost:3000)を、外部のメンバーやクライアントに見せたい。しかしローカル環境はプライベートIP配下で、外部から直接アクセスできない。ルーターやファイアウォールの設定変更も簡単ではない。
  • 解決: パブリックIPを持つサーバー(VPSやクラウド)を経由して、ローカル開発サーバーを外部へ公開できます。
# ローカル開発マシン(Client B)で実行
ssh -R 80:localhost:3000 your_user@your_public_server.com
# 80番は権限が必要な場合があるので、別ポートを使う例
ssh -R 8080:localhost:3000 your_user@your_public_server.com

以後、http://your_public_server.com:8080 にアクセスすると、実際にはあなたの localhost:3000 に到達します。

2. Webhook(ウェブフック)の受信テスト

  • 状況: 決済、GitHub/GitLab、通知サービスなどのWebhookをローカルで受けて試したい。しかしWebhookは基本的にパブリックURLにしか送れない。
  • 解決: -R でローカルのWebhookエンドポイントを外部サーバー上のURLへ“見せかけて”受信できます。
# ローカル開発マシン(Client B)で実行
ssh -R 5000:localhost:5000 your_user@your_public_server.com

Webhookの送信先に http://your_public_server.com:5000/webhook を指定すれば、イベントはトンネル経由でローカルへ届きます。

3. 外部から閉じたネットワーク内のサービスに到達したい

  • 状況: ファイアウォール配下のサーバー(Client B)で動くDBや管理ツール(例:localhost:9000)に外部からアクセスしたい。しかし外部向けポートは閉じている。ただし Client B からは外部サーバー(Server A)へ SSH 接続できる。
  • 解決: Client B から Server A に -R 付きで接続し、Server A 側に入口を作ります。
# Client B(閉じたネットワーク側)で実行
ssh -R 9000:localhost:9000 your_user@server_a_public_ip

これで外部から server_a_public_ip:9000 にアクセスすると、Client B の localhost:9000 へ到達できます。

4. 一時的なデモや短期共有

  • 状況: 同僚にローカルで動くアプリの動作を短時間だけ見せたい、簡単に外部公開してフィードバックを取りたい。
  • 解決: SSHセッションを切れば公開も即終了できるため、短期共有に向きます。

リバースポートフォワーディング使用時の注意点

  • GatewayPorts yes: -R で作られたリモート側ポートは、デフォルトでは Server A 自身からのアクセスに限定されることがあります。Server A 以外の外部マシンからも接続できるようにするには、sshd_configGatewayPorts yes を設定し、SSHサービスの再起動が必要です。公開範囲が広がるため、セキュリティ面に注意してください。

  • セキュリティ: ローカルのサービスを外部へ露出させる機能なので、信頼できるサーバーにだけ使い、公開先サービス自体の脆弱性も事前に確認しましょう。

  • SSHセッションの維持: トンネルはSSH接続が生きている間だけ有効です。常時実行したい場合は ssh -fN -R ... のように -f(バックグラウンド)と -N(リモートコマンドを実行しない)を併用するのが一般的です。


おわりに

SSHリバースポートフォワーディング(-R)は、複雑なネットワーク環境やファイアウォール配下のサービスを外部から利用したいときに非常に役立ちます。ローカル開発環境の共有やWebhookテストなど、開発フローを大きく楽にしてくれる強力な道具です。

もし難しく感じたら、まずは小さな例で実際に動かしてみるのが一番です。あなたの開発ワークフローにも、ぜひ -R を取り入れてみてください。

疑問があれば、いつでもコメントで質問してください!