Rust サーバーの「Steam Auth Error: NetworkIdentityFailure」の原因と対処
Published on 2025/08/10Tags
問題の概要
Rust ゲームサーバーに、AWS 上のリバースプロキシサーバー (rapiz1/rathole) 経由でクライアントが接続しようとすると、以下のエラーにより接続が拒否されます:
Rejecting connection - Steam Auth Error: NetworkIdentityFailure
kicked: Steam Auth Failed
このエラーのため、クライアントはサーバーに参加できません。環境としては Linux 上の Docker (didstopia/rust-server イメージ使用) で Rust サーバーを稼働させ、AWS 側に公開 IP を持つリバースプロキシを立ててポート転送しています。必要なポート (例: 28015/UDP や Rust+アプリ用 28082 など) も AWS のファイアウォールで開放済みです。それでもなお上記エラーが発生します。
エラーの原因:Steam 認証におけるネットワーク識別の不一致
「Steam Auth Error: NetworkIdentityFailure」 は、Rust サーバーが Steam によるクライアント認証に失敗したことを示しています。特にこのエラーは、サーバーが認識しているネットワーク上の自分の IP アドレス情報と、クライアントが接続に使用している IP アドレスが一致しない場合に発生することが報告されています。
Rust サーバー (および Steam の認証システム) は、サーバーが Steam に対して登録・通信する際の送信元 IP と、クライアントが接続してくる宛先 IP が同一であることを前提にしています。しかし今回の構成では:
- サーバーから Steam への通信は自宅ネットワーク経由で行われるため、自宅側の外部 IP (または NAT 越しの IP) を使用している。 クライアントからの接続は AWS の公開 IP 経由でトンネリングされており、サーバーから見ると AWS 経由の別 IP から来た接続として扱われる。
- このようにサーバーのアウトバウンド通信経路上の IP と、インバウンド接続経路上の IP が食い違っているため、Steam 認証でネットワーク識別情報が一致せず拒否されてしまうと考えられます。実際、類似のケース (例えば Starlink 等でグローバル IP を持たない環境で VPN やプロキシを使った場合) でも同様のエラーが報告されており、「Rust/Steam の認証プロセス上、クライアントから要求される IP と実際のサーバーのローカル IP が一致していないと認証が通らない」と指摘されています。 また Rust の開発元 Facepunch のフォーラムやコミュニティでも、Rust サーバーが複数の IP をまたいで接続を受け付ける状況に弱い (server.ip 0.0.0.0 で全インターフェイスにバインドしても一部 IP でしか動作しない) ことや、Steam 認証方式に起因する問題であることが示唆されています。つまりネットワーク設定やポート転送の問題ではなく、Rust の Steam 認証実装上の制約によって発生している現象です。
対処方法
この問題を根本的に解決するには、「サーバーが認識・使用する IP」と「クライアントから見えるサーバーの IP」を一致させる必要があります。
具体的な対処策としては Rust サーバーから Outbound 通信も AWS 経由で行うようにネットワーク経路を次のように工夫してサーバーの外部 IP と通信経路の統一します。
- Rust サーバーから AWS への VPN トンネルを張り、Rust サーバーの Steam への通信をそのトンネル経由でおこないます。
- こうすることでクライアント受信 IP (AWS) とサーバー送信 IP (AWS 経由) が一致し、Steam 認証を通すことができます。
前提 (IP/IF 名)
- Docker ブリッジ:br-rustnet (172.30.0.1/24)
- Rust コンテナ固定 IP:172.30.0.10
- Rust サーバー wg0:10.10.0.2/24
- AWS wg0:10.10.0.1/24
- AWS 外向き IF:ens5
Rust サーバー LAN:192.168.210.0/24 (※実ネットに合わせて変更)
Docker 側 (Rust サーバー) 固定 IP & ブリッジ名固定
-
docker-compose.yml 内でカスタムネットワークを作り、固定 IP を割り当てます。
# docker-compose.yml version: "3.7" services: rust: ... networks: rustnet: ipv4_address: 172.30.0.10 # 固定 IP を指定 aws_reverse_proxy: ... networks: rustnet: # `networks:` セクションでサブネットを定義 networks: rustnet: name: rustnet driver: bridge driver_opts: com.docker.network.bridge.name: br-rustnet ipam: config: - subnet: 172.30.0.0/24
-
固定 IP の確認をおこないます。
docker compose up -d ip addr show br-rustnet # 172.30.0.1/24 が付いていればOK
WireGuard インストール & 鍵作成
-
AWS 側で WireGuard インストール & 鍵の作成をおこないます。
sudo apt update && sudo apt install -y wireguard iproute2 iptables umask 077 wg genkey | tee ~/wg0_server.key | wg pubkey > ~/wg0_server.pub
-
Rust サーバー側で WireGuard インストール & 鍵の作成をおこないます。
sudo apt update && sudo apt install -y wireguard iproute2 iptables umask 077 wg genkey | tee ~/wg0_client.key | wg pubkey > ~/wg0_client.pub
WireGuard 設定
-
AWS 側で wg0.conf の作成をおこないます。
SNAT 対象は 172.30.0.0/24 (Rust コンテナの実 IP 帯)
# /etc/wireguard/wg0.conf [Interface] Address = 10.10.0.1/24 ListenPort = 51820 PrivateKey = <AWS の秘密鍵> # 受け口&転送&SNAT PostUp = sysctl -w net.ipv4.ip_forward=1 PostUp = iptables -I FORWARD 1 -i wg0 -o ens5 -j ACCEPT PostUp = iptables -I FORWARD 1 -i ens5 -o wg0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT PostUp = iptables -t nat -A POSTROUTING -s 172.30.0.0/24 -o ens5 -j MASQUERADE PostDown = iptables -D FORWARD -i wg0 -o ens5 -j ACCEPT PostDown = iptables -D FORWARD -i ens5 -o wg0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT PostDown = iptables -t nat -D POSTROUTING -s 172.30.0.0/24 -o ens5 -j MASQUERADE [Peer] PublicKey = <Rust サーバーの公開鍵> AllowedIPs = 10.10.0.2/32, 172.30.0.0/24
<AWS の秘密鍵> は
cat ~/wg0_server.key
の中身を指定します。<Rust サーバーの公開鍵> は Rust サーバー側
cat ~/wg0_client.pub
の中身を指定します。 -
AWS ファイアウォールに UDP 51820 を追加して開放します。
-
Rust サーバー側で wg0.conf の作成をおこないます。
AllowedIPs は 0.0.0.0/0 (重要:PBR で “誰を出すか” を制御します)
# /etc/wireguard/wg0.conf [Interface] Address = 10.10.0.2/24 PrivateKey = <Rust サーバーの秘密鍵> DNS = 1.1.1.1 [Peer] PublicKey = <AWS の公開鍵> Endpoint = <AWS のIPまたはドメイン>:51820 AllowedIPs = 0.0.0.0/0 PersistentKeepalive = 25
<Rust サーバーの秘密鍵> は
cat ~/wg0_client.key
の中身を指定します。<AWS の公開鍵> は AWS 側
cat ~/wg0_server.pub
の中身を指定します。
WireGuard 起動 & 握手確認
-
AWS、Rust サーバーの両方で WireGuard を起動します。
sudo wg-quick down wg0 2>/dev/null || true sudo wg-quick up wg0
-
AWS、Rust サーバーの両方で握手確認をおこないます。
sudo wg show
AWS 側は
latest handshake
が表示されたら OKRust サーバー側は
received
が 0 より大きければ OK
Rust サーバー:ポリシールーティング (PBR)
-
テーブル定義 & ルート(table 200 = vpn)
echo "200 vpn" | sudo tee -a /etc/iproute2/rt_tables # 既定は wg0 (AWS) へ sudo ip route replace default dev wg0 table 200 sudo ip route add 10.10.0.0/24 dev wg0 table 200 2>/dev/null || true sudo ip route add 172.30.0.0/24 dev br-rustnet table 200 2>/dev/null || true sudo ip route add 192.168.210.0/24 dev eth0 table 200 2>/dev/null || true ip route show table 200 # default dev wg0 # 10.10.0.0/24 dev wg0 # 172.30.0.0/24 dev br-rustnet # 192.168.210.0/24 dev eth0
-
ルール (優先度高め、転送でも確実ヒット)
# Rust コンテナ IP からの発信を table 200 へ sudo ip rule add pref 600 from 172.30.0.10 lookup 200 # br-rustnet から来た転送パケットも table 200 へ sudo ip rule add pref 590 iif br-rustnet lookup 200 sudo ip route flush cache ip rule | sed -n '1,20p'
Rust サーバー:転送許可 & rp_filter 調整
# ルーティング転送 ON (恒久化は後述)
sudo sysctl -w net.ipv4.ip_forward=1
# FORWARD 許可 (行きと戻り)
sudo iptables -C FORWARD -i br-rustnet -o wg0 -j ACCEPT || sudo iptables -I FORWARD 1 -i br-rustnet -o wg0 -j ACCEPT
sudo iptables -C FORWARD -i wg0 -o br-rustnet -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT || \
sudo iptables -I FORWARD 1 -i wg0 -o br-rustnet -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# (必要に応じて)rp_filter の緩和
# sudo sysctl -w net.ipv4.conf.all.rp_filter=2
# sudo sysctl -w net.ipv4.conf.default.rp_filter=2
動作確認
# ルート解決
ip route get 1.1.1.1 from 172.30.0.10 iif br-rustnet # → dev wg0 ... になればOK
# コンテナから TCP/80 を3秒テスト
docker exec -it rust-dedicated-server bash -lc \
'timeout 5 bash -c "cat </dev/null >/dev/tcp/93.184.216.34/80" && echo OK || echo FAIL'
AWS 側で SNAT カウンタが増えることも確認:
watch -n1 'sudo iptables -t nat -L POSTROUTING -n -v | egrep "172\.30\.0\.0/24|10\.10\.0\.2/32"'
増えれば コンテナ → wg0 → AWS → 外 が通っている確証
永続化
-
WireGuard の自動起動 (Rust サーバー & AWS)
sudo wg-quick down wg0 || true sudo systemctl enable wg-quick@wg0 sudo systemctl start wg-quick@wg0 systemctl status wg-quick@wg0 --no-pager -l
-
PBR の自動適用 (Rust サーバー)
/usr/local/sbin/rust-pbr.sh
#!/usr/bin/env bash set -e RUST_IP="172.30.0.10" RUSTNET_BR="br-rustnet" LAN_IF="$(ip -4 route | awk '/default/ {print $5; exit}')" WG_NET="10.10.0.0/24" LAN_NET="192.168.210.0/24" ip route replace default dev wg0 table 200 ip route add ${WG_NET} dev wg0 table 200 2>/dev/null || true ip route add 172.30.0.0/24 dev ${RUSTNET_BR} table 200 2>/dev/null || true ip route add ${LAN_NET} dev ${LAN_IF} table 200 2>/dev/null || true ip rule del from ${RUST_IP} lookup 200 2>/dev/null || true ip rule add pref 600 from ${RUST_IP} lookup 200 ip rule del pref 590 2>/dev/null || true ip rule add pref 590 iif ${RUSTNET_BR} lookup 200
sudo chmod +x /usr/local/sbin/rust-pbr.sh
/etc/systemd/system/rust-pbr.service
[Unit] Description=Policy routing for Rust container via wg0 After=wg-quick@wg0.service docker.service Wants=wg-quick@wg0.service docker.service [Service] Type=oneshot ExecStart=/usr/local/sbin/rust-pbr.sh RemainAfterExit=true [Install] WantedBy=multi-user.target
sudo systemctl daemon-reload sudo systemctl enable --now rust-pbr.service
トラブル時のチェック項目
- 鍵の対応:
Rust サーバー[Peer].PublicKey
= AWS 公開鍵 / AWS [Peer].PublicKey = Rust サーバー公開鍵 - Rust サーバー
[Peer].AllowedIPs = 0.0.0.0/0
- AWS NAT:
POSTROUTING -s 172.30.0.0/24 -o ens5 -j MASQUERADE
- ルール優先度:
pref 590 iif br-rustnet
とpref 600 from 172.30.0.10
が 998/999 より上 - ルート:
ip route show table 200
が「default dev wg0 …」の 4 行になっている - 経路確認:
ip route get 1.1.1.1 from 172.30.0.10 iif br-rustnet
→dev wg0
- 実疎通:コンテナから
/dev/tcp/93.184.216.34/80
→ OK