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]
  1. 自宅PCがVPSに向けてSSH接続を開始(これが「リバース」)
  2. その接続にトンネルを貼り、自宅PCのポートをVPS上に公開
  3. 外出先から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のほうが学習効果が高いかもしれません。

関連記事

ブログ

BLOG

PAGE TOP