ポート開放できない自宅回線で、OCI + WireGuard + Proxmoxを使ってMinecraft統合版サーバーを公開した話
マンションの無料インターネット回線を使っていると、自分でルーターを管理できず、ポート開放ができないことがあります。
自分の環境もまさにこれでした。
そこで今回は、
自宅のProxmox上でMinecraft Bedrock Serverを動かし、Oracle Cloud Infrastructure(OCI)のVMをインターネット側の入口として使う
構成を作りました。
最終的な構成はこんな感じです。
Minecraftクライアント
│
│ UDP 51821
▼
OCI VM(グローバルIPv4あり)
│
│ WireGuard
▼
自宅 Proxmox
│
▼
Ubuntu VM
│ UDP 19132
▼
Minecraft Bedrock Dedicated ServerOCIではMinecraft本体を動かさず、通信の中継だけを担当させています。
技術スタック
自宅側は、
Proxmox VE
Ubuntu VM
Minecraft Bedrock Dedicated Server
WireGuard
OCI側は、
Ubuntu
WireGuard
iptables
iptables-persistent
です。
OCIのVMはMinecraft本体を動かさないので、かなり小さいインスタンスでも足ります。
今回はA1 Flexの空きがなかったので、VM.Standard.E2.1.Micro を使いました。
1. Proxmox上にUbuntu VMを作る
まずProxmox上にUbuntu VMを作成しました。VMから普通にインターネットへ出られることを確認しました。
ping -c 3 1.1.1.1Minecraft ServerとWireGuardはProxmox本体ではなく、このUbuntu VMの中で動かします。
2. OCI VMの作成
OCI VMを作る OCI側にもUbuntu VMを1台作成します。主に確認したポイントは以下です。パブリックIPv4が割り当てられている Internet Gatewayが存在する Route Tableが正しく設定されている Security Listが正しいSubnetに適用されている SSH鍵を使って接続します。
ssh -i ~/.ssh/oci ubuntu@<OCI_PUBLIC_IP>3. WireGuardをインストール
OCI側と自宅Ubuntu VM側の両方にWireGuardを入れます。
sudo apt update && sudo apt install -y wireguard4. WireGuard鍵を作成
OCI側では次のように鍵を作成しました。
sudo sh -c 'umask 077; mkdir -p /etc/wireguard; wg genkey > /etc/wireguard/oci.key; wg pubkey < /etc/wireguard/oci.key > /etc/wireguard/oci.pub'自宅Ubuntu VM側では、
sudo sh -c 'umask 077; mkdir -p /etc/wireguard; wg genkey > /etc/wireguard/home.key; wg pubkey < /etc/wireguard/home.key > /etc/wireguard/home.pub' としました。
WireGuardでは、 PrivateKey = 自分の秘密鍵 PublicKey = 相手の公開鍵 という関係になります。
5. WireGuard用のIPアドレスを決める
今回はWireGuard内で以下のIPアドレスを使いました。
OCI : 10.100.0.1 自宅Ubuntu: 10.100.0.2
OCI側の /etc/wireguard/wg0.conf はこのような構成です。
[Interface] Address = 10.100.0.1/24
ListenPort = 51820
PrivateKey = <OCI_PRIVATE_KEY>
[Peer] PublicKey = <HOME_PUBLIC_KEY>
AllowedIPs = 10.100.0.2/32 自宅Ubuntu VM側は、
[Interface] Address = 10.100.0.2/24
PrivateKey = <HOME_PRIVATE_KEY>
[Peer] PublicKey = <OCI_PUBLIC_KEY>
Endpoint = <OCI_PUBLIC_IP>:51820
AllowedIPs = 10.100.0.1/32
PersistentKeepalive = 25という構成にしました。
6. OCIでUDP 51820を許可する
OCIのSecurity ListでWireGuard用のUDP 51820を許可します。
Source CIDR : 0.0.0.0/0
Protocol : UDP Dest Port : 51820
ここで注意したいのが、 ルールを追加したSecurity Listが実際にVMのSubnetへ適用されているか という点です。別のSecurity Listを編集していても通信は通りません。
7. WireGuardが繋がらない
WireGuardが繋がらない、ここでかなりハマりました。
OCI側で、
sudo tcpdump -ni any udp port 51820を実行すると、自宅から送信されたUDPパケット自体は確認できました。
しかし、
sudo wg を実行しても、 latest handshake が表示されません。
つまり、
インターネット
↓
OCI
まではパケットが届いているのに、
OCI
↓
WireGuard
へ届いていない状態でした。8. 原因はOCI Ubuntu側のiptables
OCI側で、
sudo iptables -L INPUT -n -vを確認すると、通信をREJECTするルールが存在していました。
そこでUDP 51820をINPUTチェーンの先頭で許可しました。
sudo iptables -I INPUT 1 -p udp --dport 51820 -j ACCEPTその後、sudo wg を確認すると、
latest handshake: ... が表示されるようになりました。
さらに自宅Ubuntu側から、
ping 10.100.0.1も通るようになりました。
これでWireGuardトンネルは完成です。
9. WireGuardを自動起動する
OCIと自宅Ubuntuの両方で、
sudo systemctl enable wg-quick@wg0を実行して、再起動後にもWireGuardが立ち上がるようにしました。
10. iptablesの設定を保存する
iptablesの設定は、そのままだと再起動すると消える可能性があります。
そこで、
sudo apt install -y iptables-persistentをインストールしました。
設定変更後は、
sudo netfilter-persistent saveを実行して保存します。
11. Minecraft Bedrock Dedicated Server導入
Minecraft Bedrock Dedicated Serverは、自宅のUbuntu VM内で動かします。
mkdir -p ~/bedrock-serverでディレクトリを作り、公式のBedrock Dedicated Serverを展開します。 展開したディレクトリへ移動して、
chmod +x bedrock_server
LD_LIBRARY_PATH=. ./bedrock_serverで起動します。 正常に起動すると、 IPv4 supported, port: 19132 Server started. などと表示されます。
待ち受け状態は、
sudo ss -lunp | grep 19132で確認できます。
12. OCIでIP Forwardingを有効化する
OCIへ来たMinecraft通信をWireGuardへ転送するため、IPv4 Forwardingを有効にします。
sudo sysctl -w net.ipv4.ip_forward=1再起動後にも有効になるよう、
echo 'net.ipv4.ip_forward=1' | sudo tee /etc/sysctl.d/99-minecraft-relay.confも設定しました。
13. Minecraft用の外部ポート
Minecraft Bedrockの標準ポートは、UDP 19132 です。ただし今回の環境では、なぜか外部からOCIのUDP 19132へ通信がうまく到達しませんでした。 そこで外部側だけ、UDP 51821 を使用することにしました。構成としては、
インターネット
↓
OCI:51821
↓
自宅Ubuntu:19132としました。
OCIのSecurity ListでもUDP 51821を許可します。
14. OCIでDNATする
OCIへ来たUDP 51821を、自宅Ubuntu VMの19132へ変換します。
sudo iptables -t nat -A PREROUTING \
-i ens3 \
-p udp \
--dport 51821 \
-j DNAT \
--to-destination 10.100.0.2:19132さらにWireGuard側へ送る通信をNATします。
sudo iptables -t nat -A POSTROUTING \
-o wg0 \
-p udp \
-d 10.100.0.2 \
--dport 19132 \
-j MASQUERADE15.iptables
今度はFORWARDチェーンで詰まったOCIの外部インターフェースではUDP 51821の通信が確認できました。DNATのカウンタも増えていました。
sudo iptables -t nat -L PREROUTING -n -v --line-numbersしかし、
sudo tcpdump -ni wg0 udp port 19132では通信が確認できませんでした。
原因を調べるため、
sudo iptables -L FORWARD -n -v --line-numbersすると、Minecraft用のACCEPTルールよりも前にREJECTルールがありました。
iptablesは上から順番にルールを処理するため、
REJECT
↓
ACCEPTという順番では、後ろのACCEPTルールまで到達しません。そこでMinecraft用のルールを先頭に追加しました。
sudo iptables -I FORWARD 1 \
-i ens3 \
-o wg0 \
-p udp \
-d 10.100.0.2 \
--dport 19132 \
-j ACCEPT返信側の通信も許可します。
sudo iptables -I FORWARD 1 \
-i wg0 \
-o ens3 \
-m conntrack \
--ctstate ESTABLISHED,RELATED \
-j ACCEPTこれで、
Minecraft
↓
OCI:51821
↓
DNAT
↓
WireGuard
↓
Ubuntu VM:19132
↓
Minecraft Bedrock Server
↓
WireGuard
↓
OCI
↓
Minecraftという通信が完成しました。
最後に、
sudo netfilter-persistent saveでiptables設定を保存しました。
16. Minecraftから接続する
Minecraft統合版からサーバーを追加します。
サーバーアドレス : <OCI_PUBLIC_IP>
ポート : 51821これで、自宅ルーターのポート開放を行わずにMinecraftサーバーへ接続できました。
17. Allow Listを有効にする
今回は2人だけで遊ぶサーバーなので、Allow Listを有効にしています。 server.properties で、
allow-list=trueとします。
Bedrock Serverのコンソールで、
allowlist add プレイヤー名1
allowlist add プレイヤー名2を実行。
確認する場合は、
allowlist listを使います。
これで登録したプレイヤーだけが参加できます。
18. Minecraft Serverをsystemdで自動起動する
毎回手動でBedrock Serverを起動するのは面倒なので、systemdサービスにしました。例として、/etc/systemd/system/bedrock.service を作成します。 内容は以下のようにしました。
[Unit]
Description=Minecraft Bedrock Server
After=network-online.target
[Service]
User=<USER>
WorkingDirectory=/home/<USER>/bedrock-server/bedrock-server-1.26.44.3
Environment=LD_LIBRARY_PATH=.
ExecStart=/home/<USER>/bedrock-server/bedrock-server-1.26.44.3/bedrock_server
Restart=on-failure
RestartSec=5
KillSignal=SIGINT
[Install]
WantedBy=multi-user.target設定を読み込みます。
sudo systemctl daemon-reload自動起動を有効にして、そのまま起動します。
sudo systemctl enable --now bedrock状態確認は、
sudo systemctl status bedrock --no-pagerです。
Active: active (running)
になっていれば起動しています。
19. Ubuntu VMを再起動して確認
最後にUbuntu VMを再起動しました。sudo reboot 再起動後、sudo wg でWireGuardを確認。 さらに、sudo systemctl status bedrock --no-pager でBedrock Serverを確認しました。 WireGuardとBedrock Serverの両方が自動起動していました。実際にMinecraftから接続してみたところ、Ubuntu VMを再起動したあとでも問題なくサーバーへ入ることができました。
今回一番ハマったポイント
今回特に苦戦したのは、OCIとUbuntu側のファイアウォールです。OCIには、Security List があります。 しかし、それとは別にUbuntu側にも、iptables があります。 そのため、OCIのSecurity Listでポートを開けただけでは必ずしも通信できません。
sudo tcpdump -ni any udp port 51820
sudo tcpdump -ni wg0 udp port 19132を使えば、パケットがどこまで届いているのかを確認できます。
また、
sudo iptables -L INPUT -n -v
sudo iptables -L FORWARD -n -v --line-numbersを見ることで、iptablesに通信を止められていないか確認できます。 そしてiptablesでは、 ルールの内容だけではなく順番も重要 ということも今回かなり勉強になりました。 許可ルールが存在していても、その前にREJECTルールがあれば通信はそこで止まります。
最終的な構成
Internet
│
│ UDP 51821
▼
OCI Public IPv4
│
│ DNAT
▼
OCI wg0
10.100.0.1
│
│ WireGuard
▼
Ubuntu VM wg0
10.100.0.2
│
│ UDP 19132
▼
Minecraft Bedrock Dedicated Server
この構成によって、 自宅側でポート開放できない環境でもMinecraft統合版サーバーを外部公開することができました。 Minecraft本体は自宅PCで動かし、OCIは通信の中継だけを担当します。 そのため、OCI側に高性能なVMを用意する必要がないのもメリットです。
今後やりたいこと
OCI自体を再起動しても自動復旧するか確認 昔遊んでいたMinecraftワールドをサーバーへ移行 ワールドの自動バックアップ Minecraft Serverの自動アップデート サーバー監視 などもやってみたいと思います。 ポート開放できない環境でMinecraftサーバーを公開したい人の参考になれば幸いです。