VPSとリバースSSHの概念と応用|NAT越しで自宅PCに接続する仕組みをわかりやすく解説
「外出先から自宅のPCに繋ぎたい」という話をすると、よく出てくるのがリバースSSHという技術です。
名前は難しそうに聞こえますが、仕組みがわかると「あ、これだけのことか」と思えるくらいシンプルです。VPSとセットで理解しておくと、かなり応用が広がります。
VPS(バーチャルプライベートサーバー)とは
物理的な1台のサーバーを仮想化して、複数の独立したサーバーに分割したものです。
各VPSは:
- 独立したOSとファイルシステムを持つ
- 独占的な管理者権限がある
- ネットワークレベルで分離されている
要は「月数百円〜で借りられる、ネットに繋がったLinuxマシン」という感覚で使えます。クラウドに常時接続された踏み台として使うのが、今回の用途です。
リバースSSHとは
通常のSSHと逆方向の接続パターンです。
| パターン | 接続元 | 接続先 | 主な用途 |
|---|---|---|---|
| 通常SSH | クライアント | サーバー | サーバー管理 |
| リバースSSH | サーバー(自宅PC) | クライアント(VPS) | NAT越し接続 |
普通のSSHは「外から内へ」繋ぎに行きますが、自宅PCはルーターのNATの内側にいるため、外から直接繋ぐことができません。
リバースSSHは逆に「自宅PCが先にVPSへ繋ぎに行く」ことで、このNATの壁を突破します。
VPS × リバースSSH の全体像
[自宅PC] ──── リバースSSH接続 ────→ [VPS(公開サーバー)]
↑ │
└────────────────────────────── 外出先からトンネル経由 ←──── [スマホ・外出先PC]
- 自宅PCがVPSに向けてSSH接続を開始(これが「リバース」)
- その接続にトンネルを貼り、自宅PCのポートをVPS上に公開
- 外出先からVPSの該当ポートに接続すると、自宅PCに繋がる
基本のコマンド
# 【自宅PCで実行】VPSにリバース接続を張る
ssh -R 2222:localhost:22 user@vps.example.com
# 【外出先で実行】VPS経由で自宅PCに繋ぐ
ssh -p 2222 localhost -J user@vps.example.com
-R 2222:localhost:22 の意味:
– 2222 ← VPS側に開けるポート番号
– localhost:22 ← 自宅PCの転送先(SSHポート)
セキュリティの注意点
リバースSSHは便利ですが、設定を間違えると穴になります。
1. 公開鍵認証を必ず使う
# ❌ パスワード認証(危険)
ssh -R 2222:localhost:22 user@vps.example.com
# ✅ 公開鍵認証(推奨)
ssh -i ~/.ssh/id_ed25519 -R 127.0.0.1:2222:localhost:22 user@vps.example.com
鍵の生成:
ssh-keygen -t ed25519
2. バインドアドレスをループバックに限定する
-R 127.0.0.1:2222:localhost:22 のように 127.0.0.1 を指定すると、VPS上の自分しかポート2222を使えません。指定しないと外部全体に開放されてしまいます。
VPSの /etc/ssh/sshd_config で制御する場合:
GatewayPorts no
3. VPSのファイアウォールを設定する
# 特定IPのみ許可
sudo ufw allow from 203.0.113.0 to any port 2222
sudo ufw deny to any port 2222
4. 高いポート番号を使う
# よく使われる番号は避ける
-R 45821:localhost:22 # ランダムな高いポートのほうがスキャンに引っかかりにくい
自動再接続スクリプト
接続が切れたら自動で繋ぎ直すスクリプトです。
#!/bin/bash
# /usr/local/bin/auto-reverse-ssh.sh
VPS_USER="user"
VPS_HOST="vps.example.com"
SSH_KEY="/home/user/.ssh/id_ed25519"
REMOTE_PORT=45821
while true; do
ssh -N -i "$SSH_KEY" \
-o ServerAliveInterval=60 \
-o ServerAliveCountMax=3 \
-o ConnectTimeout=10 \
-o StrictHostKeyChecking=accept-new \
-R 127.0.0.1:$REMOTE_PORT:localhost:22 \
"$VPS_USER@$VPS_HOST"
echo "$(date): 接続が切れました。10秒後に再接続します..."
sleep 10
done
systemd に登録して常駐させる
# /etc/systemd/system/reverse-ssh.service
[Unit]
Description=Reverse SSH Tunnel
After=network.target
[Service]
Type=simple
User=username
ExecStart=/usr/local/bin/auto-reverse-ssh.sh
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
sudo systemctl enable reverse-ssh
sudo systemctl start reverse-ssh
セキュリティチェックリスト
自宅PCをリバースSSHで外部公開する前に確認しておきたい項目です。
- [ ] 公開鍵認証で接続している(パスワード認証は無効)
- [ ] バインドアドレスを
127.0.0.1に限定している - [ ] VPSのファイアウォールでアクセス元を制限している
- [ ] 高いポート番号(49152〜65535推奨)を使っている
- [ ]
ServerAliveIntervalでゾンビ接続を防いでいる - [ ] 秘密鍵にパスフレーズがある
- [ ] VPS側で
PermitRootLogin noを設定している
まとめ
リバースSSHは、NAT越しのアクセスを実現するシンプルかつ強力な仕組みです。VPSを踏み台にすることで、ポート開放不要・固定IPなしで自宅PCに繋げます。
ポイントをまとめると:
- 通常SSH:外から内へ(サーバーに固定IPが必要)
- リバースSSH:内から外へ繋いで、外からもトンネル経由でアクセス
- セキュリティは「公開鍵 + ループバックバインド + ファイアウォール」の3点セット
Cloudflare Tunnel と比べると設定は手間ですが、仕組みを理解した上で動かせるという点では、リバースSSHのほうが学習効果が高いかもしれません。
