Maple

Maple

探索文明6の最適なネットワーク技術——WireGuard + udp2raw

設計思路#

文明 6(Civilization VI)このゲームのマルチプレイヤーオンラインは常に批判されています。

公式の「インターネット」オンラインモードは間違いなく中国のプレイヤーにとって不親切であり、不安定な国際リンクとファイアウォールの時折の干渉により、非常に高い遅延と頻繁な切断が発生します。文明のオンラインは UDP プロトコルに基づいているため、多くのプレイヤーは Zerotier/easyN2N などのツールを使用して仮想 LAN を構築し、直接 p2p で打開し、WinIPBroadcastを使用して文明の255.255.255.255の部屋検索ブロードキャストを仮想ネットワークカードに転送することを考えました。または、より高度なツールであるinjciv6を使用します。これは、文明の送信、受信などの操作をフックし、元のブロードキャストを直接ユニキャストに変更します(これにより、ルーティングテーブルに従って仮想ネットワークカードに正しくルーティングできます)。しかし、実際のプレイ中に新たな問題が浮上しました:プロバイダーが UDP トラフィックに対して非常に不親切な QoS ポリシーを採用しており、しばらくするとパケットロスが発生し、重要なデータパケットが失われると、文明はプレイヤーを一時的に部屋から追い出して再読み込みし、「プレイヤーのデータが同期していません」と表示されます。通常、再読み込みには約 30 秒かかり、ゲームの進行に非常に影響を与えます。(私たち 6 人はほぼ毎ターン少なくとも 1 人が切断され、時折全員が切断されます)

これに対処するために、UDP パケットをいくつかの巧妙な手段で TCP パケットに偽装し、プロバイダーの信頼を得て、パケットロスの発生頻度を減らすことができます。すべての人が Linux マシンで文明をプレイする場合、性能の良いphantunを選択するのが良いですが、これはあまり現実的ではないため、マルチプラットフォームをサポートするudp2rawを選択します。

udp2raw を各プレイヤーのネットワークツールの出口に配置し、各ゲストプレイヤーがホストプレイヤーに接続できるようにすると、p2p ネットワークを構築するのはあまり現実的ではありません。ノード間のデータが双方向で到達可能であることを保証するために、スーパーノードを中継する仮想 LAN が必要です。したがって、WireGuard(UDP ベースの通信トンネルツール)をネットワーク構築のソリューションとして採用し、WireGuard サーバーと udp2raw(サーバーモード)を公衆インターネット上のサーバーに展開し、WireGuard クライアントと udp2raw(クライアントモード)を各プレイヤーの個人コンピュータに展開することで、私たちのニーズを満たすことができます!

設計のトポロジー図は大体以下のようになります。udp2raw は WireGuard の外側にあります:

network

サーバーのデプロイ方法#

前提条件:パブリック IP アドレスを持っていること。システムは Debian 11 ディストリビューションを例とします。

ソフトウェアのインストール#

sudo apt update
sudo apt install wireguard

# GitHubからudp2rawリリースをwgetし、/usr/local/bin/にインストールし、PATHに含めることを確認
# テスト
udp2raw --help

システムのポート転送を有効にする#

/etc/sysctl.confで以下の内容をコメント解除 / 追加します:

net.ipv4.ip_forward=1
net.ipv6.conf.all.forwarding=1

以下のコマンドを実行して設定を有効にします:

sudo sysctl -p

キーペアの生成#

cd /etc/wireguard

# ディレクトリ内のファイルのデフォルト権限を変更、デフォルト600
umask 077

wg genkey | tee server.key | wg pubkey > server.key.pub

これにより、現在のディレクトリにサーバーの秘密鍵server.keyファイルと公開鍵server.key.pubファイルが作成されます。

次に、各クライアントのキーペアを 1 つずつ生成します:

# "10"の数字をnに変更し、(n-1)個のキーペアを生成、番号は2から始まります
seq 2 10 | xargs -I{} sh -c 'wg genkey | tee client{}.key | wg pubkey > client{}.key.pub'

WireGuard 設定ファイルの作成#

sudo su

echo "
[Interface]
PrivateKey = $(cat server.key)
Address = 10.8.0.1/24
DNS = 8.8.8.8
MTU = 1280
ListenPort = 4321

PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o enp1s0 -j MASQUERADE;
PostUp = rm -f /var/log/udp2raw.log
PostUp = nohup udp2raw -s -l 0.0.0.0:54321 -r 127.0.0.1:4321 -a -k 'testpasswd' --raw-mode faketcp &> /var/log/udp2raw.log &
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -D FORWARD -o wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o enp1s0 -j MASQUERADE
PostDown = killall udp2raw || true
" > wg0.conf

# 各クライアントの公開鍵ファイルをループして対応する[Peer]エントリを追加
for client_key in client*.key.pub; do
    public_key=$(cat "$client_key")
    peer_number=$(echo "$client_key" | grep -o '[0-9]\+')
    # ピア番号に基づいてAllowedIPsを計算(client1は含めないこと)
    allowed_ip="10.8.0.${peer_number}/32"
    echo "[Peer]
PublicKey = $public_key
AllowedIPs = $allowed_ip
" >> wg0.conf
done

WireGuard を起動する際に udp2raw を静かに起動し、そのログを/var/log/udp2raw.logに出力することに注意してください。

サービスを起動し、ファイアウォールを設定#

sudo systemctl enable wg-quick@wg0 --now
sudo ufw allow 54321/udp

クライアントの設定方法#

まず、サーバーで生成されたクライアントのキーペアを安全な手段で送信します。

WireGuard のインストールと設定#

公式サイトからWireGuardをダウンロードします。ソフトウェアを正常にインストールした後、新しい設定を作成します。(client3 を例に、Address は自分で変更する必要があります)

[Interface]
PrivateKey = .....   # client3.key
Address = 10.8.0.3/24  # あなたのプライベートIP
DNS = 8.8.8.8
MTU = 1280

[Peer]
PublicKey = .....   # server.key.pub
Endpoint = 127.0.0.1:3333
AllowedIPs = 10.8.0.0/24
PersistentKeepalive = 25

udp2raw のインストールと設定#

まず、GitHub からudp2raw_multiplatformをダウンロードし、実行可能ファイルを環境変数 PATH のいずれかのディレクトリに配置します。

Windows システムの udp2raw faketcp は少し面倒で、手動でファイアウォールを設定する必要があります。Windows のネイティブファイアウォールが有効な状態であることを確認し、管理シェルでこのコマンドを実行します。-gは、サービスを起動せず、手動で実行する必要がある 2 つのコマンドを出力します。ファイアウォール設定を調整するために使用します。【注意:後でパブリック IP が変更された場合、このステップを再度実行する必要があります】

# 123.xxx.xx.xを実際のパブリックIPに変更
udp2raw -c -l 0.0.0.0:3333 -r 123.xxx.xx.x:54321 -k "testpasswd" --raw-mode faketcp -g

このステップでは、Windows の特定のネットワークモジュールが不足しているというメッセージが表示される場合があります。インターネットで検索してインストールしてください。成功した場合、最後の 2 つのコマンドを一つずつコピーして実行します。最後に、通常のシェルで-gを外したコマンドを実行し、このシェルを常に閉じないでください

# 123.xxx.xx.xを実際のパブリックIPに変更
udp2raw -c -l 0.0.0.0:3333 -r 123.xxx.xx.x:54321 -k "testpasswd" --raw-mode faketcp

使用方法#

udp2raw を前面で実行し、WireGuard トンネルを起動し、easyN2N などの UDP テストツールでクライアント間の接続性をテストします。

その後、文明 6 を起動し、各ゲストコンピュータでinjciv6をクライアントモードで注入し、アドレスにホストの仮想 LAN IP 10.8.0.2を入力すると、部屋を発見して参加できるようになります!

読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。