[2024/04/15 更新]
パルワールドサーバーのRCONの使用について、パルワールド公式のテックガイドに「LAN内での使用に留めておくことを推奨します」の文言が追加されたため、RCONのトラフィックを許可する設定を削除。
適当なタイトルが思いつかなかった…
内容としては、クラウド上のVPSにフロントエンドサーバーを建てて、プロキシーのようにフロントエンドサーバーを経由してクライアントと通信させるということ。クライアントから見えるのはフロントエンドサーバーのIPアドレスってわけ。
結構上級者向けの内容。WireGuard、ファイアーウォールやNATの知識があることが前提。
大変参考にした記事: Internet Watch / 清水理史の「イニシャルB」:VPSを使って「マインクラフト」などの自宅ゲームサーバーを安全に公開する方法
ここからいくつかアレンジをしている。
- 自宅内のゲームサーバー上に直接WireGuardを置くのではなく、WireGuardで通信するゲートウェイサーバーを、ゲームサーバーとは別に独立して用意する
→自宅内に複数台のサーバーがあったり、他に管理したいマシンがあるケースに対応できる - ファイアーウォールをufwからnftablesに変更
- 普段Fedoraを利用していて、Fedoraで利用する方法も載せたかったので、今回は自宅のVPNゲートウェイをFedoraで構築。コマンドとファイルの配置場所が違うぐらいだけど…
- シンプルにするため、ここでは冗長化は扱わない
参考にした記事ではゲームサーバーで利用するケースが想定されているが、ポート番号やプロトコルの設定を変更すれば、様々なアプリケーションに対応可能。話題のパルワールドのサーバーでも、Webサーバーでも利用可能。
構成図
グローバルIPアドレスは例示用のものを使用している。
v6プラス 固定IP1の回線環境でテストしている。WireGuardの接続形態は参考元の記事と同じなので、恐らくMAP-E、DS-Liteでもいけるはず。ただし、MTUの調整は必要。
今回はパルワールドのサーバーを公開する場合の設定をしてみる。
パルワールドのサーバーで必要となるデフォルトのポートは下記の通り。
プロトコル | ポート番号 | 用途 |
UDP | 8211 | ゲームポート |
UDP | 27015 | クエリーポート |
クエリーポートは開けなくても動いているけど一応載せておく。
また、WireGuardの待ち受けポートとして、今回はUDPの61267を使用する。
フロントエンドサーバーの設定
Ubuntu 22.04.4 LTSを使用。
WireGuardをインストール。nftablesはインストールされていた
sudo apt install wireguard
IPフォワードを有効化する
sudoedit /etc/sysctl.d/10-net-forward.conf
/etc/sysctl.d/10-net-forward.confの内容:
net.ipv4.ip_forward = 1
再起動
sudo reboot
再起動後、/etc/nftables.confを配置する。
/etc/nftables.confの内容:
flush ruleset
table inet firewall {
chain inbound_ipv4 {
# パルワールドのサーバーブラウザー上でPing値が表示されるようになる。お好みで
icmp type echo-request limit rate 5/second accept
}
chain inbound_ipv6 {
icmpv6 type { nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert } accept
}
chain inbound {
type filter hook input priority filter; policy drop;
ct state vmap { invalid : drop, established : accept, related : accept }
iifname "lo" accept
meta protocol vmap { ip : jump inbound_ipv4, ip6 : jump inbound_ipv6 }
# ポートを追加・変更する場合は下の2行を変更
iifname "eth0" tcp dport 22 accept # SSH
iifname "eth0" udp dport { 8211, 27015, 61267 } accept # Palworld / WireGuard
}
chain forward {
type filter hook forward priority filter; policy drop;
iifname "eth0" oifname "wg0" accept
iifname "wg0" oifname "eth0" accept
}
}
table inet nat {
chain postrouting {
type nat hook postrouting priority srcnat; policy accept;
ip saddr 192.168.100.0/24 oifname "eth0" masquerade
}
chain prerouting {
type nat hook prerouting priority dstnat; policy accept;
# ポートを追加・変更する場合は下の行を変更
ip daddr 203.0.113.10 udp dport { 8211, 27015 } iifname "eth0" dnat ip to 192.168.100.100
}
}
イーサーネットのインターフェイス名はeth0。必要に応じて置き換える。
簡単に説明。
table inet firewall(ファイアーウォール用テーブル)
chain inbound_ipv4
パルワールドのサーバーブラウザー上のPing値の計測は、サーバーに入ったあとに表示されるPing(RTT)値の計測とは異なり、ICMPが使用されている模様。同じUnreal Engineを使用しているLongvinterでも同じ挙動だったので、UE共通の仕様なのかも?
icmp type echo-requestの行をコメントアウトすると、ICMPがdropされるのでPing値は非表示になる。
chain inbound
ポートを追加・変更する場合はdportの括弧内の番号を変更する。TCPとUDPで行が分かれる。
TCP: SSHを許可。
UDP: パルワールド(ゲームポート)、パルワールド(クエリーポート)、WireGuardの通信を許可。
chain forward
eth0~wg0間の転送を相互に許可する。
table inet nat(NAT用テーブル)
chain postrouting
自宅のLANセグメントから出てきた通信のソースアドレスを、eth0のアドレスでマスカレード(ソースNAT)する。snatでも可能。
chain postrouting
フロントエンドサーバーへやってきて、自宅内のサーバーへ通す通信の行き先アドレスを、自宅内のサーバーのアドレスにデスティネーションNATする。
ポートを追加・変更する場合はdportの括弧内の番号を変更する。こちらもTCPとUDPで行が分かれる。サーバーを複数台に増やしたい場合は末尾参照。
ufwの停止とnftablesの起動を行う。
sudo systemctl stop ufw
sudo systemctl disable ufw
sudo systemctl start nftables
sudo systemctl enable nftables
ルールが正常に読み込まれていることを確認
sudo nft list ruleset
/etc/wireguard/wg0.confを配置
[Interface]
Address = 192.168.10.1/30
ListenPort = 61267
PrivateKey = <フロントエンドサーバーの秘密鍵>
[Peer]
PublicKey = <VPNゲートウェイの公開鍵>
AllowedIPs = 192.168.10.2/32, 192.168.100.0/24
AllowedIPs についてはここでは対向のインターフェイスのアドレスと、LANのネットワークアドレスを指定する。
WireGuardを起動する
sudo systemctl start wg-quick@wg0
sudo systemctl enable wg-quick@wg0
VPNゲートウェイの設定
Fedora Server 39 ネットワークインストール版を使用。
WireGuardをインストール。こちらもnftablesはインストールされていた
sudo dnf install wireguard-tools
IPフォワードを有効化する
sudoedit /etc/sysctl.d/10-net-forward.conf
/etc/sysctl.d/10-net-forward.confの内容:
net.ipv4.ip_forward = 1
再起動
sudo reboot
再起動後、/etc/sysconfig/nftables.confを配置する。
/etc/sysconfig/nftables.confの内容:
flush ruleset
table inet firewall {
chain inbound_ipv4 {
icmp type echo-request limit rate 5/second accept
}
chain inbound_ipv6 {
icmpv6 type { nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert } accept
}
chain inbound {
type filter hook input priority filter; policy drop;
ct state vmap { invalid : drop, established : accept, related : accept }
iifname "lo" accept
meta protocol vmap { ip : jump inbound_ipv4, ip6 : jump inbound_ipv6 }
iifname "enp1s0" tcp dport 22 accept # SSH
}
chain forward {
type filter hook forward priority filter; policy drop;
iifname "enp1s0" oifname "wg0" accept
iifname "wg0" oifname "enp1s0" accept
}
}
イーサーネットのインターフェイス名はenp1s0。必要に応じて置き換える。
Fedoraのデフォルトのファイアウォール、firewalldを停止して、nftablesを起動
sudo systemctl stop firewalld
sudo systemctl disable firewalld
sudo systemctl start nftables
sudo systemctl enable nftables
ルールが正常に読み込まれていることを確認
sudo nft list ruleset
/etc/wireguard/wg0.confを配置
[Interface]
Address = 192.168.10.2/30
ListenPort = 61267
PrivateKey = <VPNゲートウェイの秘密鍵>
MTU = 1380
[Peer]
PublicKey = <フロントエンドサーバーの公開鍵>
AllowedIPs = 0.0.0.0/0
Endpoint = 203.0.113.10:61267
PersistentKeepalive = 25
v6プラスのIPv4のMTUは1460。
WireGuardのペイロードサイズが80なので、WireGuardのトンネルで設定すべきMTUは、1460 – 80 = 1380となる。IPv4のみ使う気であればペイロードサイズが60らしいので、1400でもいけるかも
MTUを設定せずに使ったところ、一部サイトで通信できないことがありハマった。
AllowedIPs = 0.0.0.0/0ですべての行き先のトラフィックをVPNを通して通信させる。
WireGuardを起動する
sudo systemctl start wg-quick@wg0
sudo systemctl enable wg-quick@wg0
※WireGuardが起動すると、自動的にnftablesにいくつかルールが追加される。
最後に、WireGuardの接続ができていることを双方で確認
sudo wg
自宅内のサーバーの設定
- デフォルトゲートウェイをVPNゲートウェイのIPアドレスに設定
これを行うことでLANを出るすべての通信はVPNゲートウェイへルーティングされる。 - MTUを1380に設定
サーバーを追加したい場合はどうする?
例えば、192.168.100.101というWebサーバーを追加したい場合は、フロントエンドサーバーのnftables.conf内の、inboundとpreroutingのチェーンを下記のようにする。
chain inbound {
type filter hook input priority filter; policy drop;
ct state vmap { invalid : drop, established : accept, related : accept }
iifname "lo" accept
meta protocol vmap { ip : jump inbound_ipv4, ip6 : jump inbound_ipv6 }
iifname "eth0" tcp dport { 22, 80, 443 } accept # 80, 443ポート追加
iifname "eth0" udp dport { 8211, 27015, 61267 } accept
}
chain prerouting {
type nat hook prerouting priority dstnat; policy accept;
ip daddr 203.0.113.10 udp dport { 8211, 27015 } iifname "eth0" dnat ip to 192.168.100.100
# Webサーバー用のdnatルール追加
ip daddr 203.0.113.10 tcp dport { 80, 443 } iifname "eth0" dnat ip to 192.168.100.101
}
最後のdnat ip toの部分の行き先のIPアドレスが変わるため、台数分、行を追加することになる。
最近のコメント