0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

1台のPCでリバースSSH接続 + ポートフォワーディング環境を構築をしてみました!

Last updated at Posted at 2025-09-02

背景

 前回の投稿から約1年が経ちました。仕事上のある案件をきっかけに、以前「やるやる詐欺」と称して予告していたリバースSSH接続の検証に、本気で取り組むことにしました。

 一年前と比べると、生成AIは徐々に生活の中に浸透してきています。今回は、自分の考えに加え、ChatGPT 5.0の指導を受けながら検証環境を構築した経験をまとめます。

 少し本題から逸れますが、生成AIは非常に便利ですが、常に「なぜその結論になったのか」を意識しながら利用することが重要だと思います。

 本題に戻ると、今回の検証環境は以下のゴールを達成するために構築しました。
 ・リバースSSHとポートフォワーディングを組み合わせて利用するメリットを実感すること
 ・個人でも手軽に再現できる方法を探ること
 ・構築時の注意点を経験として学ぶこと
まとめると、「手を動かして覚える」ことを目的としています。

注意点

 検証に入る前に、事前練習を行うことをお勧めします。事前練習を通じて、つまずきやすいポイントを把握でき、あらかじめ対策を準備することが可能です。

例えば、事前練習を通じて以下のことが分かりました:

・ARMベースのMac(Apple Silicon:M1/M2/M4など) を使用している場合、VMware Fusionで仮想マシンを動かす際には、ARMアーキテクチャ対応のOSイメージが必要です。

・VMware Fusion の NAT は、MacからNAT IPへアクセスする場合、一部のアプリ(Chromeなど)でループバック接続がブロックされることがあります。

・SSHトンネルサービスを管理するsystemdの設定ファイル内ではExecStartは1行しか書けないです。

・ChatGPTの助言はとても参考になりますが、鵜呑みにすると、間違った設定の泥沼から抜けられなくなる可能性があります。

事前準備

・MacBook Pro 1台
 世の中の多くの個人の方が手軽に再現できることを想定し、PC1台で検証を完結させることにしました。
 PCスペック:メモリ36GB、HDD 1TB、チップ Apple M4 Max
(最近新しいPCを購入したことも、「ちゃんと検証しよう」というモチベーションになっています)

・Mac上で仮想マシンを動かすためのソフトウェア:VMware Fusion
 VMware Fusionについては説明記事が充実しているので、好きな記事を参考にすれば問題ありません。個人的にはこの記事が丁寧にまとめられていると思います。

・環境構成を考えること
「リバースSSH環境の中でポートフォワードも使いたい」
「VMware Fusionを使ってMacBook内に構築したい」
こうしたキーワードをもとに、ChatGPT先生の助言を受けていくつかの案を検討し、最終的に下記の構成を選びました。

[Mac (Remote PC)]
      ↓ (SSH ポートフォワード)
[Gateway VM (踏み台)]
      ↑ (Reverse SSHトンネル)
[Internal Server VM (Webサーバ:80)]

 ・Remote PC:外部から接続する役。VMでもいいし、Mac本体でも代用可
 ・Gateway VM (踏み台サーバ):2枚NICを持つ(外向けと内向け)
 ・Internal Server VM:踏み台の内側にあるサーバ。通常は直接アクセスできない

環境構築

検証用サーバインストール

Gateway VM (踏み台)インストール

・Ubuntu Desktop (ARM64)
・vCPU 2、RAM 4GB 、ディスク20GB目安
・NICを2枚設定
 -NAT または Bridged → 外部アクセス用
 -Host-Only → 内部ネットワーク用

実際の設定画面
  1. VMware Funsion管理画面 > 新規
    スクリーンショット 2025-09-02 18.58.34.png

2.インストール方法を選択 > ディスクまたはイメージからインストール > 続ける
スクリーンショット 2025-09-02 18.58.48.png

3.事前にダウンロードしたUbuntu Server 24.04.03 TLSイメージを選択 > 続ける
スクリーンショット 2025-09-02 18.59.11.png
 Ubuntu 22.04/24.04 LTSには公式のARM64デスクトップISOイメージがないため、Ubuntu Server ARM64をインストールした上で、Desktop環境を追加する形でUbuntu Desktopを利用しました。

 Ubuntu Serverのまま検証しても問題ありませんが、個人的にはUbuntu Desktopの方が見た目で検証結果を確認しやすいため、検証時にはDesktop環境を好んで使用する傾向があります。

4.VMのイメージ設定が終わったら、NICを追加します。デフォルトではNAT NICが存在しているため、Host-Onlyを追加
設定 > 取り外し可能デバイス > ネットワークアダプタ > デバイスを追加

スクリーンショット 2025-09-02 18.59.46.png

5.構成を「インターネット共有:Macを共有(NAT)」から「カスタム:Macをプライベート(Host-Only)に変更」
スクリーンショット 2025-09-02 19.00.18.png

6.VMの設定に戻ると、ネットワークアダプタは二つあることを確認
スクリーンショット 2025-09-02 19.00.26.png

7.この状態でVMを起動し、「Try or Install Ubuntu Server」でUbuntuをインストール
スクリーンショット 2025-09-02 19.00.38.png
 その後も画面のガイダンスに従って、インストールを完了させます。

8.SSHは利用するため、インストール時に「Install OpenSSH Server」を選ぶと便利
スクリーンショット 2025-09-02 20.24.54.png
 SSH鍵は後で設定するため、ここではImportしなくていいです。

9.Ubuntu Serverのインストールが完了し、コマンドラインが利用できたら下記のコメントでUbuntu Desktopへ変換

sudo apt update && sudo apt upgrade -y
sudo apt install ubuntu-desktop-minimal -y #テストのため、軽量版のデスクトップを利用
sudo reboot

 このステップでは少し時間がかかります。

10.Ubuntuの基本設定

# 基本ツールインストール、必要なものをご自由に追加
sudo apt install -y net-tools curl vim git ufw

# SSH 有効化(デフォルトではdisabledになっている)
sudo systemctl enable --now ssh

# IPアドレスの確認/固定化(任意)
ip -4 addr show
sudo nano /etc/netplan/01-netcfg.yaml
# Host‑Only側インタフェース(例:ensX)に静的IPを付けたい場合(サブネットは実環境に合わせて)は下記のようにYamlファイルを作成:
ーーーーーーーーーーーーーーーーーーーーーーーーー
network:
  version: 2
  ethernets:
    ens160: # 外向きNIC(NAT/Bridged)検証環境では172.16.112.133を利用
      dhcp4: true
    ens192: # 内向きNIC(Host-Only)
      addresses: [192.168.244.134/24]
ーーーーーーーーーーーーーーーーーーーーーーーーー

#反映
sudo netplan apply

11.SSHサーバ設定(ポートフォワードを許可)

sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
sudo nano /etc/ssh/sshd_config

# 変更点:
AllowTcpForwarding yes # SSH ポートフォワーディングの利用を許可
GatewayPorts yes # リバースフォワード (ssh -R) で待ち受けるアドレス範囲を制御、Yesでは 0.0.0.0 で待ち受けるようになり、LAN 内や外部のクライアントからもアクセス可能になる

#反映
sudo systemctl restart ssh

12.ホストベースのFW(ufw)で必要なセキュリティ設定

sudo ufw default deny incoming
sudo ufw allow OpenSSH
sudo ufw allow from 192.168.244.0/24 to any port 8080 proto tcp # 内向きNIC側のサブネットから8080ポート(SSH)に対する接続を許可
sudo ufw allow from 172.16.112.0/24 to any port 8080 proto tcp # NAT NIC側のサブネットから8080ポートに対する接続を許可
sudo ufw enable # ufwを有効化
sudo ufw status verbose # ufwの基本設定を確認

Internal Server VM (Webサーバ:80)インストール

・Ubuntu Desktop (ARM64)
・vCPU 2、RAM 2GB 、ディスク20GB目安
・NICを1枚設定
 -Host-Only → 内部ネットワーク用
(初期設定時は2枚目のNAT NICを有効化 → Apacheなどを入れるため、その後無効化)

1.VMをインストール
 Gateway-VMとほぼ同じ手順で行うため、ここでは詳細は割愛します。

2.基本ツールインストール

sudo apt update && sudo apt -y upgrade
sudo apt install -y net-tools curl vim git ufw openssh-server autossh apache2 
# Gateway-VMにはない、後で使用する autossh と Apache をインストール 

3.テスト用Apacheを有効化し、テストページを作成

sudo systemctl enable --now apache2
sudo nano /var/www/html/index.html

# サンプル内容
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
<!DOCTYPE html>
<html>
<head>
    <title>Internal VM Test Page</title>
</head>
<body>
    <h1>This is a test page for Reverse SSH</h1>
    <p>This page is from Apache on Internal VM.</p>
</body>
</html>
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

# ローカルから動作確認
curl -I http://127.0.0.1

スクリーンショット 2025-09-03 11.00.39.png

Internal-VMのブラウザからも確認可能
スクリーンショット 2025-09-02 22.30.58.png

4.リバースSSHを手動テスト

# Internal-VM -> Gateway-VM へリバースフォワード
ssh -N -R 8080:localhost:80 <gateway_user>@<gateway_in_ip>

これで Gateway-VMの 8080 が Internal-VMの80 につながります。
Remote(Mac)から http://gateway_out_ip:8080 へアクセスでApacheのテストページが表示されます。

スクリーンショット 2025-09-03 10.54.39.png

5.リバースSSHを自動維持

# 自動リバースSSH用のsystemdユニット作成
sudo nano /etc/systemd/system/reverse-tunnel.service

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
[Unit]
Description=Reverse SSH Tunnel
After=network.target

[Service]
User=youruser
ExecStart=/usr/bin/ssh -N -R 0.0.0.0:8080:localhost:80 user@gateway-Internal-IP
Restart=always
RestartSec=5
Environment="HOME=/home/youruser"

[Install]
WantedBy=multi-user.target
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

# 有効化
sudo systemctl daemon-reload
sudo systemctl enable --now reverse-tunnel.service
sudo systemctl status reverse-tunnel.service

# 自動リバースSSHをリアルタイムで確認するログを表示させる
journalctl -u reverse-tunnel.service -f

6.必要なセキュリティ設定

sudo ufw allow OpenSSH
sudo ufw allow 80/tcp # 内部だけでOK、Webは外に出さない(ポートフォワード経由で見せる)
sudo ufw enable

7.SSH鍵を作成し、Gateway-VM に公開鍵を登録

ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa
ssh-copy-id -i ~/.ssh/id_rsa.pub user@gateway-Internal-IP
ssh -v user@gateway-Internal-IP # パスワードを聞かれずにログインできればOK

スクリーンショット 2025-09-02 23.11.53.png

Remote PC(Mac)上の設定・作業

1.SSH接続用の鍵を生成し→Gateway-VMへ配布(Internal-VMに対しては直接SSH接続ではなく、リバースSSHトンネルで接続するため、Internal-VMへの配布は不要)

ssh-keygen -t ed25519 -C "mac-m4max"
ssh-copy-id <user>@<gateway_out_ip> # Gateway-VMへSSH公開鍵を配布

2.Macbookのターミナルからリバースポートフォワードを使い、本来到達できないInternal-VMへアクセス

# Apacheに到達(Internalの80番)
curl http://<gateway_out_ip>:8080

スクリーンショット 2025-09-02 23.33.27.png

3.ブラウザからhttp://gateway_out_ip:8080へアクセス
スクリーンショット 2025-09-02 23.35.15.png
Internal-VMのテストページ(80)にフォワードされたことを確認できました!
注意:Chromeではセキュリティの制約でテストページにアクセスできず、検証の場合はFirefoxを利用してください。

4.ローカルフォワードを併用可能(延長線上にできることを確認)

# Mac側の 9090 を Gateway:8080 に接続(結果として Internal:80 へ)
ssh -L 9090:localhost:8080 <user>@<gateway_out_ip> 
# → http://localhost:9090 で表示

スクリーンショット 2025-09-02 23.41.34.png
スクリーンショット 2025-09-02 23.41.13.png

5.ここまで来て、MacからGateway-VM経由でInternal-VMへのSSHアクセスも実現してみたい
トンネルを常に貼りたいため、まずはInternal-VMのsystemd サービスファイルに下記の記述を追加

5.1下記はInternal-VM側で作業

sudo nano /etc/systemd/system/reverse-tunnel.service
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
[Unit]
Description=Reverse SSH Tunnel
After=network.target

[Service]
User=youruser
# 追加 (例: Gatewayの2222ポート→Internal VMの22)
ExecStart=/usr/bin/ssh -N -R 2222:localhost:22 -R 8080:localhost:80 user@gateway_Internal_ip -p 22 -o ServerAliveInterval=60 -o ServerAliveCountMax=3

#ExecStart=/usr/bin/ssh -N -R 0.0.0.0:8080:localhost:80 user@gateway-Internal-IP
Restart=always
RestartSec=5
Environment="HOME=/home/youruser"

[Install]
WantedBy=multi-user.target
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
sudo systemctl daemon-reload
sudo systemctl enable reverse-tunnel
sudo systemctl start reverse-tunnel

5.2Gateway-VM側のUFW設定を追加

# Internal VM へのリバーストンネル (SSH 用)を追加
sudo ufw allow 2222/tcp

# セキュリティを考えると、ポートを全開放するのは危険なので Mac の IP アドレスに限定すると安心
sudo ufw allow from <mac-global-ip> to any port 2222 proto tcp

sudo ufw enable
sudo ufw reload

5.3 Mac側から接続確認

ssh -p 2222 <user>@<gateway_public_ip>

Internal-VMへSSH接続できたことを確認できました!
スクリーンショット 2025-09-03 12.02.28.png

Gateway-VM上のポート稼働状況を確認

sudo ss -tulnp

-t → TCP
-u → UDP
-l → LISTEN(待ち受け中のポート)
-n → 数字で表示(ポート番号/IP)
-p → プロセス名/PID 表示

スクリーンショット 2025-09-03 12.04.30.png

 結果から言えること:
・ポート22 、2222、8080が待機して、sshd が待ち受けている
・IPv4 (0.0.0.0) と IPv6 ([::]) の両方で listen 中
・リバーストンネルはきちんと動いている

 つまり、リバースSSHトンネル自体は正常に確立しています!
 これで、1台のPC上でリバースSSH接続とポートフォワーディング環境を再現できました。

学んだこと

 リバースSSH接続とポートフォワーディングを組み合わせると、通常の「外部からアクセスできない環境」でも柔軟かつ安全に接続できるようになります。

具体的には、下記の代表的なメリットが考えられます:
・NAT越え / ファイアウォール越えが簡単
 -普通は外部から家庭内や社内のサーバに直接アクセスできません(NATやFWで遮断)。
 -リバースSSHは内部から外部へ接続する仕組みなので、通常のアウトバウンド通信として許可されやすいです。

・単一のIP/ポート経由で複数サービスにアクセス可能
 -1台の踏み台サーバ(Gateway-VMなど)経由で、複数の内部サービスに接続できる。
 -外部に直接公開せずに済むのでセキュリティ上安全。

・セキュリティの向上
 -ファイアウォールで制限されたポートやサービスにも、安全にアクセスできる。
 -外部に直接サービスを公開しないため、攻撃リスクが低くなる。

・VPNを張らなくてもリモートアクセスが可能
 -VPN構築よりも簡単。サーバ1台とSSHだけで最低限の環境を作れる。

・シンプルで導入しやすい
 -専用ソフト不要、SSHだけで実現可能。

最後に

 ようやく自分に約束した検証を完成させました。
 これからはコンテナとクラウドの勉強を再開する予定なので、近いうちにクラウドに関する投稿をするかもしれません。

 この未熟な記事が、どこかで誰かの参考になれば幸いです。いつも温かく見守ってくださる方々に、心から感謝します!

 今後もより良い記事を書けるよう、この新しいMacBookを大切に使っていきたいと思います!
IMG_6166.jpg

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?