endaaman.com

2026-07-02

Tips

regdomainはちゃんとJPに設定しましょう

Wifi→Wireguard→NFSの転送が25MB/sで頭打ち問題の犯人はWireGuardではなくWi-Fiの規制ドメイン(regdomain)だった話

前の所属のラボの TrueNAS を、 LXC コンテナ→ WireGuard → NAT で NAS につなぐ形で NFS マウントして使い始めた。手元のノートPCで転送速度を確認したら 25MB/s あたりで完全に頭打ちになっていた。最初は「ルータの WireGuard の暗号化が遅いんだろう」と決めつけていたが、順番に切り分けていくと、真犯人は自分のノートPCの Wi-Fi の規制ドメイン(regulatory domain)が 00(未設定)だったであり、全く別だったという記録。

環境

ノートPC(Arch, Intel AX200) --[WiFi]--> ルータ(ASUS AX6000)--[WireGuard]--> NAS内LXC --[NAT]--> NAS
$ mount | grep server41
10.105.100.41:/mnt/data/share on /home/ken/Mount/server41 type nfs4 (rw,...,rsize=1048576,wsize=1048576,...,proto=tcp,...)

rsize/wsize は 1MB でチューニング済み。マウント自体は問題なし。

切り分け1: NFS越しの実測

まず実際に測る。キャッシュに騙されないよう、書き込みは conv=fdatasync、読み込みは iflag=direct を付ける。

$ cd ~/Mount/server41/.bench_ken

# 書き込み
$ dd if=/dev/zero of=testfile bs=1M count=1024 conv=fdatasync
1073741824 bytes (1.1 GB) copied, 57.5 s, 18.7 MB/s

# 読み込み(キャッシュヒット → 無意味)
$ dd if=testfile of=/dev/null bs=1M
1073741824 bytes (1.1 GB) copied, 0.099 s, 10.8 GB/s   ← ローカルのページキャッシュ

# 読み込み(direct でキャッシュ回避)
$ dd if=testfile of=/dev/null bs=1M iflag=direct
1073741824 bytes (1.1 GB) copied, 46.6 s, 23.0 MB/s

Write 18.7 / Read 23.0 MB/s。だいたい 200Mbps 相当。LAN にしては遅すぎ!

切り分け2: 単一ストリームの問題か?

TCP 単一ストリームで詰まっているだけなら、並列化すれば合計は伸びるはず。4本並列で direct read してみる。

$ for i in 1 2 3 4; do dd if=testfile of=/dev/null bs=4M iflag=direct 2>/tmp/dd$i & done; wait
dd1: ... 6.4 MB/s
dd2: ... 6.4 MB/s
dd3: ... 6.4 MB/s
dd4: ... 6.4 MB/s   → 合計 25.6 MB/s

単一(24.6MB/s)とほぼ同じ。並列化しても伸びない = TCPストリーム数の問題ではなく、経路のどこかに ~25MB/s の固い上限がある。レイテンシは ping で avg 3.5ms・ロス0% と良好なので、遅延ではなく帯域律速。

切り分け3: ネットワークか、それとも自分か

ここで同じ LAN 内の有線の端末から NAS へ iperf3 すると、

$ iperf3 -c 10.105.100.41
Connecting to host 10.105.100.41, port 5201
[  5] local 10.105.7.246 port 56570 connected to 10.105.100.41 port 5201
[ ID] Interval           Transfer     Bitrate         Retr  Cwnd
[  5]   0.00-1.00   sec  83.6 MBytes   701 Mbits/sec  115   1.38 MBytes       
[  5]   1.00-2.00   sec  83.4 MBytes   699 Mbits/sec    0   1.50 MBytes       
[  5]   2.00-3.00   sec  81.1 MBytes   680 Mbits/sec    0   1.59 MBytes       
[  5]   3.00-4.00   sec  83.9 MBytes   704 Mbits/sec    3   1.19 MBytes       
...

700Mbpsくらい出る。つまり手元の LAN も NAS 側のネットワークも WireGuard もほぼ問題なし。遅いのは 自分のノートPCから先の経路だけと判明。

犯人発見: Wi-Fiのリンクレートが低すぎる

$ iw dev wlp165s0 link
	signal: -38 dBm                              ← 電波は最高レベル
	rx bitrate: 286.7 MBit/s HE-MCS 11 HE-NSS 2  ← なのに286Mbpsしか出ていない
	tx bitrate: 286.7 MBit/s HE-MCS 11 HE-NSS 2

$ iw dev wlp165s0 info
	channel 120 (5600 MHz), width: 20 MHz        ← チャンネル幅が20MHz

電波は -38dBm と目の前レベルなのに、リンクが 286.7Mbps しか出ていない。これは Wi-Fi 6・2ストリームでも チャンネル幅が 20MHz のときの値。TCP 実効はPHYの6〜7割なので、286 × 0.65 ≒ 186Mbps ≒ 23MB/s。実測の 25MB/s とピッタリ一致する。

つまり犯人は WireGuard ではなく、Wi-Fi が 20MHz 幅でしか繋がっていないことだった。

なぜ20MHzに落ちるのか → 規制ドメインが00

ここで「じゃあルータの設定が 20MHz なのか?」と思ったが、同じ SSID にスマホで繋ぐと 800Mbps 出る。AP は 80MHz 以上で飛ばせているのに、自分のノートPCだけが 20MHz にネゴっている。

原因は規制ドメインだった。

$ iw reg get
country 00: DFS-UNSET     ← JPではなく「00」(ワールド/未設定)になっている

$ iw list | grep -A1 5600
	* 5600.0 MHz [120] (22.0 dBm) (no IR, radar detection)
  • 現在の 5GHz チャンネル ch120 は DFS 帯(レーダーと共用する帯域)。
  • 規制ドメインが 00(未設定)だと、DFS チャンネルは no IR(No Initiate Radiation = 自分から送信開始してはいけない) 扱いになり、安全側に倒して 20MHz に制限される。
  • スマホは正しく JP ドメインで動くので、同じ ch120 でも 80MHz を張れて 800Mbps 出ていた。

カードは Intel AX200 (Wi-Fi 6) で 80/160MHz にフル対応。ハードは何も悪くなく、規制ドメインが JP になっていなかっただけだった。

対策

1. 規制ドメインを JP にする(即効・一時的)

$ sudo iw reg set JP
$ iw reg get | grep country          # → country JP
$ iw dev wlp165s0 info | grep width   # → width: 80 MHz
$ iw dev wlp165s0 link | grep bitrate # → 800Mbps台に上がる

2. 永続化

再起動でも維持されるよう、カーネルモジュールのオプションで固定する。

# /etc/modprobe.d/cfg80211.conf
options cfg80211 ieee80211_regdom=JP

wireless-regdb が入っていること。

$ pacman -Q wireless-regdb || sudo pacman -S wireless-regdb

3. (保険) AP側を非DFSの80MHz固定にする

regdomain を JP にすれば ch120 の 80MHz でも動くが、DFS 帯はレーダー検出で瞬断・幅低下のリスクが残る。確実にしたいなら AP の 5GHz を 非DFS(ch36 or ch149)+ 80MHz 固定にすると、DFS 絡みの不安定さを完全に回避できる。

なぜAPによって発症したりしなかったりするのか

この問題のいやらしいところは、同じノートPCでも AP によって出たり出なかったりすること。「別のAPだと平気」「スマホは平気」「昨日は速かった」とブレるので、余計に原因にたどり着きにくい。理由は、規制ドメインの決まり方と、引っかかる条件がどちらも AP 依存だから。

まず規制ドメインの決まり方には優先順があり、ざっくり以下の順で決まる。

  1. 明示設定(iw reg set / cfg80211.conf / wireless-regdb の設定)
  2. カードのEEPROMに焼かれた値
  3. AP がビーコンで流す国コード(802.11d の Country IE)

Ubuntu などはインストール時のロケール/国選択でここを設定してくれるので 00 に落ちないが、Arch は何も設定しないので 1・2 が無ければ 00(ワールド=一番保守的)のままになる。「ちゃんと設定しろ」と案内されないのに踏むのはこれが理由。

その上で、00 のまま繋いでも 2つの条件が噛み合ったときだけ発症する。

条件① APが 802.11d の Country IE を流しているか

Intel の iwlwifi には LAR(Location Aware Regulatory) という機能があり、繋いだ AP が「私は JP です」とビーコンで宣言していれば、クライアントが 00JP に自動追従して制限が解ける。

  • Country IE を流す AP → 00 でも勝手に直る(発症しない)
  • 流さない AP(消費者向けは流さない設定も多い)→ 00 のまま張り付く

条件② APが DFS チャンネルを使っているか

00 が痛いのは DFS帯(ch52–64, 100–144) に対してだけ。非DFS(ch36–48 / ch149–165、2.4GHzのch1–11)なら 00 でもだいたい普通の幅で通る。

  • AP が非DFS(ch36等)→ 00 でも 80MHz 出る(発症しない)
  • AP が DFS(今回の ch120)→ no IR で 20MHz に制限(発症する)

今回はこの両方が同時に成立していた。

AP が Country IE を流さない  ×  AP が自動選択で DFS の ch120 を掴んだ
        ↓
クライアントは 00 のまま  ×  DFS帯は no IR で 20MHz 制限
        ↓
25MB/s 頭打ち

自分の AP が Country IE を流しているかは、スキャン結果に Country: 行が出るかで分かる。

$ sudo iw dev wlp165s0 scan | grep -iA1 -E 'SSID: C1-105-wifi|Country'

出れば 802.11d を流している AP(LAR で自動追従する)、出なければ流していない AP(00 に張り付く)。だからこそ regdomain は AP 任せ(LAR頼み)にせず、ieee80211_regdom=JP で明示固定しておくのが確実。そうすれば AP が Country IE を流そうが、DFS を掴もうが、常に JP の制限で動く。

教訓

  • 「遅い = 一番それっぽいやつ(WireGuard)が悪い」と決めつけない。端から順に切り分ける
  • iperf3 で「自分より先は速い」を確認できたのが決定打だった。切り分けは どこまでが速くてどこから遅いか の境界を探す作業。
  • Wi-Fi が遅いときは電波強度(signal)だけ見てはダメ。iw dev ... linkbitrateiw dev ... infowidth、そして iw reg getcountry を見る。電波が良いのに遅いなら、たいてい幅か規制ドメイン。
  • 規制ドメインが 00 のまま運用されているケースは意外と多い。DFS チャンネルを掴んだ瞬間に地味に足枷が付く。

©2024 endaaman.com