ホームネットワーク内のサービスをVPN内に公開する
ホームネットワーク内のサーバーで起動しているサービスをVPN内に公開する方法です。
ホームネットワーク内のサーバーはVPNに参加しないというのが肝です。
VPNに接続したマシンがホームネットワーク内の特定のマシンに起動中のサービスにアクセスできるようにします。
ホームネットワーク内のjellyfinの起動しているサーバー(Target Searver/192.168.1.20:8097)に外出先からアクセスするというシナリオで説明を進めます。 ホームネットワーク内のサーバーがjellyfinのポートをリモートフォワーディングします。
なお、初期設定はホームネットワーク内で行う必要があるため、ホームネットワーク内のサーバーがVPNサーバーの51821ポートをローカルフォワーディングします。
ホームネットワーク内の公開したいサーバーはVPN内にのみ公開されます。 全世界に公開するというより、外出先でホームネットワーク内のサーバーを使いたい場合に使用します。
詳細は下記githubを参照してください。 https://github.com/syagawa/vpn-wireguard-settings-with-ssh-tunnel
なお、下記はgithubの内容とだいたい同じですので好きな方を参照してください。
System Architecrure
- A. VPN サーバー(203.0.113.50 username: ubuntu) AWS、GCP、Oracle、さくらなどのLinuxマシン 任意のクラウド(AWS・GCP など)を利用できます。
- B. ホームネットワーク
- Tunnel Server(Linux 192.168.1.10)
- Target Server(Linux 192.168.1.20:8097)
- C. VPN クライアント Linux / Android
ABCともにOSはUbuntuを前提としていますが、他のLinuxディストロでもおおむね動作します。また、CはWireGuardクライアントがインストールできればLinuxである必要はありません。
Installation and Configuration
A. VPN サーバーの設定
-
VPSを用意します、この説明ではOracle Cloudのコンピュートインスタンス(Ubuntu)を前提に話をすすめますが、AWSでもGCPでもさくらのクラウドでも特に変わりはないと思います。作成したマシンのIPは203.0.113.50、ユーザー名はubuntuとして話を進めます。
-
VPSにsshでログインしパッケージのアップデートとインストールを行います
# パッケージのアップデート
$ sudo apt update
$ sudo apt upgrade
# 使用する可能性のあるパッケージをインストール
$ sudo apt install git vim curl wget htop ncdu lsof
# dockerのインストール
下記公式に従ってインストール
https://docs.docker.com/engine/install/ubuntu/#install-using-the-repository
- wireguard-easyのインストールと設定
# ネットワークを設定
$ docker network create \
--driver=bridge \
--subnet=10.42.42.0/24 \
--ipv6 \
--subnet=fdcc:ad94:bacf:61a3::/64 \
--opt com.docker.network.bridge.name=wg0 \
wg
# このレポジトリのwgをホーム(~)に持ってくる
$ git clone https://github.com/syagawa/vpn-wireguard-settings-with-ssh-tunnel.git
$ cd vpn-wireguard-settings-with-ssh-tunnel
$ cd wg
# compose.ymlの編集
$ vim compose.yml
## <VPS external IP> をVPSの外部IPに書き換えるこの例だと203.0.113.50
- nginxの設定
# init.shに実行権限を付与
$ chmod +x init.sh
# 公開ポートの編集
$ vim default.conf
## server内のlistenに設定するポートを記述
## 例 jellfinの 8097を設定する;
listen 8097;
## いらないlistenの行は消す
## ポートは自由に変更可能だが、説明を簡易にするためjellyfinならデフォルトポートである8097で話を進める
- wg-easyコンテナの起動と、コンテナ内nginxの起動
$ docker compose -f compose.yml up -d
$ docker compose -f compose.yml exec -d wg-easy sh /usr/local/bin/init.sh
- ホスト側の設定変更
# sysctlでの設定変更
$ sudo vim /etc/sysctl.d/99-sysctl.conf
## 下記に変更
net.ipv4.ip_forward=1
$ sysctl -p /etc/sysctl.d/
# ssh設定の変更
$ sudo vim /etc/ssh/sshd_config
## 下記に変更
GatewayPorts yes
AllowTcpForwarding yes
$ sudo systemctl restart ssh
# iptablesの設定
$ sudo apt install iptables-persistent
$ sudo iptables -I INPUT 1 -i wg0 -j ACCEPT
$ sudo iptables -I INPUT 2 -i wg0 -p icmp -j ACCEPT
$ sudo netfilter-persistent save
- VPSのネットワーク側のUDP:51820を許可(Oracleの場合)
コンピュート > インスタンス > 仮想クラウドネットワーク(VCN) > vcnなんちゃらを選択 > セキュリティ > セキュリティ・リスト > Default Security なんちゃらを選択 > セキュリティ・ルール > イングレス・ルール から UDP:51820を追加する
GCPやAWSさくらでも同様な設定が必要なはずです。
B. ホームネットワーク側Tunnel Serverの設定
ホームネットワーク内のTunnel Server(Ubuntuを想定)を使用。IPは192.168.1.10とする。
- ホームネットワーク内のサーバーのパッケージのアップデートとdockerのインストール
# パッケージのアップデート
$ sudo apt update
$ sudo apt upgrade
# 使用する可能性のあるパッケージをインストール
$ sudo apt install git vim curl wget htop ncdu lsof
# dockerのインストール
下記公式に従ってインストール
https://docs.docker.com/engine/install/ubuntu/#install-using-the-repository
- sshの設定
# 秘密鍵・公開鍵の作成
$ ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa
$ cat ~/.ssh/id_rsa.pub
##表示された文字列をA. VPN サーバー側の~/.ssh/authrized_keysに追記する
下記でつながるか確認
$ ssh -i ~/.ssh/id_rsa ubuntu@203.0.113.50
- このレポジトリのssh-tunnelを~/ssh-tunnelにコピーしてVPN内に公開したいサービスの設定をして起動
$ git clone https://github.com/syagawa/vpn-wireguard-settings-with-ssh-tunnel.git
$ cd vpn-wireguard-settings-with-ssh-tunnel
# ホームネットワーク内のVPN内に公開したいサービスのIPとポートを設定する
$ vim ./ssh-tunnel/compose.ssh.yml
# 例 jellyfinが下記IP:portの場合
## jellyfin 192.168.1.20:8097
PORT_FORWARD_LIST: "8097:192.168.1.20:8097"
# 下記も編集 VPNサーバーのユーザー名と外部IPを設定
SSH_USER: "ubuntu"
SSH_SERVER: "203.0.113.50"
# dockerの起動 VPNサーバーとホームネットワークにSSHトンネルが作られる
$ docker compose -f ~/ssh-tunnel/compose.ssh.yml up -d
C. VPN クライアントの追加と設定(初回はホームネットワーク内である必要アリ)
ホームネットワーク内にあるLinuxマシン(Ubuntu Desktopを想定)で行う
- ホームネットワーク内で192.168.1.10:51821(Tunnel Server)にブラウザでアクセスするとwireguard-easyの設定画面になる
- Newボタンでクライアント用の設定を作成
- ダウンロードボタンで設定をダウンロードする(<設定した名前>.confと言うファイルになる)
- ダウンロードした<設定した名前>.confをホーム(~)にコピー
- wireguardのインストールと起動
$ sudo apt install wireguard
$ cd ~
$ cp ./<設定した名前>.conf /etc/wireguard/wg0.conf
# IPv4 over IPv6環境の場合
$ sudo vim /etc/wireguard/wg0.conf
# [Interface]内に下記を追記して保存
MTU = 1280
$ wg-quick up wg0
-
ブラウザで10.42.42.1:8097でjellyfinが表示されるのを確認する、表示されればホームネットワーク外の外出先でも
wg-quick up wg0をすれば、10.42.42.1:8097でjellyfinにアクセスできる -
Androidの場合は
WireGuardをPlayStoreからインストールして、WireGuardのアプリ画面からwireguard-easyの設定画面上のQRコードの読み込みですぐ設定が可能
VPNサーバー側のwireguard-easy用のcompose.ymlは下記を参照しました。
- https://qiita.com/dxa/items/0fc38c368b1847918035
- https://github.com/wg-easy/wg-easy/blob/badae8b8e4523ff644da80809c2a4a6cc065f320/docker-compose.yml
更新履歴
- 2025/11/25 VPSのネットワーク側のUDP:51820を許可についてを追加
- 2026/8/15 説明文の修正