2026/07/16(木)R86S U1のNICを交換した

R86S U1のNICについているSFP+ポートの片方が不安定という問題があり、これがずっと悩みの種だった。

しかしR86S U1のNICはOCP2.0のメザニンカードという特殊な規格であり、入手が難しかった。あと最近なんでも高いことや、ここ一年近く財政が悪く資金がショートしていたこともあり、中々購入のタイミングがなかったが、偶然安いのを見つけたので交換を決意した。

購入したもの

ほぼ新品 Mellanox ConnectX-4 CX4421A MCX4421A-ACQN ネットワーク インターフェイス PCIe カード (OCP2.0 用)

ほぼ新品とあるが中古なのは間違いない。

写真を見る限り左右でコネクタが異なるといったこともなく、3,745円でConnectX-3からConnectX-4に上げられて不調もなくなるならアリではないか?と思い、購入することにした。

配送

荷物はいつも通りCainiaoから発送され、国内ではエスポ便という聞いたこともない業者に引き渡された。軽く調べたところ株式会社エスポリアという越境ECのサービス会社がやっているようで、ここ最近のアリエクに増えているらしい。ここ自体は仲介業者で配送はしてないらしい。

そういえば最近中華特有のテカテカしたプチプチ袋減った気がする。

実際の配送はかつてAmazon便で悪名を馳せたTMG、椿本グループだった。久々に見たので、一般消費者向け宅配便事業で生きてたのかお前…となった。

開封の儀

結構ちゃんとした箱に入っていた。

中身。緩衝材が底にあり、本体も一応元袋らしきものに入っていた。いい感じのヒートシンクがついているのが素晴らしい。

賞味期限ラベルみたいなものが貼ってあったが非常に強力なシールで、爪でカリカリすると爪が削れるレベルで剥がせなかったため剥がすのを諦めた。

新旧比較をすると上が今まで使っていたやつで、下が今回新たに買ったやつだ。

裏返したところ。裏面には薄いアクリルフィルムが基板を保護するように付いていた。短絡防止用だろうか?ヒートシンクを支えるプッシュピンも見えた。

ラベルを見る限り2019年6月製とみられ、比較的新しい製品なのも嬉しい。以前使っていたConnectX-3は製造時期不明だがCX342Aは2015年のモデルらしいので、だいぶ古い。

どこで見たか記憶にないがConnectX-3はサポート切れが近いか、切れていることもあるという話も見た気がするのでConnectX-4を入手できたのはよかった。メイン機もサーバー機もNICはConnectX-4なのでお揃いになった。

装着は既存のConnetX-3を外し、カードを刺す場所に元々ついてたチップクーラーを除去して取り付けたら、そのまま何事もなく普通に装着できた。

このクーラーがあるとヒートシンクに干渉するので、外す必要があった。

OpenWrt上でのセットアップ

OpenWrt 24.10.0にはドライバがなかったのでドライバを入れるのをやっていく。

SFP+以外に接続手段のない私の環境ではルーターのSSHに繋ぐ術がなかったので、R86S U1本体にキーボードとモニタを接続して作業した。

# まずはNIC周りの調査ツールを入れる
opkg update
opkg install pciutils ethtool

# ドライバの状態とかが見れる
# Kernel driver in use: igcならドライバがない
lspci -nnk

# ドライバを入れる。kmod-mlx4-coreは後で消した
opkg install kmod-mlx5-core
# JISキーボードだとアンスコが出せないので頑張って探して打った
modprobe mlx5_core

あとはこのまま再起動したら普通に繋がった。

そのまま使うと温度が上がりすぎた

現状片側のSFP+しか使っていないうえ、それも初日なので不具合は何もない。以前使っていたのも最低でも一週間は使ってないと不安定化しなかったので、まだ安定性は不明だ。

ただソケットが両方とも同じ形に見えるので、以前使っていたものよりは安定するのではないかと考えている。

温度については高くなりがちなようで、R86S U1本体のCPU温度が51度に達することもあった。

以前のNICの温度はデータがなく比較できないのだが、ここまで上がっていることはなかった気がしている。

NIC本体の温度は取得する方法が今のところ分かっていない。mstflintでmstflint -d xxxx -reg_name MTMPとかしたら、提供されていないとか出た気がするがログは取っていない。

参考までに以下の手順でレジスタの値が取れるっぽい。参考:man/mstreg

# 必要なツールのインストール
opkg install lspci mstflint
# MellanoxのデバイスIDの取得
lspci | grep Mellanox | awk '{print $1}'
# レジスタ名一覧
mstflint -d <デバイスID> -show_regs
# レジスタ値の取得
mstflint -d <デバイスID> -reg_name <レジスタ名> -g

関係ないがデータがないのはGrafanaに出しているデータを永続化していないため、tmpが吹き飛ぶと消える状態なので、ここはそのうち何とかしないといけない。

冷却対策

端的に言うとヒートシンクを剥がし、R86S U1に元からついてるクーラーを装着した。

まずはConnectX-4を取り出し、ヒートシンクを外し、グリスを塗りなおす。この時ついでに裏のフィルムも剥がし、熱が溜まらないようにした。

R86S U1に元々ついてたチップクーラー(前述の奴)を持ってきて、付け直した。

ファンレス冷却(ヒートシンク)とファン冷却(クーラー)で同時刻に温度を比べたところ、5度ほど下がるという結果が出たので、かなり効果があった。

新しい奴のヒートシンクの方が目が細かく作りもしっかりしているように見えるが、風のあるなしがそれほどまでに大きいということだろう。

しょぼいヒートシンクと小さいファンの組み合わせなのであまり意味がないだろうと侮っていたが、結果は歴然だった。恐らくこれはケースが小さく通気の余地が少ないこともあり、自然対流には期待できないということの表れなのだろう。

ベンチマーク

以下の構成で速度を計測した結果。そもそもLAN内でパケットがルーターの中を通っているかが謎なのでルーターNIC交換の影響があるかどうかは不明である。

Windows - R86S U1 - MikroTik CRS305-1G-4S+IN - Ubuntu

以前の計測結果はこっち

Windows → Ubuntu

[ ID] Interval           Transfer     Bitrate
[  5]   0.00-1.01   sec  1.07 GBytes  9.13 Gbits/sec
[  5]   1.01-2.01   sec  1.09 GBytes  9.36 Gbits/sec
[  5]   2.01-3.00   sec  1.08 GBytes  9.36 Gbits/sec
[  5]   3.00-4.00   sec  1.09 GBytes  9.36 Gbits/sec
[  5]   4.00-5.01   sec  1.10 GBytes  9.36 Gbits/sec
[  5]   5.01-6.00   sec  1.08 GBytes  9.36 Gbits/sec
[  5]   6.00-7.01   sec  1.10 GBytes  9.36 Gbits/sec
[  5]   7.01-8.01   sec  1.09 GBytes  9.36 Gbits/sec
[  5]   8.01-9.01   sec  1.09 GBytes  9.36 Gbits/sec
[  5]   9.01-10.00  sec  1.08 GBytes  9.36 Gbits/sec
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate
[  5]   0.00-10.00  sec  10.9 GBytes  9.34 Gbits/sec                  sender
[  5]   0.00-10.00  sec  10.9 GBytes  9.33 Gbits/sec                  receiver

Ubuntu→Windows

[ ID] Interval           Transfer     Bitrate         Retr  Cwnd
[  5]   0.00-1.00   sec  1.08 GBytes  9.30 Gbits/sec    0   1.54 MBytes       
[  5]   1.00-2.00   sec  1.08 GBytes  9.28 Gbits/sec    0   1.62 MBytes       
[  5]   2.00-3.00   sec  1.08 GBytes  9.27 Gbits/sec    0   1.70 MBytes       
[  5]   3.00-4.00   sec  1.08 GBytes  9.28 Gbits/sec    0   1.78 MBytes       
[  5]   4.00-5.00   sec  1.08 GBytes  9.28 Gbits/sec    0   1.78 MBytes       
[  5]   5.00-6.00   sec  1.08 GBytes  9.29 Gbits/sec    0   1.78 MBytes       
[  5]   6.00-7.00   sec  1.08 GBytes  9.28 Gbits/sec    0   1.78 MBytes       
[  5]   7.00-8.00   sec  1.08 GBytes  9.28 Gbits/sec    0   1.93 MBytes       
[  5]   8.00-9.00   sec  1.08 GBytes  9.28 Gbits/sec    0   1.93 MBytes       
[  5]   9.00-10.00  sec  1.08 GBytes  9.28 Gbits/sec    0   1.93 MBytes       
- - - - - - - - - - - - - - - - - - - - - - - - -
[ ID] Interval           Transfer     Bitrate         Retr
[  5]   0.00-10.00  sec  10.8 GBytes  9.28 Gbits/sec    0             sender
[  5]   0.00-10.00  sec  10.8 GBytes  9.28 Gbits/sec                  receiver

まとめ

前回と比較すると若干速度が落ちているが、サーバーとして動かしてて帯域を食っている分減っているのかもしれない。

Windows→Ubuntu(上り) Windows→Ubuntu(下り) Ubuntu→Windows(上り) Ubuntu→Windows(下り)
9.34 Gbps 9.33 Gbps 9.28 Gbps 9.28 Gbps

交換前のConnectX-3が改造品だった話

以前使っていたPCB000620は元々SFP+片ポートモデルで、どうやらR86S U1では2ポートに改造していたようだ。

その影響なのか明らかに片方だけソケットの形が異なる。上側のほうが綺麗で、下側は使いこまれているのか、ややぼろ目に見える。

裏面を見ると片方ははんだ付けされているが、片方は差し込んであるだけ。シールも一度剥がしたものを貼り付けているのか、ペラペラしていてすぐに剥がせた。

おそらく上側(PORT 0)のはんだ付けされていた方が本来のソケットで、後から付けたやつ、つまり下側(PORT 1)が差し込んだだけの奴と思われる。

本来のソケットがぼろい方、後付けのが綺麗な方である。

奥の方の作りも異なる。左がPORT 0、右がPORT 1。

R86S U1のNICについているSFP+ポートの片方が不安定だった話で不安定だったのはPORT 1の方なので、改造して無理に取り付けていた方が不具合を発していたのだろう。本来できないことをしているので無理もない。

裏面の形も異なる。

恐らくよくある片ポートの奴にソケットを増設したのだと思う。

ソケットが片ポートしかなくても回路が実装されていることはよくあるので、この回路を流用しているのだと思う。回路もあるし、チップも恐らく同じなので原理的には問題なく動きそうに思える。

R86S U1のSFP+を使い始めたのは2025年の9月17日からだった[1]が、同年12月13日にはリンクアップとリンクダウンが繰り返される事象を確認していて、同年12月25日にSFP+差し込みポートの変更を行ってからは一度も起きていない。

この時の気温が落ちたので金属製のSFP+ソケットの接触不良になったのではないか?と考えていたが、恐らくソケットではなく、基板本体との接触が寒暖差でダメになったのかもしれない。実際、先ほどの写真を見ても基板の穴からピンが出たり出ていなかったりするので、寒暖差でここが僅かに狂った結果、基板と接触不良になり、回路がチャタリングした結果、リンクアップとリンクダウンをミリ秒単位で繰り返す状態が起きていたのかもしれない。

もし、この理屈が正しければ強く押し込んではんだ付けすれば改善しそうではある。

あとがき

NIC交換の時に取り出した時、酷い埃まみれになっていたのでいい加減、冷却面をどうにかしたい気がしている。

普段は上に80mm角ファンを載せて運用しているため、埃の元凶はこれである。一旦はファンフィルターを買ってその場を凌ぎたいところだが、本質的にはちゃんとしたケースに収めてちゃんとしたクーラーをつけるのが最良だと思っている。

R86S U1を冷やそうとした作業の残渣にも書いているが、R86S U1の冷却機構は耐久性があるように見えず、また大して冷やしてもくれない。上にファンを載せて風を入れていると、いつの日か中が埃まみれになってしまうし、このケースはメンテナンス性が良くないので清掃も面倒だ。

理想論としてはこんな感じのケースに組み込めればよいだろう。これならメンテナンスがしやすいし、NICのヒートシンクも元の奴が生かせそうだ。ファンも40mm角ファンだろうから壊れても交換が容易である。

まぁこれは行き過ぎとしても、ラズパイのタワークーラーを載せるとか、そういうのができるとよいなとは思っている。基板むき出しは埃が溜まってショートしそうなので、ケースもあった方がいいだろう。

ただそれをどう実現するかが難しいところで、まず本来的には3D CADでケースやCPUクーラーをモデリングし、CNCで金属を削るという工程が必要だろうが、そんなものはないし、仮に3Dプリンタである程度何とかするにしても、3D CADの使い方を学ぶところからだと気が遠くなる話で、なかなか難しい…。

そもそもノギスで測っても測るたびに数ミリ単位の誤差が出るので、アナログな図面を書くことすら困難だ(多分ノギスの角度が微妙に毎回ズレてる)

こんなことであれば去年アリエクのセールでファンレスのR86SであるR86S-FLN100を買っておけばよかった。今は22.7万もするが、去年は11万くらいで、セールでは9万にまで落ちていて、買いだった。まぁあとからは何とでも言えるし、そもそも9万でも安くないわけで、言ったところで仕方がない。

現実案としては厚紙にボードを固定して外枠をペンで引き、ネジ穴については基板のネジ穴スレスレの何かを差し込んでマーキングすればそれなりに正確なものが取れるだろうから、一度手書きで図面を書き、それを基にアクリル板を加工し、簡単なケースを作るのが一段階目としてはよさそうな気がする。

ただCPUクーラーをどうするかという問題が根深く、ここが難点になると思う…。これはCPUクーラーを作るにはCPUのヒートスプレッダに乗ってくれるヒートシンクを持ったファンと、そのファンと基板のネジ穴を繋ぐ足が必要になるからだ。ヒートシンクと基板のネジ穴がマッチしないとならないので、恐らくこれが一番の難関だろう…。

たぶん厚紙→アクリル板がいければ図面を起こせるので、カスタムアルミケース業者に発注すれば、きちんとしたものも作れると思う。そこまでやるかどうかは未定だが…w


  1. 宅内に10GbE環境を導入してみたの写真のタイムスタンプから推定。

2026/07/08(水)ASUS RT-BE92Uなど一式を買ったのでセットアップログとか

折角LAN内10GbEにしたし、WiFi7が出てずいぶん経つし無線LAN環境も充実させたいよなぁ…と思い、WiFi7対応のWANポート10GbE対応ルーターとしてASUS RT-BE92Uを買ったので、その関連のログ。

今回買ったもの

開封の儀

ASUS RT-BE92U

箱を開けるとこんな感じ。紙の繊維を圧縮したようなケースや紙箱に入った、最近ではよくある梱包。

付属品は壁掛けフック、ACアダプタ、壁掛けフックを固定するネジ、CAT6 LANケーブル。

LANケーブルは同梱品にありがちな極太で硬そうなやつ。

ASF-10G-T80

トランシーバーは金属製の缶に入っており、やたら凝っていた。

手持ちのCAT6Aケーブルを挿すとこんな感じ。

設置後の風景

Before After

びふぉーの写真が去年のものなので完全に前後の写真という訳ではないが、大体こんな感じということで…。

例えばBeforeとAfterでは右側から伸びているコンセントの本数が違うが、これは今回の施工とは関係なく、もっと前に配線変更で減らしたものである。

セットアップの儀

地味にハマるポイントがあり、苦労した。

  1. まずL2スイッチにWANポートを接続しセットアップを始めた
  2. 192.168.50.1が初期IPで、このIPがあることを確認して、http://192.168.50.1に接続するものの何故か繋がらない
  3. http://www.asusrouter.comに繋げとマニュアルにあったので繋ぐが繋がらない
  4. http://192.168.50.1:8443/に繋ぐといい情報を得たが繋がらない
  5. http://www.asusrouter.com:8443/にも繋がらない
  6. https://192.168.50.1:8443/にもhttps://www.asusrouter.com:8443/にも繋がらない
  7. 有線だから悪いのかと思い、WiFi経由で接続を頃見るが繋がらない
  8. WANポートの線を抜きスタンドアロンにして、WiFi経由で同じことをやり直したがやはり繋がらない
  9. しかしWiFiのデフォルトゲートウェイは192.168.50.1を挿していた
  10. ブラウザ経由で操作できないのはなんとも承服しがたいがASUS Routerアプリを試すことにした
  11. アプリを起動しルーターに接続すると「モデルをルーターのWANポートに接続したことを確認してください。」というメッセージが表示され、プログレスバーが100%になるとエラーで死んだ
  12. リトライすると通ったので無視することにした。WANに直接刺さってないと上手く動かないのかもしれない
  13. ISPがどうのこうのなどWAN前提のメッセージが何度か出たが全部無視した
  14. WANの種類を選べと言われたがAPにWANもクソもないのでDHCPのまま進めた
  15. 「ネットワークを再アクティブ化」というのが出たので数分見守った。再起動してるだけだと思う
  16. 動作モードをタップ
  17. アクセスポイントモードを選択し適用
  18. ここまで行うとブラウザからhttp://192.168.50.1への接続に成功したが、あんまり納得できなかった
  19. 管理画面に入ったら詳細設定→LAN→スイッチ制御に遷移しジャンボフレーム有効をON
  20. 管理→システム→サービス→SSHを有効にする、で「LAN only」
  21. SSHのポートを適当に指定し、パスワードログインを許可「いいえ」、認証済みキーに公開鍵を貼り付けて設定
  22. ここから先はSSHに入れた
  23. OSはBusyBox v1.24.1で、何故かIPv6がなく、iperf3が最初から入っていた。どうやらこのルーターにはIPv4でアクセスするしかなさそうだ
  24. ホームディレクトリは/tmp/home/rootで、再起動したら消えそうな勢い
  25. ルートディレクトリは以下の構成で、ルートにはASUS関連のファイルが直置きで散らばっていた
    /.diag
    /.sdn
    /asusdebuglog
    /asusfbsvcs
    /avahi
    /bwdpi
    /cfg_mnt
    /confmtd
    /dm
    /etc
    /home
    /mnt
    /nc
    /netool
    /notify
    /share
    /var
    

速度計測

AP・サーバー間の通信測定

APからサーバーに飛ばしたiperf3の測定結果。構成は以下の通り、速度はその口がサポートしている最大を記載。

なお、このケースではAPのCPU使用率が100%に張り付いていた。

  1. [AP] RT-BE92U (OUT RJ-45 10GbE)
  2. [LANケーブル] CAT 6A RJ45 LAN (CAT6A 10GbE)
  3. [トランシーバー] ASF-10G-T80 (10GbE)
  4. [L2SW] MikroTik CRS305-1G-4S+IN (SFP+ 10GbE)
  5. [DAC] 10Gtek CAB-10GSFP-P0.5M-30 (SFP+ DAC 10GbE)
  6. [NIC] Mellanox ConnectX-4 Lx (SFP+ 10GbE)
  7. [サーバー] Ubuntu 24.04.4 LTS
[物理線経由] AP → サーバー
[ ID] Interval Transfer Bandwidth Retr Cwnd
[ 4] 0.00-1.00 sec 448 MBytes 3.76 Gbits/sec 0 467 KBytes
[ 4] 1.00-2.00 sec 455 MBytes 3.81 Gbits/sec 0 467 KBytes
[ 4] 2.00-3.00 sec 449 MBytes 3.77 Gbits/sec 0 3.61 MBytes
[ 4] 3.00-4.00 sec 428 MBytes 3.58 Gbits/sec 0 3.79 MBytes
[ 4] 4.00-5.00 sec 450 MBytes 3.78 Gbits/sec 0 3.79 MBytes
[ 4] 5.00-6.00 sec 461 MBytes 3.86 Gbits/sec 0 3.79 MBytes
[ 4] 6.00-7.00 sec 465 MBytes 3.91 Gbits/sec 0 3.79 MBytes
[ 4] 7.00-8.00 sec 456 MBytes 3.83 Gbits/sec 0 3.79 MBytes
[ 4] 8.00-9.00 sec 462 MBytes 3.88 Gbits/sec 0 3.79 MBytes
[ 4] 9.00-10.00 sec 448 MBytes 3.75 Gbits/sec 0 3.79 MBytes
[ ID] Interval Transfer Bitrate Retr
[ 4] 0.00-10.00 sec 4.42 GBytes 3.79 Gbits/sec 0 sender
[ 4] 0.00-10.00 sec 4.42 GBytes 3.79 Gbits/sec receiver
[物理線経由] サーバー → AP
[ ID] Interval Transfer Bandwidth Retr Cwnd
[ 5] 0.00-1.00 sec 280 MBytes 2.35 Gbits/sec 11 406 KBytes
[ 5] 1.00-2.00 sec 292 MBytes 2.45 Gbits/sec 7 400 KBytes
[ 5] 2.00-3.00 sec 324 MBytes 2.72 Gbits/sec 17 354 KBytes
[ 5] 3.00-4.00 sec 318 MBytes 2.67 Gbits/sec 19 387 KBytes
[ 5] 4.00-5.00 sec 309 MBytes 2.60 Gbits/sec 17 320 KBytes
[ 5] 5.00-6.00 sec 302 MBytes 2.53 Gbits/sec 13 293 KBytes
[ 5] 6.00-7.00 sec 312 MBytes 2.61 Gbits/sec 21 413 KBytes
[ 5] 7.00-8.00 sec 312 MBytes 2.62 Gbits/sec 15 414 KBytes
[ 5] 8.00-9.00 sec 322 MBytes 2.70 Gbits/sec 7 400 KBytes
[ 5] 9.00-10.00 sec 287 MBytes 2.41 Gbits/sec 8 370 KBytes
[ ID] Interval Transfer Bitrate Retr
[ 5] 0.00-10.00 sec 2.99 GBytes 2.56 Gbits/sec 135 sender
[ 5] 0.00-10.00 sec 2.98 GBytes 2.56 Gbits/sec receiver

ノートPC

ノートPCとサーバーをAPを挟んで繋いだ時のiperf3の測定結果。

[WiFi経由] ノートPC → サーバー(旧AP)

従前のAPを利用し、ノートPCからサーバーに飛ばしたiperf3の測定結果。構成は以下の通り、速度はその口がサポートしている最大を記載。

  1. [ノートPC] Windows 11 Home (WiFi 6E)
    • NEC Lavie PC-GN20D72DYEDYH2YAA
  2. [旧AP] WSR-1800AX4P (IN Wi-Fi 6→OUT 1GbE LAN)
  3. [LANケーブル] CAT 6A RJ45 LAN (CAT6A)
  4. [L3SW] R86S U1 (IN RJ45 2.5GbE→OUT SFP+ 10GbE)
    • ここでRJ45とSFP+をソフトウェアでブリッジしている(こいつにはNICが2枚刺さってる
  5. [L2SW] MikroTik CRS305-1G-4S+IN (SFP+ 10GbE)
  6. [DAC] 10Gtek CAB-10GSFP-P0.5M-30 (SFP+ DAC 10GbE)
  7. [NIC] Mellanox ConnectX-4 Lx (SFP+ 10GbE)
  8. [サーバー] Ubuntu 24.04.4 LTS
[ ID] Interval Transfer Bitrate
[ 5] 0.00-1.00 sec 15.2 MBytes 128 Mbits/sec
[ 5] 1.00-2.00 sec 16.6 MBytes 139 Mbits/sec
[ 5] 2.00-3.02 sec 16.1 MBytes 134 Mbits/sec
[ 5] 3.02-4.01 sec 15.9 MBytes 133 Mbits/sec
[ 5] 4.01-5.01 sec 15.9 MBytes 133 Mbits/sec
[ 5] 5.01-6.02 sec 13.6 MBytes 114 Mbits/sec
[ 5] 6.02-7.01 sec 14.4 MBytes 121 Mbits/sec
[ 5] 7.01-8.01 sec 14.8 MBytes 124 Mbits/sec
[ 5] 8.01-9.01 sec 13.0 MBytes 109 Mbits/sec
[ 5] 9.01-10.01 sec 12.9 MBytes 108 Mbits/sec
[ ID] Interval           Transfer     Bitrate
[  5]   0.00-10.01  sec   148 MBytes   124 Mbits/sec                  sender
[  5]   0.00-10.03  sec   147 MBytes   123 Mbits/sec                  receiver
[WiFi経由] ノートPC → サーバー(新AP)

今回購入したAPを利用し、ノートPCからサーバーに飛ばしたiperf3の測定結果。構成は以下の通り、速度はその口がサポートしている最大を記載。

  1. [ノートPC] Windows 11 Home (WiFi 6E)
    • NEC Lavie PC-GN20D72DYEDYH2YAA
  2. [新AP] RT-BE92U (OUT RJ-45 10GbE)
  3. [LANケーブル] CAT 6A RJ45 LAN (CAT6A 10GbE)
  4. [トランシーバー] ASF-10G-T80 (10GbE)
  5. [L2SW] MikroTik CRS305-1G-4S+IN (SFP+ 10GbE)
  6. [DAC] 10Gtek CAB-10GSFP-P0.5M-30 (SFP+ DAC 10GbE)
  7. [NIC] Mellanox ConnectX-4 Lx (SFP+ 10GbE)
  8. [サーバー] Ubuntu 24.04.4 LTS
[ ID] Interval Transfer Bitrate
[ 5] 0.00-1.00 sec 128 MBytes 1.07 Gbits/sec
[ 5] 1.00-2.00 sec 126 MBytes 1.06 Gbits/sec
[ 5] 2.00-3.01 sec 127 MBytes 1.05 Gbits/sec
[ 5] 3.01-4.01 sec 123 MBytes 1.03 Gbits/sec
[ 5] 4.01-5.01 sec 130 MBytes 1.09 Gbits/sec
[ 5] 5.01-6.01 sec 127 MBytes 1.06 Gbits/sec
[ 5] 6.01-7.01 sec 146 MBytes 1.23 Gbits/sec
[ 5] 7.01-8.01 sec 139 MBytes 1.16 Gbits/sec
[ 5] 8.01-9.01 sec 137 MBytes 1.15 Gbits/sec
[ 5] 9.01-10.01 sec 124 MBytes 1.04 Gbits/sec
[ ID] Interval           Transfer     Bitrate
[  5]   0.00-10.01  sec  1.28 GBytes  1.09 Gbits/sec                  sender
[  5]   0.00-10.03  sec  1.27 GBytes  1.09 Gbits/sec                  receiver

スマホ

スマホとサーバーをAPを挟んで繋いだ時のiperf3の測定結果。

[WiFi経由] スマホ → サーバー(旧AP)

従前のAPを利用し、スマホからサーバーに飛ばしたiperf3の測定結果。構成は以下の通り、速度はその口がサポートしている最大を記載。

  1. [スマホ] Xperia 1 VIII (WiFi 7)
  2. [旧AP] WSR-1800AX4P (IN Wi-Fi 6→OUT 1GbE LAN)
  3. [LANケーブル] CAT 6A RJ45 LAN (CAT6A)
  4. [L3SW] R86S U1 (IN RJ45 2.5GbE→OUT SFP+ 10GbE)
    • ここでRJ45とSFP+をソフトウェアでブリッジしている(こいつにはNICが2枚刺さってる
  5. [L2SW] MikroTik CRS305-1G-4S+IN (SFP+ 10GbE)
  6. [DAC] 10Gtek CAB-10GSFP-P0.5M-30 (SFP+ DAC 10GbE)
  7. [NIC] Mellanox ConnectX-4 Lx (SFP+ 10GbE)
  8. [サーバー] Ubuntu 24.04.4 LTS
[ ID] Interval Transfer Bitrate Retr Cwnd
[433] 0.00-1.00 sec 42.1 MBytes 353 Mbits/sec 2 980 KBytes
[433] 1.00-2.00 sec 39.6 MBytes 332 Mbits/sec 2 526 KBytes
[433] 2.00-3.00 sec 40.0 MBytes 336 Mbits/sec 0 581 KBytes
[433] 3.00-4.00 sec 30.0 MBytes 251 Mbits/sec 5 188 KBytes
[433] 4.00-5.00 sec 30.4 MBytes 255 Mbits/sec 1 199 KBytes
[433] 5.00-6.00 sec 22.9 MBytes 192 Mbits/sec 2 184 KBytes
[433] 6.00-7.00 sec 28.9 MBytes 242 Mbits/sec 1 209 KBytes
[433] 7.00-8.00 sec 27.1 MBytes 228 Mbits/sec 2 146 KBytes
[433] 8.00-9.00 sec 22.5 MBytes 189 Mbits/sec 1 205 KBytes
[433] 9.00-10.00 sec 28.0 MBytes 235 Mbits/sec 2 164 KBytes
[ ID] Interval           Transfer     Bitrate         Retr
[433]   0.00-10.00  sec   312 MBytes   261 Mbits/sec   18            sender
[433]   0.00-10.01  sec   311 MBytes   260 Mbits/sec                  receiver
[WiFi経由] スマホ → サーバー(新AP)

今回購入したAPを利用し、スマホからサーバーに飛ばしたiperf3の測定結果。構成は以下の通り、速度はその口がサポートしている最大を記載。

  1. [スマホ] Xperia 1 VIII (WiFi 7)
  2. [新AP] RT-BE92U (OUT RJ-45 10GbE)
  3. [LANケーブル] CAT 6A RJ45 LAN (CAT6A 10GbE)
  4. [トランシーバー] ASF-10G-T80 (10GbE)
  5. [L2SW] MikroTik CRS305-1G-4S+IN (SFP+ 10GbE)
  6. [DAC] 10Gtek CAB-10GSFP-P0.5M-30 (SFP+ DAC 10GbE)
  7. [NIC] Mellanox ConnectX-4 Lx (SFP+ 10GbE)
  8. [サーバー] Ubuntu 24.04.4 LTS
[ ID] Interval Transfer Bitrate Retr Cwnd
[512] 0.00-1.00 sec 145 MBytes 1.21 Gbits/sec 0 1.93 MBytes
[512] 1.00-2.00 sec 135 MBytes 1.13 Gbits/sec 1 1.93 MBytes
[512] 2.00-3.00 sec 133 MBytes 1.12 Gbits/sec 0 1.93 MBytes
[512] 3.00-4.00 sec 156 MBytes 1.31 Gbits/sec 0 1.93 MBytes
[512] 4.00-5.00 sec 161 MBytes 1.35 Gbits/sec 0 1.93 MBytes
[512] 5.00-6.00 sec 143 MBytes 1.20 Gbits/sec 0 1.93 MBytes
[512] 6.00-7.00 sec 141 MBytes 1.18 Gbits/sec 0 1.93 MBytes
[512] 7.00-8.00 sec 150 MBytes 1.26 Gbits/sec 0 1.93 MBytes
[512] 8.00-9.00 sec 149 MBytes 1.25 Gbits/sec 0 1.93 MBytes
[512] 9.00-10.00 sec 122 MBytes 1.02 Gbits/sec 0 1.93 MBytes
[ ID] Interval           Transfer     Bitrate         Retr
[512]   0.00-10.00  sec  1.40 GBytes  1.20 Gbits/sec    1            sender
[512]   0.00-10.01  sec  1.40 GBytes  1.20 Gbits/sec                  receiver

まとめ

環境 送信 受信 備考
新AP→サーバー 3.79Gbps 3.79Gbps CPU使用率が100%に張り付いていた
サーバー→新AP 2.56Gbps 2.56Gbps
ノートPC→旧AP→サーバー 124Mbps 123Mbps
ノートPC→新AP→サーバー 1.09Gbps 1.09Gbps 旧環境の約8倍
スマホ→旧AP→サーバー 261Mbps 260Mbps
スマホ→新AP→サーバー 1.20Gbps 1.20Gbps 旧環境の約4倍

公式商品ページには「最大9700Mbpsの超高速トライバンドWiFi 7」とあり、10GbEのWANポートがあることから10Gbpsを期待したものの、10Gbps出ることはなかった。所詮無線は無線ということか…。

とはいえ、以前のAPと比べたときの速度は4~8倍と格段に上がっており、WiFi経由での写真の転送もかなり早くなっており、全体的な満足度は高い。

今までルーターと言えば数千円のものを常用してきており、これは3万円強したが、よい買い物だったと思う。

あとがき

ルーターの置き方やアンテナの方向に無理があるので、ラックにぶら下げておけるような紐か何かがあると便利かもなぁと思ったので、そのうち整備したいところだ。

或いは壁美人を使って壁に付けるのもなくはないかもしれないが、ケーブルを伸ばすとケーブルに埃が溜まって嫌なので、それはしないかもしれない…。

旧AP (1GbE, WiFi6) 新AP (10GbE, WiFi7)

ひとまず10GbEネットワークが広がったので満足度は高まった。

上図ではWiFi APの部分以外も微妙に変わっているが、これはConoHa VPSを前段に置く対応を取りやめたことでPPPoEが復活したことを反映しているためだ。要するに別件の変更がごっちゃになっている()

あとは無線は破線の方が分かりやすいというのでWiFiを破線化している。というか、これは元来破線だったのがいつの間にか消失していたのを戻している感じである。

2026/07/08(水)nginxにクライアント証明書認証の設定をした

管理領域など、自分以外などにアクセスを許可したくない場所にパスフレーズ付きクライアント証明書で制限を掛け、自分以外アクセスできないようにしたので、そのログ。

確認環境

サーバーと証明書作成環境

Env Ver
OS Ubuntu 24.04.4 LTS
nginx 1.24.0
OpenSSL 3.0.13 30

クライアント証明書を設定してアクセスした環境1

Env Ver
OS Windows 11 Pro 25H2 (OSビルド 26200.8783)
クライアント Microsoft Edge バージョン 150.0.4078.48

クライアント証明書を設定してアクセスした環境2

Env Ver
OS Android 16
クライアント Microsoft Edge バージョン 149.0.4022.105

手順

CAやクライアント証明書の作成

ここから行うコマンドはその全てでパスワード入力プロンプトが出るため、個別に流す必要がある。

  1. 判別しやすくするためにファイル名の頭に付与する接頭辞を決める
    file_prefix=lyco_
    
  2. CA(認証局)を作成する

    1. CAの秘密鍵の作成
      # -pass=pass:<PASSWORD>でもパスワードを掛けられるが平文になるらしいので-aes-128-cbcでパスワードを掛ける
      openssl genpkey \
        -algorithm EC \
        -pkeyopt ec_paramgen_curve:P-256 \
        -out ${file_prefix}ca.key \
        -aes-128-cbc
      
    2. CAの証明書署名要求の作成

      # 適当に好きな値を設定(以下は私の設定例)
      # 最低限CommonNameさえあればあとは何でもいいらしい?
      
      CountryCode=JA # 国コードを指定するっぽいが多分何を指定してもいい
      Province=Hyogo # たぶん県を指定するっぽいが多分何を指定してもいい
      Location=Kobe # たぶん市区町村を指定するっぽいが多分何を指定してもいい
      Organization="Lycolia Rizzim" # 組織を設定を指定するっぽいが多分何を指定してもいい
      CommonName=lycolia.info # FQDNを指定するっぽいが多分何を指定してもいい
      
      # CA証明書署名要求作成
      
      openssl req \
        -new \
        -key ${file_prefix}ca.key \
        -out ${file_prefix}ca.csr \
        -subj "/C=${CountryCode}/ST=${Province}/L=${Location}/O=${Organization}/CN=${CommonName}-CA"
      
    3. CAの証明書の作成
      openssl req \
        -new \
        -x509 \
        -key ${file_prefix}ca.key \
        -out ${file_prefix}ca.crt \
        -subj "/C=${CountryCode}/ST=${Province}/L=${Location}/O=${Organization}/CN=${CommonName}-CA"
      
  3. クライアント証明書作成

    1. クライアントの秘密鍵の作成

      # -pass=pass:<PASSWORD>でもパスワードを掛けられるが平文になるらしいので-aes-128-cbcでパスワードを掛ける
      openssl genpkey \
        -algorithm EC \
        -pkeyopt ec_paramgen_curve:P-256 \
        -out ${file_prefix}client.key \
        -aes-128-cbc
      
    2. クライアントの証明書署名要求の作成

      openssl req \
        -new \
        -key ${file_prefix}client.key \
        -out ${file_prefix}client.csr \
        -subj "/C=${CountryCode}/ST=${Province}/L=${Location}/O=${Organization}/CN=${CommonName}-CLIENT"
      
    3. クライアント証明書の作成

      openssl x509 \
        -req \
        -in ${file_prefix}client.csr \
        -CA ${file_prefix}ca.crt \
        -CAkey ${file_prefix}ca.key \
        -CAcreateserial \
        -out ${file_prefix}client.crt \
        -subj "/C=${CountryCode}/ST=${Province}/L=${Location}/O=${Organization}/CN=${CommonName}-CLIENT"
      
  4. クライアントに食べさせる用の証明書を作る(PKCS12形式)
    openssl pkcs12 \
      -export \
      -out ${file_prefix}client.pfx \
      -inkey ${file_prefix}client.key \
      -in ${file_prefix}client.crt
    
  5. CA証明書の配置

    sudo mkdir /etc/nginx/ca
    sudo cp ${file_prefix}ca.crt /etc/nginx/ca
    
  6. nginxのsnippetsの作成

    cat <<EOF | sudo tee /etc/nginx/snippets/ssl_verify_client.conf
    ssl_verify_client on;
    ssl_client_certificate "ca/${file_prefix}ca.crt";
    EOF
    
  7. 各vhostの設定に埋め込む。https環境でないと設定しても意味ないので注意
    server {
      ...
      include snippets/ssl_verify_client.conf;
      ...
    }
    
  8. 設定を再読み込み
    sudo systemctl reload nginx
    
  9. 疎通確認
    curl -v \
      --cert ${file_prefix}client.crt \
      --key ${file_prefix}client.key \
      --cacert ${file_prefix}ca.crt \
      https://hoge.example.com/
    

WindowsのEdgeからアクセスする

  1. 作成したPKCS12形式の証明書をWindowsにもってきてダブルクリックする。保存場所→現在のユーザーで次へ
  2. 何もせず次へ
  3. パスワードを入力して次へ
  4. 何もせず次へ
  5. スマートカードを挿入をキャンセルする
  6. プライベートモードでEdgeを開き設定したvhostにアクセスして証明書を選択しなかったときに400エラーが出ることを確認
  7. プライベートモードを閉じて再度アクセスしたときに証明書を選択したときに正常にアクセスできることを確認

AndroidのEdgeから確認する

  1. 作成したPKCS12形式の証明書をAndroidにもってきて開く
  2. 適当にインポートする
  3. プライベートモードでEdgeを開き設定したvhostにアクセスして証明書を選択しなかったときに400エラーが出ることを確認
  4. プライベートモードを閉じて再度アクセスしたときに証明書を選択したときに正常にアクセスできることを確認

メモ

genrsaよりgenpkeyを使った方がいい

Generation of RSA Private Key. Superceded by genpkey.

https://linux.die.net/man/1/openssl

トラブルシューティング

証明書の選択画面が出ない

httpsになってないと出ない。

http://localhostとかhttp://dev.localみたいなアクセスをしていると出てこない。

HTTPSでアクセスしているのに400エラーが出る

CAの証明書とクライアントの証明書でCNの値が同じだと自己署名証明書扱いされて上手くいかないのでCNの値を変える。

今回手順に書いた内容ではCAとクライアント用でCNの値が相違するよう書いているので手順通りにしていれば起きない。

ED25519で証明書を作ったらなんか動かない

openssl genpkey-algorithm ed25519にするとEdgeは上手く解釈できないっぽいので-algorithm EC -pkeyopt ec_paramgen_curve:P-256として作る必要がある。

今回手順に書いた手順通りにしていれば起きない。

参考記事

2026/07/06(月)ConoHa VPSからIPv4のアクセスを自宅サーバーにIPv6でリバースプロキシするときにやったこと

更新日:
投稿日:

ログを取っていないので記憶で書いているし、順序は効率よくなるように変えているため、上手くいかない可能性がある。

前提

  • IPv4接続だけをConoHa VPSに移し、IPv4はConoHa VPSに立てたリバプロから受ける
  • ConoHa VPSスペックとしてOSはDebian GNU/Linux 13、メモリは512MB、CPU 1コアの最安インスタンス
  • ConoHa VPSから自宅サーバーへはIPv6でリバースプロキシする
  • ConoHa VPSから自宅サーバーへはHTTP通信で接続する
    • つまりIPv4側のTLS終端はConoHa VPS、IPv6側は自宅サーバーという構成
  • ConoHa VPSのIPv6アドレスは2400:8500:2002:3175:160:251:206:248

1. ConoHa VPS側でSSH接続できるようにする

この時点ではSSHで繋げないためWeb画面からすべて行う。

  1. SSHとICMPが繋がるようにする
  2. SSHDの設定方法
  3. 秘密鍵を作成し、公開鍵を取り出し.ssh/authorized_keysに追加
    • rootユーザーに追加した

2. ConoHa VPS側でnginxの設定

ここからはSSHで快適操作!

  1. nginxをインストールして証明書置き場を作る

    apt update
    apt upgrade -y
    apt install -y nginx
    
    mkdir -p /etc/nginx/cert/lycolia.info
    
  2. 証明書をSFTPで移す

  3. 自宅サーバーへのリバプロ設定の作成。メンテナンスを最小限にするためにワイルドカードで飛ばす

    cat <<'EOF' | tee /etc/nginx/conf.d/lycolia-info.conf
    map $http_upgrade $connection_upgrade {
      default upgrade;
      ''    close;
    }
    
    upstream backend {
      server [2400:4153:8f01:c800:c14b:3f7a:2b54:353a];
    }
    
    server {
      http2 on;
      listen 443 ssl;
      server_name lycolia.info *.lycolia.info;
    
      ssl_certificate   /etc/nginx/cert/lycolia.info/fullchain1.pem;
      ssl_certificate_key /etc/nginx/cert/lycolia.info/privkey1.pem;
    
      client_max_body_size 500m;
    
      location / {
        proxy_pass http://backend;
    
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-Proto $scheme;
    
        proxy_http_version 1.1;
        proxy_set_header Upgrade  $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
      }
    }
    EOF
    
    # enbaleは勝手にやってくれた気がする
    systemctl enable nginx
    systemctl restart nginx
    

3. 自宅サーバー側で疎通可能にする

  1. OpenWrtで80番ポートを開く
    1. LuCIを開き、Network→Firewall→Traffic Rulesで443を開けてるところに80を追加
  2. ufwにある既存の設定からIPv4で443に繋ぐ設定を消す
  3. ufwに新しい設定を足す

    # IPv6のみ許可する
    sudo ufw allow to ::/0 port 443
    # ConoHa VPSからの接続のみ80で受けられるようにする
    sudo ufw allow from 2400:8500:2002:3175:160:251:206:248 to any port 80
    
  4. nginx側でConoHa VPSを信頼するようにする
    set_real_ip_from 2400:8500:2002:3175:160:251:206:248;
    real_ip_header X-Real-IP;
    
  5. ConoHa VPSから来たX-Forwarded-Protoがhttpsならhttps、それ以外なら$schemeと解釈できるようなmapを書く
    これはConoHa→自宅サーバーがhttpで結ばれており、標準ではスキーマがhttpになってしまうが、それを回避しつつ、IPv6からの自作場への直アクセスがhttpないしhttpsだった場合は、そちらを取れるように変換するためである
    map "$realip_remote_addr:$http_x_forwarded_proto" $real_scheme {
      default $scheme;
      "2400:8500:2002:3175:160:251:206:248:https" "https";
    }
    
  6. 対応するスキーマのバインドを全部変更する。以下はMastodonの例(4.5.4では二箇所ある)
    CGIであればCGIヘッダを書き換えるとよいと思うが、今回は該当がなかった
    +    proxy_set_header X-Forwarded-Proto $real_scheme;
    -    proxy_set_header X-Forwarded-Proto $scheme;
    

4. DNSの切り替えをする

  1. AレコードをすべてConoHa VPSのIPv4に変更

5. nginxの設定を再読み込みする

DNSレコードが伝播するまでの間に粉うことでダウンタイムを最小化できる!

  1. nginxの設定を再読み込みする
    sudo systemctl reload nginx
    

6. 疎通確認

  1. 現時点で一般公開しているサイトに対し疎通するかどうか確認する
    curl -4 https://lycolia.info
    curl -4 https://blog.lycolia.info
    curl -4 https://mstdn.lycolia.info
    curl -4 https://eco.lycolia.info/wiki/
    
  2. 落ちてたら設定を見直し再試行

7. 掃除

  1. OpenWrtでIPv4向けの443を閉じる
    1. LuCIを開き、Network→Firewall→Traffic Rulesで443を開けてるところを消す
  2. OpenWrtのDDNSスクリプトを無効化
  3. nginxの設定でIPv4で443をlistenしてるところを全部消す

あとがき

やるだけやったが、結果的に現時点では全部撤回したので実証実験みたいになってしまった。

元々はフレッツ光クロスに切り替えてIPv4が失われることを想定して行ったが、よくよく考えたら切り替えたところで、今使っているルーターであるR86S U1のSFP+ポートが片方不安定で現状活用できないことや、IPv4のポート枯渇のためレスポンスが返せなくなる恐れを考えると、今やることではないなと思い、全撤回することにした。

ただまぁせっかくだしログを残していれば将来役に立つこともあるだろうというので残したが、色々あり構築時のログが消え去っていたので記憶を頼りに書くことになってしまったのは反省点である。

しかしR86S U1のSFP+が片側死んでいるのはどうしたものか。最近は何もかもすべてが高いのでおいそれと買い替えなどできないし…。まぁ現状困ってないし、IPv4は無料で手に入るし、別にクロスに変えなくてもいい気はした。

ところで全然関係ないけどWiFi 7を入れようと思ったもののSFP+の口が付いてるWiFiルーターは価格が高く、そうでなくとも、まともに速度が出る奴はどれもこれもデカく場所も取るので難しいね…。ひとまずやるとしたら1WくらいのトランシーバーでRJ45に変換するのが無難そうだと思った。その場合、10GtekのASF-10G-T80辺りはいい選択肢になりそうだ。

ルーターも最低でもトライバンドないと速度が出ないっぽいのでWXR18000BE10P辺りが5万円程度で、比較的小さいので無難だろう。この製品は過去に設置したことがあるのでサイズ的には問題ないことは確認済みである。今は手放しているので持っていない。経緯としてはかつてクロスを入れようとして導入したが、結局入れなかったし、デカくて邪魔だったので売った。

とはいえWiFiの速度には大きな不満があるので再導入を検討するのはありかもしれない。トランシーバーとセットで6万とかになるので眩暈がしそうだが…w

2026/07/06(月)nginxのリバースプロキシが上手くいかない問題を解消した

ConoHa VPSをフロントエンドにし、自宅サーバーにリバースプロキシする構成を組んだ時のトラブルメモ。

起きていた条件

nginxからnginxへリバースプロキシする構成で前段がTLS終端で、後段へはHTTPで接続していた。前段はVPS、後段は物理サーバーで別の環境。

起きていた事象

lycolia.info*.lycolia.info全体で前段が後段に接続できない状態になっていた。

curl -iSsl4 https://blog.lycolia.info/
HTTP/2 000 
server: nginx
date: Fri, 03 Jul 2026 15:24:44 GMT

前段のnginxにcurlを投げるとステータスコード000が返ってきて、curlが終了コード23で異常終了していた。

2026/07/04 00:11:33 [error] 2537#2537: *12468 upstream sent no valid HTTP/1.0 header while reading response header from upstream, client: xxx.xxx.xxx.xxx, server: lycolia.info, request: "GET /pub/lycolia/rss.xml HTTP/2.0", upstream: "http://[2400:4153:8f01:c800:c14b:3f7a:2b54:353a]:80/pub/lycolia/rss.xml", host: "blog.lycolia.info", referrer: "https://blog.lycolia.info/pub/lycolia/rss.xml"

nginxのエラーログには「アップストリームからのレスポンスヘッダーの読み取り中に、アップストリームが有効な HTTP/1.0 ヘッダーを送信しませんでした。」という意味のエラーを出力していた。

後段のnginxには何もログが出ていなかった。

curl -v --http1.1 -H 'Host: blog.lycolia.info' "http://[2400:4153:8f01:c800:c14b:3f7a:2b54:353a]:80/"
*   Trying [2400:4153:8f01:c800:c14b:3f7a:2b54:353a]:80...
* Connected to 2400:4153:8f01:c800:c14b:3f7a:2b54:353a (2400:4153:8f01:c800:c14b:3f7a:2b54:353a) port 80
* using HTTP/1.x
> GET / HTTP/1.1
> Host: blog.lycolia.info
> User-Agent: curl/8.14.1
> Accept: */*
> 
* Request completely sent off
* Received HTTP/0.9 when not allowed
* closing connection #0
curl: (1) Received HTTP/0.9 when not allowed

前段のnginxのあるVPSから、後段のnginxに対してhttpバージョン1.1を明示して叩くと「HTTP/0.9 when not allowed」というエラーが出てきた。HTTP/0.9…?初めて聞く概念だ…。

curl -s --http0.9 'http://[2400:4153:8f01:c800:c14b:3f7a:2b54:353a]/' | xxd           
00000000: 0000 1204 0000 0000 0000 0300 0000 8000  ................
00000010: 0400 0100 0000 0500 ffff ff00 0004 0800  ................
00000020: 0000 0000 7fff 0000 0000 0807 0000 0000  ................
00000030: 0000 0000 0000 0000 01                   .........

httpバージョン0.9を明示して叩き、帰ってきたレスポンスのバイナリ。端的に言うとプロトコルエラーで帰れと言われているが、理由は後述する。

解決した方法

+listen [::]:80;
-listen [::]:80 http2;

後段のmstdn.lycolia.infoの設定を上記に変更することで、他のドメインでも問題が解決した。

何故解決したかはわからないが、恐らく80 http2と書くと、他の80番ポートのリッスンにも影響が波及するのだと思う。

http2通信にしなくても問題ないのかでいうと、Mastodonは問題なさそうに見えたのでたぶん大丈夫なんだと思う。知らんけど。

何故解決したのか

使用しているnginxのバージョンがproxy_passするときにhttp 2.0をサポートしてなかったからだ。

nginx 1.29.4になるとproxy_passでhttp 2.0がサポートされるようで、2025年12月9日のリリースには以下の一文があった。

*) Feature: the ngx_http_proxy_module supports HTTP/2.

この時ばかりは今までnginxのバージョンに興味が微塵になかった私もバージョンを上げたくなった瞬間だった。

ただ後続のバージョンのバグフィックスを見るに結構バグが出てそうなので、今あげるのは時期尚早かもしれない。まぁ現状困ってないので上げなくてもいいのは幸いだ。

ところでv1.25.1になるとlisten単位のhttp2が非推奨になり、代わりにhttp2 onという全体単位?が推奨設定になるため、将来的に現状のポート単位にhttpバージョンを分ける技は使えなくなりそうである。

あとがき

バイナリ読解

前述したHTTP 2.0のバイナリレスポンスを読んでみようのコーナー。

curl -s --http0.9 'http://[2400:4153:8f01:c800:c14b:3f7a:2b54:353a]/' | xxd           
00000000: 0000 1204 0000 0000 0000 0300 0000 8000  ................
00000010: 0400 0100 0000 0500 ffff ff00 0004 0800  ................
00000020: 0000 0000 7fff 0000 0000 0807 0000 0000  ................
00000030: 0000 0000 0000 0000 01                   .........

そのバイナリを見るといいという情報をやってみたので試してみた結果。

まず16進数なので1桁に0-Fが入る。これは0000~1111ということだ。つまり1桁が4bitであることが分かる。

さて、HTTP/0.9は一旦忘れて、先ほどやってきたHTTP/2.0として解釈してRFC 9113 - HTTP/2を読んでみる。

「4. HTTPフレーム」によればHTTPフレームの先頭24bitがLength、8bitがType、8bitがFlag、1bitがReserved、31bitがStream Identifierらしい。

つまり先頭を分解するとこうなる。

Length: 00 00 12
Type: 04
Flag: 00
Reserved+Stream Identifier: 00 00 00 00

Lengthだ。0x000012なので18個の8bitフィールドがある。

次の8bitがTypeで0x04となっている。0x046.5.1. 設定フォーマットだ。

Reserved+Streamは全て0なので無価値だろう。

設定フォーマットではそこから48bit単位が設定フィールドとなる。先頭16bitがIdentifier、後ろ32bitがValueだ。

18個の8bitフィールドが設定になるため18 * 8 = 144, 144 / 48 = 3で3つの設定が存在すると読める。

00 03 00 00 00 80

つまりこの部分になる。

Identifierは00 03なのでSETTINGS_MAX_CONCURRENT_STREAMS。最大同時ストリーム数だ。

Valueは00 00 00 80なので128

次は00 00 00 00 10なのでSETTINGS_HEADER_TABLE_SIZE。ヘッダ圧縮テーブルの最大サイズ。

04 00 01 00なので67,109,120。オクテット単位なので単位はバイトと思われる。オクテットのオクはオクトパスのOctと同じなのでタコの脚は八本と考えると覚えやすい。Octoberも旧暦の8月だからOct。

次は00 00 05なので、SETTINGS_MAX_FRAME_SIZE

00 ff ff ff 00なので4,294,967,040。これも単位なので単位はバイトと思われる。

これで設定が終わり、またフレームに戻る。

00 0004 0800
0000 0000 7fff 0000 0000 0807 0000 0000
0000 0000 0000 0000 01

これが残り。

Length: 00 00 04 → 4 * 8 = 32bit
Type: 08WINDOW_UPDATE
Unused Flags: 00
Reserved+Stream: 00 00 00 00
Reserved+Window Size Increment: 7f ff 00 002,147,418,112

次の残り

0000 0807 0000 0000
0000 0000 0000 0000 01

Length: 00 00 08 → 64bit
Type: 07帰れ
ここまでくれば尻だけ読めばいいので中間は読み飛ばす。
最後の32bitがエラーコードらしいので00 00 00 01が恐らくエラーコード。意味合い的にはPROTOCOL_ERROR

要するにHTTP 2に対してHTTP 1.1で接続していたのでプロトコルエラーが返却され、しかしnginxは理解できなかったのでHTTP 0.9として解釈していたのだろう。

今回組んだ構成

今回nginxからnginxにリバースプロキシをしたわけだが、結果として上図のような構成にした。前段にはConoHa VPSを利用している。

これをした理由としては、以前フレッツ光クロスでフルポート使えるIPv4が取れないことが判明したため、クロスに移行出来るようにするためというのと、IPv4のためにDDNSし続けるのが地味に面倒なのと、宅内からIPv4を排除したかったところによる。

ただこれはこれでVPS側にもTLS証明書が必要になるため、DDNSが消えてもIPv4保守のための呪いはまだ残る。DDNSよりはマシだが…。

また、この構成では前後でnginxのバージョンが異なり前段がv1.26.3、後段がv1.24.0となっているため、前段ではhttp2 onにしないと警告が出るなど、バージョン差異による違いが微妙にある。

結果的にできた構成

今回の施策によって自宅サーバーからIPv4が失われても、AレコードをConoHa VPSに向けることでIPv4を受けることが可能な体制の検証をすることができた。これによってフレッツ光クロスに乗り換えたときのIPv4不在問題を解消できる状態となった。

実運用に移すためにはVPS側にもTLS証明が必要になるので自宅サーバーからSCPで送るか、VPS側でも取得する必要が出てくるので、まだまだ対策が必要だ。後者は同一ドメインに二重に証明書が存在する状態になるのでなんか嫌だし、恐らく前者でやるだろう。TCP パススルーなる技術も健闘したが、真のクライアントIP転送問題など、いろいろ厄介そうなのでやめた。

SCPで送る場合はパスフレーズ付きの鍵認証を突破させ、更にnginxをリロードさせないといけないからこちらもやや頭が痛い。パスフレーズ付きのSSH鍵を無人突破させるにはどこかに平文でパスフレーズを持つ必要がある。暗号化もできるがどんどん複雑に…。

或いはDNS-PERSIST-01を使うことで証明書更新を不要にするのも一つの選択肢かもしれないので、こちらも検討していいかもしれない。

しかしVPSがあることで監視対象が増えるなど、なかなか複雑化してしまうので、これを軌道に乗せるかどうかは現時点では不透明だ。ただConoHa VPSは最低スペックで36ヶ月契約であれば月額293円のため、36ヶ月換算でも10,548円にしかならず、IPv4を保持する手段としてはお手頃である。安いISPでもv4を買おうとすると月2~3,000円はするし、まともなところだと一万円以上するので、IPv4にサーバーがついてこの価格は破格と言える。

帯域は100Mbpsだが、100Mbpsあれば十分だろう。

おまけConoHa VPSで帯域実測

自宅サーバーとConoHa VPS間でiperf3をやってみた結果。自宅サーバーへの穴あけが面倒だったので自宅サーバー→ConoHaという逆経路でしか試していない。

Interval Transfer Bitrate Retr Cwnd
0.00-1.00 sec 24.4 MBytes 204 Mbits/sec 0 1.42 MBytes
1.00-2.00 sec 10.9 MBytes 91.2 Mbits/sec 0 1.43 MBytes
2.00-3.00 sec 12.2 MBytes 103 Mbits/sec 0 1.43 MBytes
3.00-4.00 sec 11.0 MBytes 92.3 Mbits/sec 0 1.43 MBytes
4.00-5.00 sec 10.9 MBytes 91.2 Mbits/sec 0 1.43 MBytes
5.00-6.00 sec 12.2 MBytes 103 Mbits/sec 0 1.43 MBytes
6.00-7.00 sec 11.0 MBytes 92.3 Mbits/sec 11 1.26 MBytes
7.00-8.00 sec 11.0 MBytes 92.3 Mbits/sec 169 762 KBytes
8.00-9.00 sec 11.0 MBytes 92.3 Mbits/sec 0 807 KBytes
9.00-10.00 sec 12.2 MBytes 103 Mbits/sec 0 838 KBytes
  • sender: 106 Mbits/sec
  • receiver: 103 Mbits/sec