目次
今回の IPv6 DNS ハイジャックに該当するか確認する
この記事で扱うのは、条件が明確な OpenClash の障害です。IPv6、ルーター自身のプロキシ、ローカル DNS ハイジャック、Fake-IP を有効にすると、ルーター上の SmartDNS などのリゾルバーがパブリック IPv6 DNS へアクセスしても 198.18.x のアドレスを受け取ります。その結果、サーバーアドレスにドメインを使うプロキシノードへ接続できなくなります。
一般的な端末で Web ページを開けない、LAN 内の端末が IPv6 を取得できない、サブスクリプションのダウンロードに失敗する、DNS ポートが AdGuard Home に使用されている、といった状況だけでは同じ問題と証明できません。障害がルーター自身からパブリック IPv6 DNS へ送る問い合わせで起きていることを先に確認し、IPv6 が関係するという理由だけでネットワーク全体の機能を無効にしないでください。
次の条件をすべて満たす場合だけ続ける
- OpenClash のバージョンが修正収録済みの v0.47.156 より古い、または更新後にサービスをまだ再起動していない
- システムが fw4/nftables または legacy ip6tables を使用し、ルーター自身のプロキシが有効になっている
- ローカル DNS ハイジャックと Fake-IP が有効で、ルーター自身でも SmartDNS などのリゾルバーが動作している
- そのリゾルバーにパブリック IPv6 DNS の上流が設定され、ノードのサーバーアドレスにドメインが使われている
設定を変更する前に、ロールバック可能なバージョンを保存する
まず OpenClash でプラグイン設定と現在の構成をバックアップし、現在インストール可能な IPK または APK も保存します。プラグインのバージョン、カーネルのバージョン、動作モード、IPv6、ルーター自身のプロキシ、ローカル DNS ハイジャック、SmartDNS の上流を記録してください。これにより、更新や調整後にネットワークが悪化しても元の状態へ戻せます。
テスト中はサブスクリプション、ルール、DNS の上流、動作モードを同時に変更しないでください。一度に変更するのは一項目だけにし、変更前後の問い合わせ結果を残します。そうしなければ、ノードが復旧してもどの手順が効いたか判断できません。
ロールバック用の資料を用意する
プラグイン設定をエクスポートする
設定ファイル管理から設定と現在の構成をバックアップし、ルーター外の端末へダウンロードして保存します。
元のインストーラーを残す
現在のバージョンに対応する公式 IPK または APK を保存し、システムのパッケージ管理が opkg と apk のどちらかを記録します。
原因となるスイッチを記録する
IPv6、ルーター自身のプロキシ、ローカル DNS ハイジャック、Fake-IP、SmartDNS の IPv6 上流が有効かを書き留めます。
直接接続の管理経路を用意する
LAN からルーターを管理できることを確認します。リモートで保守する場合は、予備の接続がない状態で DNS やファイアウォールを変更しないでください。
指定したサーバーへの問い合わせとルールのカウンターから特定する
ルーターのターミナルから、現在到達可能なパブリック IPv6 DNS を一つ指定して、実在するドメインを問い合わせます。正常な結果は、そのドメインの公開 A または AAAA レコードです。198.18.0.0/16 が返り、実行前後で該当する IPv6 OUTPUT DNS Hijack ルールのカウンターが増えた場合、問い合わせは誤ってローカルの Clash DNS へ戻されています。
OpenClash issue #5251 の再現では 2400:3200::1 が使われました。このアドレスが手元のネットワークに適するかは、事前に確認する必要があります。IPv6 の経路自体が到達不能なら、タイムアウトが示すのは上流を利用できないことだけで、ハイジャックの発生は証明できません。問い合わせるドメインは、公開レコードがあると明確に分かっている一般的なドメインへ変更できます。
nslookup www.nic.ad.jp 2400:3200::1結果に応じて次の手順を決める
| 問い合わせ結果 | ルールのカウンター | 結論 |
|---|---|---|
| 198.18.x が返る | IPv6 OUTPUT のカウンターが増える | 確認済みのルーター自身に対する IPv6 DNS ハイジャックと一致する |
| 実際の A または AAAA が返る | カウンターが増えない | この経路は正常なので、サブスクリプション内のノード名前解決用 DNS を確認する |
| 問い合わせがタイムアウトする | カウンターが増えない | まず IPv6 の経路と、選択した DNS へ到達できるかを確認する |
| LAN 内の端末に異常があるが、ルーターの問い合わせは正常 | 該当する変化がない | RA、DHCPv6、RDNSS、ブラウザのセキュア DNS を確認する |
SmartDNS の問い合わせだけに異常があり、Mihomo の上流は正常
プロセスの実行主体と経路を照合します。Mihomo は通常、除外対象の GID で動作しますが、ほかのローカルリゾルバーは OUTPUT ルールに一致する場合があります。
すべての DNS で connection refused が返る
ローカルのリッスンポートと上流設定を確認し、この記事の IPv6 ルール修正を適用しないでください。
指定した IPv4 DNS は正常だが、指定した IPv6 DNS から 198.18.x が返る
この比較結果とカウンターの変化を残し、バージョン更新へ進みます。
- SmartDNS などのローカルリゾルバーパブリック IPv6 アドレスへ 53 番ポートの問い合わせを送る
- OpenClash の OUTPUT ルール旧版では ::/0 により、すべての IPv6 DNS 接続先へ誤って一致する
- ローカルの Clash DNSリダイレクトされた問い合わせが Fake-IP モードで 198.18.x を返す
- プロキシノードのドメイン誤った結果により、ドメインを使用するノードがダイヤルを完了できない
修正では、ルーター自身に対する IPv6 DNS ハイジャックの範囲をすべてのアドレスからループバックアドレス ::1 へ絞りました。この変更で LAN 内の端末に対する DNS 引き継ぎルールは削除されていません。
パブリック IPv6 DNS がローカル問い合わせとして扱われる理由
旧ルールが本来引き継ぐべきだったのは、ルーター自身からループバックアドレスへ送る DNS だけでしたが、IPv6 の接続先範囲に ::/0 が指定されていました。この範囲にはすべての IPv6 アドレスが含まれるため、SmartDNS からパブリック IPv6 DNS の TCP または UDP 53 番ポートへアクセスした場合も、ローカル DNS へリダイレクトされていました。
問題は PR #5209 が ::/0 を新たに追加したことではありません。このコミットで IPv4 と IPv6 のルールを個別に識別した結果、それまで早い段階でスキップされていた古い分岐が安定して実行されるようになり、v0.47.117 以降で欠陥が表面化しやすくなりました。PR #5252 は nftables の二か所と legacy ip6tables の四か所をすべて ::1 へ変更し、LAN 側の DNS 引き継ぎは維持しています。
修正を収録した v0.47.156 へ更新する
OpenClash v0.47.156 は、公式リリース記録から #5252 の収録を確認できる現在の安定版です。まず公式 Release からシステムに対応するインストーラーを取得し、実際のパッケージ管理が opkg か apk かに応じて更新します。開発ブランチのファイル、IPK、APK を混在させず、更新と同時にカーネルや設定を変更しないでください。
インストール完了後は、必ず OpenClash を再起動します。古い ::/0 ルールがランタイムに残っている場合があり、ファイアウォールルールを再生成して初めて、ソース内の ::1 が実際に反映されます。起動に失敗した場合は、保存済みの元のインストーラーと設定を直ちに復元し、変更を重ね続けないでください。
一回でロールバックできる更新手順
システムのパッケージ形式を照合する
opkg のシステムでは公式 IPK、apk のシステムでは公式 APK を選び、ダウンロード元が v0.47.156 Release であることを確認します。
追加の変更を一時停止する
元のカーネル、サブスクリプション、動作モード、DNS 設定を維持し、OpenClash プラグインだけを更新します。
インストールしてサービスを再起動する
インストール完了後に OpenClash を再起動し、ファイアウォールと DNS のルールが再生成されるまで待ちます。
通信を始める前にログを確認する
設定テスト、カーネルの起動、DNS のリッスンに成功したことを確認します。失敗した場合は、元のパッケージとバックアップを復元してください。
再起動後に三つの組み合わせで検証する
更新前と同じルーター、同じドメイン、同じパブリック IPv6 DNS を使ってもう一度問い合わせます。修正が反映されていれば、実際の A または AAAA が返り、パブリックへの問い合わせで IPv6 OUTPUT DNS Hijack のカウンターは増えません。端末自身のループバック ::1 への問い合わせは、引き続き OpenClash で引き継げます。
DNS の比較に成功してから、元々ドメインを使用していたノードをテストし、名前解決、ダイヤル、実際の Web リクエストを確認します。遅延の数値を見るだけでは不十分です。少なくとも一つのノード接続記録と一つの実際のページが復旧したことを確認してください。
修正の受け入れ確認リスト
- OpenClash に v0.47.156 と表示され、インストール後にサービスを再起動している
- 指定したパブリック IPv6 DNS から実際の A または AAAA が返り、198.18.x は返らない
- パブリック IPv6 DNS への問い合わせで、ルーター自身の IPv6 ハイジャックルールのカウンターが増えない
- ::1 への問い合わせではローカル DNS の引き継ぎが正常に機能し、LAN 内の端末の名前解決も損なわれていない
- 元のノードでドメインの名前解決、ダイヤル、実際のアクセスを一度完了できる
すぐに更新できない場合の回避方法とロールバック
すぐに更新できない場合は、SmartDNS からパブリック IPv6 DNS の上流を一時的に削除し、到達可能と確認済みの IPv4 上流へ変更できます。また、ルーター自身のプロキシまたはローカル DNS ハイジャックの原因となる項目を一時的に無効にする方法もあります。どの方法もルーター自身の通信または DNS の引き継ぎを変えるため、項目ごとにテストし、長期的な修正として扱わないでください。
更新後に異常の範囲が広がった場合は、システムプロキシと TUN への依存を無効にし、元のプラグインパッケージと設定のバックアップを復元して OpenClash を再起動します。その後、更新前と同じ IPv4/IPv6 問い合わせを比較し、元の状態へ戻ったことを確認してください。
パブリック IPv6 DNS から実際の結果が返るのにノードが失敗する場合は、proxy-server-nameserver、サブスクリプションの内容、TLS、ノードサーバーを確認し、OUTPUT ルールを変更し続けないでください。
一時的な方法の影響
| 実施内容 | 適する状況 | 必ず再確認する項目 |
|---|---|---|
| SmartDNS を到達可能な IPv4 上流へ変更する | すぐに更新できないが、ノードの名前解決を復旧する必要がある | ローカルドメイン、キャッシュ、ノードのドメインをすべて正常に名前解決できる |
| ルーター自身のプロキシを一時的に無効にする | ルーター自身の DNS だけが影響を受けている | ルーターの更新、サブスクリプション、プラグインダウンロードの送信経路 |
| ローカル DNS ハイジャックを一時的に無効にする | 端末が DHCP で配布された DNS を使ってもよい場合 | LAN 内の端末が、想定した振り分けと DNS ポリシーを迂回していないか |
| 元のパッケージと設定を復元する | 更新後にサービスを起動できない、または LAN で通信できない | バージョン、DNS のリッスン、ファイアウォールルール、実際のアクセス |
