「本番サーバーで動くWebアプリをローカルブラウザで確認したい…」
こうした場面で威力を発揮するのが、sshコマンドのポートフォワーディングです。暗号化されたSSHトンネルを通じて、直接アクセスできないサーバーやポートへ安全に接続できます。
この記事では、ローカル転送(-L)・リモート転送(-R)・ダイナミック転送(-D)の3種類を、RHEL 9.4 / Ubuntu 24.04 LTSで動作確認した実行例付きで解説します。踏み台サーバー経由のDB接続からSOCKSプロキシ設定まで、一気に理解できます。
この記事のポイント
・ssh -L でローカルポートをリモートサーバーへ安全に転送できる
・ssh -R でリモート側から手元のポートを外部へ公開できる
・ssh -D でSOCKSプロキシを立ち上げ全通信をトンネリングできる
・~/.ssh/config に書けばオプション省略で毎回の打ち込みが不要
でも安心してください。プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
SSHポートフォワーディングとは何か
SSHポートフォワーディング(SSHトンネリング)とは、SSHの暗号化通信路を使って任意のポートへの通信を転送する機能です。たとえば社内ネットワーク内のMySQLサーバー(外部から直接アクセス不可)へ、踏み台となるSSHサーバー経由で安全に接続できます。通信はSSHが暗号化するため、平文でパケットが流れる心配がありません。
ポートフォワーディングには大きく3種類あります。
・ローカルポートフォワーディング(-L):手元のポートをリモートへ転送。踏み台経由でDB・Webアプリへ接続するときに使う
・リモートポートフォワーディング(-R):リモートのポートを手元へ転送。外部からアクセスできない手元サービスを一時公開するときに使う
・ダイナミックポートフォワーディング(-D):SOCKSプロキシとして機能。特定ポートではなく全通信をトンネル経由にしたいときに使う
ローカルポートフォワーディング(-L)の使い方
ローカルポートフォワーディングは、手元(クライアント)の指定ポートをSSHサーバー経由で別ホストのポートへ転送します。踏み台サーバー越しに内部ネットワークのホストへアクセスするときに最も多用します。1. 基本構文
# 書式 ssh -L [ローカルポート]:[転送先ホスト]:[転送先ポート] [SSHユーザー@SSHサーバー] # 例: 踏み台サーバー bastion.example.com 経由で内部DB(192.168.10.20:3306)へ接続 ssh -L 13306:192.168.10.20:3306 admin@bastion.example.com
# ローカルの13306番ポート経由でMySQLへ接続 mysql -h 127.0.0.1 -P 13306 -u dbuser -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 48 Server version: 8.0.36
2. トンネルが開通しているか確認する
ssコマンドでLISTENしているポートを確認します。$ ss -tlnp | grep 13306 LISTEN 0 128 127.0.0.1:13306 0.0.0.0:* users:(("ssh",pid=12847,fd=5))
3. バックグラウンドで起動する
ターミナルを占有させたくない場合は -fN オプションを組み合わせます。# -f: バックグラウンドへ移行 -N: リモートコマンド実行なし(トンネルのみ) ssh -fNL 13306:192.168.10.20:3306 admin@bastion.example.com # 切断するには対象プロセスをkillする ps aux | grep ssh kill [pid]
リモートポートフォワーディング(-R)の使い方
リモートポートフォワーディングは、SSHサーバー側のポートを手元(クライアント)のポートへ転送します。外部からアクセスできない手元のサービスをリモートサーバー経由で一時的に公開したいときに使います。1. 基本構文
# 書式 ssh -R [リモートポート]:[転送先ホスト]:[転送先ポート] [SSHユーザー@SSHサーバー] # 例: リモートサーバーの18080番ポートを手元のlocalhost:8080へ転送 ssh -R 18080:localhost:8080 admin@public-server.example.com
2. GatewayPorts の設定
デフォルトでは、リモートポートフォワーディングは127.0.0.1のみにバインドされます。外部からリモートサーバーのIPアドレス経由でアクセスしたい場合は、SSHサーバー側の /etc/ssh/sshd_config に以下の設定が必要です。# /etc/ssh/sshd_config に追記 GatewayPorts yes # 設定を反映する systemctl restart sshd
ダイナミックポートフォワーディング(-D)の使い方
ダイナミックポートフォワーディングは、手元にSOCKSプロキシサーバーを立ち上げます。特定のポートではなく、アプリケーションが指定したすべての通信をSSHトンネル経由に流せるのが特徴です。1. 基本構文
# 書式 ssh -D [ローカルSOCKSポート] [SSHユーザー@SSHサーバー] # 例: localhost:1080 にSOCKSプロキシをバックグラウンドで起動 ssh -fND 1080 admin@bastion.example.com
# curlでSOCKSプロキシ経由にアクセスする例 curl --socks5 127.0.0.1:1080 http://internal-web.example.com/ # Firefoxの場合: 設定 → ネットワーク設定 → 手動プロキシ # SOCKSホスト: 127.0.0.1 ポート: 1080 SOCKS v5 を選択
~/.ssh/config で設定を省力化する
毎回長いオプションを入力する手間は、~/.ssh/config に記述することで省略できます。設定ファイルにまとめておけば、トンネル名を指定するだけで起動できます。# ~/.ssh/config の記述例 # 踏み台サーバーの基本設定 Host bastion HostName bastion.example.com User admin IdentityFile ~/.ssh/id_ed25519 ServerAliveInterval 60 ServerAliveCountMax 3 # DBへのローカルポートフォワーディングをまとめて設定 Host db-tunnel HostName bastion.example.com User admin IdentityFile ~/.ssh/id_ed25519 LocalForward 13306 192.168.10.20:3306 LocalForward 15432 192.168.10.21:5432
# db-tunnel の設定でトンネルをバックグラウンド起動 ssh -fN db-tunnel
トラブルシュート・エラー対処
「channel 2: open failed: connect failed」が出た時の対処法
このエラーはSSHサーバーから転送先ホストへの接続に失敗したことを示します。・転送先ホスト(例: 192.168.10.20)が稼働しているか確認する
・転送先ポート(例: 3306)がListenしているか、SSHサーバー上でssコマンドで確認する
・SSHサーバーから転送先ホストへの経路(ファイアウォール・セキュリティグループ)を確認する
接続先ホスト名が正しく解決されているかどうかは、dig コマンドで DNS を調べることで確認できます。
「AllowTcpForwarding no」で転送が拒否される場合
SSHサーバー側の /etc/ssh/sshd_config でポートフォワーディングが無効になっている場合があります。# 設定を確認 grep AllowTcpForwarding /etc/ssh/sshd_config # yes に変更して反映 AllowTcpForwarding yes systemctl restart sshd
「bind: Address already in use」が出た時の対処法
ローカルポートがすでに使用中の場合は、別の番号を指定してください。どのプロセスが使っているかは ss -tlnp コマンドで特定できます。# 13306番を使っているプロセスを確認 $ ss -tlnp | grep 13306 LISTEN 0 128 127.0.0.1:13306 0.0.0.0:* users:(("ssh",pid=9843,fd=5)) # プロセスIDを確認してkillする kill 9843
接続後すぐに「Connection closed by remote host」が出る場合
SSHの接続が切れると、そのトンネルも切断されます。~/.ssh/config の ServerAliveInterval で定期的にキープアライブパケットを送信するよう設定してください。# ~/.ssh/config に接続維持設定を追加 Host * ServerAliveInterval 60 ServerAliveCountMax 3
本記事のまとめ
| やりたいこと | コマンド |
|---|---|
| 手元のポートをリモート経由で転送(ローカル) | ssh -L 13306:192.168.10.20:3306 user@bastion |
| バックグラウンドでトンネルを起動(ローカル) | ssh -fNL 13306:192.168.10.20:3306 user@bastion |
| リモートのポートを手元へ転送(リモート) | ssh -R 18080:localhost:8080 user@server |
| SOCKSプロキシをバックグラウンドで起動(ダイナミック) | ssh -fND 1080 user@bastion |
| curlでSOCKSプロキシ経由アクセス | curl --socks5 127.0.0.1:1080 http://example.com/ |
| 設定ファイルからトンネル起動 | ssh -fN db-tunnel |
| トンネルのListenポートを確認 | ss -tlnp | grep [ポート番号] |
SSHの基礎から現場で使えるサーバー管理スキルを体系的に学びたいなら
SSHポートフォワーディングを使いこなせると、踏み台構成・安全な通信設計の幅が格段に広がります。
ネットの断片的な情報をつなぎ合わせるだけでなく、現場で通用する安全なLinuxサーバー構築の「型」を体系的に身につけたい方へ、『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼントしています。
「独学の時間がもったいない」「プロから直接、現場の技術を最短で学びたい」という本気の方には、2日で実務レベルのスキルが身につく【初心者向けハンズオンセミナー】も開催しています。
3,100名以上が実践した「型」を無料で公開中
プロのエンジニアはコマンドを暗記していません。
「現場で使える型」を効率よく使いこなしているだけです。
その「型」を図解60Pにまとめた入門マニュアルを、完全無料でプレゼントしています。
登録10秒/合わなければ解除3秒 / 詳細はこちら
- 次のページへ:patchコマンドでファイルを差分適用する方法|--dry-runで安全確認とロールバックも
- 前のページへ:localectlコマンドでLinuxのロケールとキーボードを設定する方法|文字化け対策と環境統一も
- この記事の属するカテゴリ:Linuxtips・ネットワークへ戻る

無料メルマガで学習を続ける
Linuxの実践スキルをメールで毎週お届け。
登録は1分、解除もいつでも可。
登録無料・いつでも解除できます