endaaman.com

2026-07-30

Tips

研究室のネットワークが半年ごとに死ぬ事件、犯人はビーコンだった

半年周期で研究室のLANが全滅する怪現象を2日かけて追い、DHCPプールを毒殺していたIoTビーコンと、ついでに隣からタダ乗りしていた謎ルーターを検挙するまでの記録

北海道大学の研究室のネットワークが、半年くらいの周期で完全に死ぬ。壁のLANポートを別の系統に差し替えると復活する。ルーターを RTX1210 から IX2207 に買い替えても再発した。「LAN内に変な端末がいるのでは」という勘だけを頼りに、シリアルコンソールから2日がかりで犯人を追い詰めた記録。

結論から書くと、犯人は Dr.JOY のビーコンゲートウェイ(Minew製、ホスト名 Thingoo) だった。設置ミスで半接続状態になった1台が、DHCPプールを1日約1.8個のペースで毒殺し、約4〜5ヶ月でプールを食い尽くす——「半年で死ぬ」の正体はこれだった。ついでに、まったく別件のタダ乗り二段ルーターも発見・遮断した。

環境

[北大キャンパス網 HINES] ──壁LANポート── [NEC IX2207]
                                          ├ LAN: 192.168.0.0/21 (ルーター=192.168.0.1)
                                          ├ DHCPプール: 192.168.4.1〜254 (リース6時間)
                                          ├ NAPT + proxy-DNS
                                          └ Buffalo AirStation ×2 ほか有線/無線 約80台
  • 障害発生時、壁LANに別のPCを直挿しすると普通に通信できる(=大学側ポートは無実に見える)
  • ルーターを買い替えても再発(=ルーター個体も無実)
  • 消去法で「LANの中に何かいる」

シリアルを繋ぐ

Webの管理画面はACLで実質封鎖されていたので、シリアルコンソール(9600bps 8N1)で入る。picocom を人間が叩く代わりに、スクリプトから printf でコマンドを流し込んで timeout cat で受ける方式にした。これが後々の「無人監視」に効いてくる。

$ stty -F /dev/ttyUSB0 9600 cs8 -cstopb -parenb -crtscts raw -echo
$ ( timeout 30 cat /dev/ttyUSB0 > log.txt ) & printf 'show logging\r' > /dev/ttyUSB0; wait

IXシリーズの罠メモ:

  • show logging などは enable-config(設定モード)に入らないと使えない
  • terminal length 0 でページング無効化
  • Ctrl-U での行クリアは効かない。ゴミが残ったら \r を送ってエラーで流す
  • コンソールにログが垂れ流されるので、キャプチャにはノイズが混ざる前提で

発見1: 上流ゲートウェイがARPに応答しない

障害発生中のログはこうなっていた。リンクはUP、物理エラーはCRC含めゼロ。なのに:

IP.006: Packet 192.168.11.9 > 192.168.11.17 discarded for LINK-FRMWRK:
        NO ENTRY IN LOOKUP TABLE TO COMPLETE OPERATION, GigaEthernet0.0

上流側(当時のポートは 192.168.11.0/24 系)のゲートウェイ/DNSへの ARP解決が延々と失敗している。累積カウンタを見ると WAN側 neighbor unreachable が900万件。「線は生きているのに、上流がうちのルーターだけ無視する」状態。NAPTなので研究室の全トラフィックは上流から1つのMAC/IPに見える。LAN内の誰かの異常トラフィックのせいで、大学側の検疫がルーターごと隔離したのではないか、という仮説がここで立つ。

発見2: DHCPプールが毒殺されていた

show ip dhcp lease を見て息を呑んだ。

Leased to 94 clients
D 192.168.4.31    <同一MAC>  N/A  N/A  Abandoned lan-pool
D 192.168.4.32    <同一MAC>  N/A  N/A  Abandoned lan-pool
D 192.168.4.34    <同一MAC>  N/A  N/A  Abandoned lan-pool
...(延々と続く)

プール254個のうち、151個が Abandoned(放棄)状態。うち134個がたった1つのMACに紐づいていた。DHCPには「OFFERされたIPをクライアントが衝突チェックして、使用中だと思ったらDECLINEで拒否する」仕組みがあり、サーバーはDECLINEされたIPを Abandoned として封印する。つまりこの端末、もらったIPを片っ端から「衝突してる!」と誤検知して拒否し続け、数ヶ月かけてプールを食い潰していた

数字がきれいに合う。ルーター起動から75日で134個 ≒ 1日1.8個。このペースだと:

254個 ÷ 1.8個/日 ≒ 140日 ≒ 4〜5ヶ月でプール枯渇

「半年くらいで死ぬ」の周期と一致。ルーター再起動(壁ポート差し替えのついでの電源入れ直し)で Abandoned がリセットされて復活し、また数ヶ月かけて枯渇する——長年の怪現象の正体だった。

犯人MACのOUIは深圳の無名ベンダー(Shenzhen Naxiang Technology)。この時点では正体不明の中華IoTとしか分からない。

対処: MAC ACLでban

IX2207 のMACアクセスリストで即座に遮断した。

access-list baniot sequence-mode 100
access-list baniot 100 deny src <犯人MAC> dest any
access-list baniot 200 permit src any dest any
interface GigaEthernet1.0
  filter baniot 100 in

ポイント:

  • permit any より小さいシーケンス番号で deny を入れる(後から足すと permit の後ろに回って無効)
  • deny のヒットカウンタがそのまま「犯人の生存センサー」になる
  • MFLT.003: BLOCK ... としてログにも遮断記録が残る

あわせて clear ip dhcp lease で汚染をリセットし、プールを 192.168.4.1〜192.168.5.254 に倍増(/21なので5.x帯も同一サブネット。事前にping掃引で空きを確認)。壁LANを繋ぎ直すと完全復旧した。ちなみに新ポートはグローバル直(133.87.0.0/16系)で、ポートごとに上流の系統が違うことも分かった。

寄り道: タダ乗り二段ルーターの検挙

調査中、副産物が2つ出た。

1つめ。DNSに毎秒数十発のクエリを投げる端末がいたが、これは上流DNS死亡による再試行嵐(二次症状)で、tcpdumpでmDNSを覗いたら教授室のWindows機が epson.local を延々探しているだけだった。シロ。

2つめが本命で、見覚えのないTP-Link機器がうちのDHCPからIPをもらい、こちらのゲートウェイを毎秒ARPしていた。banして観察すると、denyカウンタが毎秒数十ヒット。一時的にbanを解除する「おとり捜査」をやったところ、通過トラフィックが平常の4倍に跳ねたのに、新しいMACは1つも現れなかった——つまり配下の端末群をNATで抱えた二段ルーターが、うちのLANを上流としてタダ乗りしていた。昔の配線が隣の研究室まで伸びているらしく、電波状況からも隣室設置が濃厚(同名のSSIDが42%の強度で見える)。こちらは別件としてban継続中。

犯人の正体: Dr.JOYのビーコンゲートウェイ

決定打は物理捜索だった。HINESの壁LAN(大学管理のハブ、うちのルーターのWAN側と同居)に刺さっている謎のビーコンが見つかった。ラベルのWiFi MACは、LAN上で75日間行儀よく動いているMinew製ゲートウェイと下1桁違いの連番。同一ロットの兄弟機だ。

抜き差しした瞬間、banのdenyカウンタが 0 → 191 に跳ねた。現行犯。

さらに隔離環境で解剖した。ノートPCのUSB-LANに直結し、使い捨てのdnsmasqでDHCPを立てる:

dnsmasq-dhcp: DHCPDISCOVER 192.168.0.2 <ビーコン有線MAC>   ← 工場デフォルトのIPを希望してくる
dnsmasq-dhcp: DHCPOFFER    10.99.0.37
dnsmasq-dhcp: DHCPREQUEST  10.99.0.37
dnsmasq-dhcp: DHCPACK      10.99.0.37 ... Thingoo           ← 素直に取得。ホスト名はThingoo

取得直後に mqtt.drjoy.jp を引きに行ったので Dr.JOY の機器と確定。ついでに、DHCPで配ったDNSを無視して 8.8.8.8 と 114.114.114.114(中国の114DNS)に直接問い合わせる行儀の悪さも観察できた。

重要なのは、有線側のDHCPクライアントは健全だったこと(単体ではDECLINEしない)。犯人MACはこの箱のWiFiモジュール側(だからOUIが別ベンダー)で、病気はWiFi側のスタックに固有だった。

全体像: 半接続の子機がWiFi経由でプールを毒殺していた

このビーコンゲートウェイは2台1組で、親機は GW-(自身のMAC) という形式のSSIDのホットスポットを吹き、子機は工場設定でそこに自動接続する(設定UIはなく「持ってきてLANに挿すだけ」の製品)。整理すると:

[子機B] ─有線─→ HINESのハブ ← MAC登録制なので大学DHCPからは永遠に無視される
   │
   └─WiFi─→ [親機AのGW-*ホットスポット] ─→ 親機Aの有線 ─→ 研究室LAN
                                   ↓
              子機BのWiFi側がうちのDHCPに DISCOVER → OFFER → DECLINE のループ
              (有線とWiFiの二本足で自分のARPプローブを自分で聞いて衝突誤検知、と推定)
  • 子機の有線は「リンクは上がるがIPは永遠にもらえない」半接続状態(HINESはMACホワイトリスト制)
  • 有線を諦めきれないファームがWiFiフォールバックし、親機経由でうちのLANに出てくる
  • そこでDECLINEループ → 1日1.8個ペースでプール毒殺
  • おまけにHINES側でも未登録MACのままDHCPを叫び続けるので、大学の検疫が壁ポートごと殺していた疑い(こちらは状況証拠のみ。「壁ポートを変えると復活」「ルーターを替えても再発」とは整合する)

検証実験で分かった機器の癖も残しておく:

  • 有線PHYはケーブル差し替えでは起きない。電源入れ直し必須(起動から2〜3分でリンクアップ)
  • 有線が完全に無いと自分が親機(AP)モードになり、クライアントには回らない
  • 隔離環境(クラウド不達)では兄弟機への接続が成立しない — 再現にはインターネットが要る
  • 親機と子機の役割は固定らしく、逆配置(親機を半接続にする)では一晩置いても発症しなかった

対策まとめ

対策 内容
根本 ビーコンの有線をHINESから撤去。正規に使うなら「研究室LANに有線1本だけ」
保険 犯人MACのban(MAC ACL)は恒久で残す。denyカウンタが監視センサーを兼ねる
延命 DHCPプールを254→508に倍増
別件 タダ乗りTP-Linkもban。配線の物理撤去と隣室との相談はこれから
報告 「有線+WiFi同時接続時にDECLINEループでDHCPプールを枯渇させる」としてベンダーに報告可能な再現ログ一式を保存

教訓

  • 「ルーターを替えても直らない」は、犯人がルーターの外にいる強いヒント。今回は買い替え1台分の授業料だった。
  • DHCPの障害は show ip dhcp leaseAbandoned を数える。DECLINEループによるプール毒殺は、進行がゆっくりなせいで「たまに死ぬ」「再起動で直る」という掴みどころのない症状になる。
  • 汚染ペース(個/日)× プールサイズ = 障害周期。周期性のある障害は割り算してみると犯人の挙動が逆算できる。
  • banはブロックであると同時に計測器になる。denyカウンタ+タイムスタンプ付きログで、犯人の生死・発作の瞬間・経路の切り分けまで全部できた。
  • IoT機器は「WiFiのMAC」「有線のMAC」「無線モジュールのMAC」が全部バラバラのベンダーOUIだったりする。ラベルのMACだけ見て安心しない。
  • シリアルコンソール+スクリプトのポーリングで、安物ルーターでも簡易NMSが組める。ログバッファが20分で一周する機種でも、ACLカウンタは無限に積算してくれる。

©2024 endaaman.com