Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

第6章 ポート転送(SSHトンネル)

ポート転送(SSH トンネル)とは

ポート転送(ポートフォワーディング)は、SSH の暗号化された通信経路(トンネル)の中に別の TCP 通信を通す技術です。

この技術を使うことで、インターネットに直接公開されていない社内 Web 画面やプライベートなデータベース(MySQL や PostgreSQL など)に対し、手元の PC から安全にアクセスできるようになります。

SSH のポート転送には、通信の向きや用途に応じて以下の 3 種類が存在します。

  • ローカルポート転送(-L):

    手元 PC のポートへの通信を、SSH サーバ経由で目的のリモートサーバへ転送します。

  • リモートポート転送(-R):

    リモートサーバのポートへの通信を、SSH サーバ経由で手元のローカル PC へ転送します。

  • ダイナミックポート転送(-D):

    手元 PC を SOCKS プロキシ化し、任意の宛先への通信を SSH サーバ経由で中継します。

1. ローカルポート転送(-L)

リモートネットワーク内に存在する非公開サービスへアクセスする最も代表的な手法です。

[手元 PC (localhost:8080)] ===(SSH暗号化トンネル)===> [SSH サーバ] ───> [社内Web (192.168.1.200:80)]

コマンド構文

ssh -L <ローカルポート>:<転送先ホスト>:<転送先ポート> <ユーザー名>@<SSHサーバ>

具体例:リモートのデータベースに接続する

外部から接続できないリモートサーバ上の PostgreSQL(ポート 5432)に接続したい場合:

ssh -L 15432:localhost:5432 user@ssh-server

このコマンドを実行している間、手元 PC の localhost:15432 に接続するだけで、自動的にリモートサーバ上の localhost:5432 へパケットが暗号化転送されます。手元の GUI データベースクライアントから安全に操作できます。

2. リモートポート転送(-R)

手元のローカル PC で動作している開発用サーバーなどを、離れたリモートサーバ側からアクセス可能にする手法です。

[リモートクライアント] ───> [SSH サーバ (:8080)] ===(SSH暗号化トンネル)===> [手元 PC (localhost:3000)]

コマンド構文

ssh -R <リモートポート>:<ローカルホスト>:<ローカルポート> <ユーザー名>@<SSHサーバ>

具体例:手元で開発中の Web アプリを共有する

手元の PC で動いている Node.js 開発サーバー(ポート 3000)を、リモートサーバのポート 8080 で待ち受けて公開する場合:

ssh -R 8080:localhost:3000 user@ssh-server

リモートサーバ上で curl http://localhost:8080 を実行すると、手元 PC のポート 3000 で動作する Web アプリが応答します。

▸ リモートポートを外部ホストに公開する場合(GatewayPorts)

デフォルトでは、リモート転送されたポートはリモートサーバ自身のループバック(127.0.0.1)にのみバインドされます。外部の第三者マシンからもアクセス可能にするには、サーバ側の /etc/ssh/sshd_config で GatewayPorts yes を有効化する必要があります。

3. ダイナミックポート転送(-D)

手元 PC の指定ポートを SOCKS5 プロキシサーバーとして機能させます。 Web ブラウザ等のプロキシ設定をこれに向けることで、ブラウザからのすべてのアクセスがあたかも SSH サーバからアクセスしているかのように振る舞います。

コマンド構文

ssh -D <ローカルポート> <ユーザー名>@<SSHサーバ>

具体例:SOCKS プロキシの起動

ssh -D 1080 user@ssh-server

手元 PC のブラウザ設定で SOCKS5 プロキシとして 127.0.0.1:1080 を指定すると、安全でないフリー Wi-Fi 環境からでも、すべてのブラウジング通信を SSH 暗号化トンネル経由で行うことができます。

トンネル専用の便利なオプション(-N と -f)

ポート転送のトンネルを維持するだけで、リモートサーバのシェルプロンプトを操作する必要がない場合は、以下のオプションを組み合わせます。

  • -N: リモートコマンドを実行せず、ポート転送のみを行う。
  • -f: 認証完了後、直ちにプロセスをバックグラウンドへ移行する。
# バックグラウンドでローカルポート転送を常駐
ssh -f -N -L 15432:localhost:5432 user@ssh-server

バックグラウンド接続を終了したい場合は、kill コマンドで対象プロセスの PID を停止します。

.ssh/config によるポート転送の自動化

コマンドラインで長い引数を指定する代わりに、~/.ssh/config に転送定義をあらかじめ記述しておくことができます。

# 社内 DB トンネル用定義
Host tunnel-db
    HostName 203.0.113.10
    User developer
    IdentityFile ~/.ssh/id_ed25519_dev
    IdentitiesOnly yes
    # ローカル 15432 をリモートの 5432 に転送
    LocalForward 15432 localhost:5432

# SOCKS プロキシ用定義
Host socks-proxy
    HostName 203.0.113.20
    User proxy-user
    IdentityFile ~/.ssh/id_ed25519_proxy
    IdentitiesOnly yes
    # ローカル 1080 を SOCKS プロキシ化
    DynamicForward 1080

これにより、単に ssh tunnel-db や ssh -f -N tunnel-db と実行するだけで、意図したポート転送が即座に開始されます。