はじめに
もともと NURO 光 2G (デュアルスタック) を使っていて、固定 IP があったのでポート開放して自宅 Minecraft サーバーを友人に公開していたのですが、
新しく NURO 光 10G に乗り換えたところ、MAP-E 方式になってしまいポート開放ができなくなってしまいました。
MAP-E 方式とは、IPv4 アドレスを複数のユーザーで共有する技術で、自由に使えるポートが制限されていたり、グローバル IP が固定できなかったりするものです。
乗り換えるときに仕様が変わることを知らずかなり困ってしまったのですが、VPS を踏み台にし、VPN トンネルを掘ることでこの制限を回避できる、という記事を見つけたのでやってみました。
この記事では、その構築手順を紹介する。
目次
環境
-
VPS (踏み台)
- Service: Oracle Cloud Infrastructure (OCI) Always Free
- OS: Ubuntu 22.04 LTS Minimal
- Role: WireGuard Server, Port Forwarding
- Global IP: あり
--
-
自宅サーバー
- OS: Ubuntu 24.04 LTS (Proxmox LXC Container)
- Role: WireGuard Client, Minecraft Server
- Network: NURO 光 (MAP-E), ポート開放不可
構成イメージ
外部からのアクセスを VPS で受け取り、WireGuard VPN 経由で自宅の Minecraft サーバーへ転送する。
ポイント:
- Minecraft クライアントは VPS のグローバル IP にアクセス
- VPS が iptables (DNAT) でパケットを自宅サーバーへ転送
- 自宅サーバーは WireGuard VPN で VPS と常時接続
1. VPS 側の設定 (WireGuard Host)
まずは踏み台となる VPS 側の設定を行う。
※ 前提として、Web UI 上で編集できる VCN などのポート開放はすでに設定されているものとする。
WireGuard のインストール
# システムアップデート
sudo apt update && sudo apt upgrade -y
# WireGuard インストール
sudo apt install wireguard -y
IP フォワーディングの有効化
VPN を通してパケットを転送するために必要。
# 念のためバックアップ
sudo cp -ai /etc/sysctl.conf{,.default}
# 設定を追記
echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.conf
# 反映
sudo sysctl -p
鍵の生成
WireGuard は公開鍵認証方式を使用する。サーバー側とクライアント側のペアを生成する。
# ディレクトリ作成・移動
sudo mkdir -p /etc/wireguard
cd /etc/wireguard
# 鍵ファイルのパーミッション用に umask 設定
sudo umask 077
# サーバー用鍵生成
wg genkey | sudo tee server_private.key | wg pubkey | sudo tee server_public.key
# クライアント用鍵生成
wg genkey | sudo tee client_private.key | wg pubkey | sudo tee client_public.key
# 確認
cat server_private.key server_public.key client_private.key client_public.key
ここで表示された鍵 (特に Private Key) は他人に漏れないように注意!
設定ファイル (wg0.conf) の作成
/etc/wireguard/wg0.conf を作成する。
[Interface]
Address = 10.100.0.1/24
ListenPort = 51820
PrivateKey = <server_private.keyの内容>
[Peer]
# 自宅クライアント
PublicKey = <client_public.keyの内容>
AllowedIPs = 10.100.0.2/32
iptables の設定 (重要)
ここが今回の肝です。以下の設定を行います。
- ポート開放: WireGuard (51820/udp) と Minecraft (25565/tcp) を許可
- ポートフォワーディング (DNAT): VPS に来たパケットを自宅サーバー (10.100.0.2) へ転送
- マスカレード (SNAT): 戻りのパケットが正しく VPS を経由するように設定
- MSS Clamping: VPN や MAP-E 環境でのパケット詰まりを防ぐため、TCP MSS を調整
- 攻撃対策: 不正なパケットをドロップ
インターフェース名 (enp0s6) は環境によって異なる (eth0 など) ので、ip a 等で確認しておくこと!
# 念のためバックアップ
sudo cp -ai /etc/iptables/rules.v4{,.default}
# ルールファイルを直接作成して適用する
cat << '_EOF_' | sudo tee /etc/iptables/rules.v4
################################################################################
# filter Table
################################################################################
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
:InstanceServices - [0:0]
# === 基本設定 ===
-A INPUT -i lo -j ACCEPT
# 攻撃対策 - 不正なパケットをドロップ
-A INPUT -p tcp --tcp-flags ALL NONE -j DROP
-A INPUT -p tcp ! --syn -m state --state NEW -j DROP
-A INPUT -p tcp --tcp-flags ALL ALL -j DROP
# 確立済み接続を許可
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
# ICMP (レート制限付き)
-A INPUT -p icmp --icmp-type echo-request -m limit --limit 1/s -j ACCEPT
-A INPUT -p icmp -j ACCEPT
# SSH
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
# NTP (OCI推奨)
-A INPUT -p udp --sport 123 -j ACCEPT
# === WireGuard VPN用 ===
-A INPUT -p udp -m udp --dport 51820 -j ACCEPT
# === Minecraft 用 ===
-A INPUT -p tcp -m tcp --dport 25565 -j ACCEPT
# OCI InstanceServices (メタデータサービス用)
-A OUTPUT -d 169.254.0.0/16 -j InstanceServices
# REJECT
-A INPUT -j REJECT --reject-with icmp-host-prohibited
# === FORWARD Chain ===
-A FORWARD -i wg0 -j ACCEPT
-A FORWARD -o wg0 -j ACCEPT
-A FORWARD -i enp0s6 -o wg0 -m state --state RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -i wg0 -o enp0s6 -j ACCEPT
-A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -j REJECT --reject-with icmp-host-prohibited
# === InstanceServices Chain (OCI固有 - 変更しないこと) ===
-A InstanceServices -d 169.254.0.2/32 -p tcp -m owner --uid-owner 0 -m tcp --dport 3260 -j ACCEPT
-A InstanceServices -d 169.254.2.0/24 -p tcp -m owner --uid-owner 0 -m tcp --dport 3260 -j ACCEPT
-A InstanceServices -d 169.254.4.0/24 -p tcp -m owner --uid-owner 0 -m tcp --dport 3260 -j ACCEPT
-A InstanceServices -d 169.254.5.0/24 -p tcp -m owner --uid-owner 0 -m tcp --dport 3260 -j ACCEPT
-A InstanceServices -d 169.254.0.2/32 -p tcp -m tcp --dport 80 -j ACCEPT
-A InstanceServices -d 169.254.169.254/32 -p udp -m udp --dport 53 -j ACCEPT
-A InstanceServices -d 169.254.169.254/32 -p tcp -m tcp --dport 53 -j ACCEPT
-A InstanceServices -d 169.254.0.3/32 -p tcp -m owner --uid-owner 0 -m tcp --dport 80 -j ACCEPT
-A InstanceServices -d 169.254.0.4/32 -p tcp -m tcp --dport 80 -j ACCEPT
-A InstanceServices -d 169.254.169.254/32 -p tcp -m tcp --dport 80 -j ACCEPT
-A InstanceServices -d 169.254.169.254/32 -p udp -m udp --dport 67 -j ACCEPT
-A InstanceServices -d 169.254.169.254/32 -p udp -m udp --dport 69 -j ACCEPT
-A InstanceServices -d 169.254.169.254/32 -p udp --dport 123 -j ACCEPT
-A InstanceServices -d 169.254.0.0/16 -p tcp -m tcp -j REJECT --reject-with tcp-reset
-A InstanceServices -d 169.254.0.0/16 -p udp -m udp -j REJECT --reject-with icmp-port-unreachable
COMMIT
################################################################################
# mangle Table - TCP MSS Clamping for WireGuard MTU
################################################################################
*mangle
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
# MSS Clamping (WireGuard MTU対応)
-A POSTROUTING -o wg0 -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1360
-A PREROUTING -i wg0 -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1360
-A FORWARD -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
-A FORWARD -i enp0s6 -o wg0 -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1360
-A FORWARD -i wg0 -o enp0s6 -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1360
COMMIT
################################################################################
# nat Table - Port Forwarding
################################################################################
*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
# ポートフォワーディング (Minecraft TCP 25565 -> 10.100.0.2:25565)
-A PREROUTING -i enp0s6 -p tcp --dport 25565 -j DNAT --to-destination 10.100.0.2:25565
# MASQUERADE
-A POSTROUTING -o enp0s6 -j MASQUERADE
COMMIT
_EOF_
# 設定を適用
sudo iptables-restore < /etc/iptables/rules.v4
WireGuard 起動
# 起動
sudo wg-quick up wg0
# 自動起動設定
sudo systemctl enable wg-quick@wg0
2. 自宅サーバー側の設定 (WireGuard Client)
次に、自宅の Minecraft サーバー側の設定をしていく。
WireGuard のインストール
sudo apt update && sudo apt install wireguard iproute2 iptables -y
設定ファイル (wg0.conf) の作成
/etc/wireguard/wg0.conf を作成する。
PersistentKeepalive の設定が重要。これがないと、NAT 配下のクライアントからの接続が一定時間で切れてしまい、外部からアクセスできなくなる。
[Interface]
Address = 10.100.0.2/24
PrivateKey = <client_private.keyの内容>
# MSS Clamping の念押し設定 (より安全に 1300 に設定)
PostUp = iptables -t mangle -A POSTROUTING -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1300
PostUp = iptables -t mangle -A PREROUTING -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1300
PostDown = iptables -t mangle -D POSTROUTING -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1300
PostDown = iptables -t mangle -D PREROUTING -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 1300
[Peer]
PublicKey = <server_public.keyの内容>
Endpoint = <OCI VMのグローバルIP>:51820
AllowedIPs = 0.0.0.0/0
# NAT越えのためのキープアライブ (秒)
PersistentKeepalive = 25
WireGuard を起動する
# 起動
sudo wg-quick up wg0
# 自動起動設定
sudo systemctl enable wg-quick@wg0
# ステータス確認
sudo wg show
動作確認
自宅サーバーから VPS への Ping が通るか確認する。
ping 10.100.0.1
問題なければ、Minecraft クライアントから VPSのグローバルIP:25565 で接続してみる。
無事に入ることができれば成功!
最後に
ここまで目を通してくださってありがとうございます。
VPS を経由することで MAP-E 方式のようなポート開放が難しい環境でも Minecraft サーバーを公開することができました!
iptables の設定、特に MSS Clamping はハマりポイントだったので、接続できない、、接続はできるけど不安定、、という場合はこの値を調整してみると良いかもしれません。(値は割と適当なので上級者的におかしかったらすみません)
今回回線を変える際に調べるのを怠っていたせいでとても面倒なことになってしまったので、どんなことでも影響範囲を調べてから行動することが大切だと感じました。
もし同じように困っている方はこのように別のやり方もあるので、あきらめずに頑張りましょう!
それでは良き Minecraft ライフを!
参考文献