上海と杭州の自宅ネットワークをつなぐ

上海と杭州の自宅ネットワークをつなぐ

彼女が仕事で北京から上海に引っ越したので、回線の手配も手伝いました。ところが上海電信の500Mは杭州の1000Mより高く、なんとも納得がいきません。そこで上海での透過プロキシ、特定の通信の杭州経由での外部接続、両拠点のLAN相互接続を目指してネットワークを組むことにしました。杭州側はソフトウェアルーターと無線APのシンプルな構成で、普段から自宅経由で通信できる環境があり、次の挑戦に向けた準備はできています。

はじめに

今月、彼女が仕事の都合で北京から上海に引っ越しました。

引っ越しの手伝いと一緒に、中国電信の500M回線も契約しました。

ついでに上海電信への愚痴ですが、500M回線が杭州電信の1000M回線より高いんです。

光ファイバーが金でできているんですか? それともONUのほう?

自称Geekとしては、いじらずにはいられません。考えた結果、次の3つを目標にしました。

  1. 上海で透過プロキシによる検閲回避。
  2. 上海の一部の通信を杭州から外へ出す。
  3. 両拠点のLANを相互にアクセス可能にする。

2つ目は、Netflixなどの地域制限解除にプロキシのサブスクリプションサービスを使っているためです(ここにアフィリエイトリンクを挿入)。このサービスは利用者を制限しており、複数拠点で同時に使うとアカウントを停止される可能性があります。そのため通信を杭州に転送し、出口を1か所にまとめる必要があります。

事前準備

杭州のネットワーク構成は単純です。ONUの下にPPPoE接続を行うソフトウェアルーターがあり、その先に無線AP用のTP-Link機器をつないでいます。小型PCもルーターに直結し、普段の通信を自宅経由にするためのShadowsocksサーバーを動かしています。ソフトウェアルーターは倍控のG30Sです(ここに広告を挿入)。N5100で十分で、OSはImmortalWrt。次のプラグインを入れています。

  • AdGuard Home:DNSによる広告ブロック。
  • Nikki:Mihomoコアによる透過プロキシ。
  • Tailscale:仮想LANの構築。これまでは自宅経由の通信の予備手段として使っていました。
  • DDNS-Go:見てのとおり、DDNSです。

LANのサブネットは192.168.7.0/24です。

機器をそろえて少しでも複雑さを減らすため、同じ構成のG30Sをもう1台購入し、ImmortalWrtを入れました。上海も杭州と同じ、ONU → ソフトウェアルーター → APの構成にします。

インストール

ImmortalWrtのインストールには触れておきたいです。最初はWindowsやほかのLinuxディストリビューションのように、イメージはLive CDかインストーラーで、USBメモリに書いて起動してからインストールするものだと思っていました。ところがUSBから起動すると、そのまま立ち上がってしまいました……。

立ち上がったんです……。

あのimg、システムそのもののイメージだったんですね。

急いでUSBをWinPEに作り直し、physdiskwriteでイメージを内蔵ディスクへ書き込みました。無事に起動し、簡単な設定でインターネット接続とDHCPも動きました。上海のLANは192.168.10.0/24です。

次は容量拡張です。イメージを直接書いたOpenWrtは使える領域が1G未満で、残りのディスクが丸ごと無駄になります。ここで2つ目の難関が来ました。適切な拡張手順が見つからないのです。簡体字中国語の解説は複雑で誤りだらけ、しかも互いのコピペばかりでした。実際の内容はsquashfsの拡張か、空き領域に新しいパーティションを作ってルートをそちらへ移す方法で、本当にパーティション自体を「拡張」する解説はほとんどありません。

結局、OpenWrtの公式ドキュメントにありました……。今後は中国語で検索するのをやめたほうがよさそうです。Googleでも役に立つものが出てきません。

まず検閲回避と通信の出口を片づけます。ここはClashだけで対応できます。

NikkiはMihomoコアで透過プロキシを行うOpenWrtプラグインです。PasswallやClashなどの同種プラグインより細かくカスタマイズできます。インストールはREADMEの手順に従ってください。Releasesからipkを直接ダウンロードしてもインストールできません。妙な話ですが。

nikkinikki-org
nikkinikki-org/OpenWrt-nikki
Transparent Proxy with Mihomo on OpenWrt.
5.3K 582GPL-3.0

インストール後は設定ファイルを読み込めば起動できます。注意点をいくつか。

  1. TUNモードをそのまま有効にできます。ルーティングテーブルを自動設定して透過プロキシを行い、基本的に問題なく動きます。
  2. Mihomoのドメインによる振り分けには、DNSクエリをMihomo経由にする必要があります。Mihomo DNSに53番ポートを取らせてOpenWrt標準のdnsmasqを別ポートに移すか、dnsmasqですべてのDNSクエリをMihomoのDNSポートへ転送します。
  3. FakeIPモードでは、FakeIP Filterを丁寧に設定してください。

あとはおなじみの話で、ほかの環境のMihomoとほぼ同じなので省略します。

設定後にNikkiを有効にすると、DashboardでMihomoがルーターの出口通信をすべて引き受けていることを確認できます。

設定はほぼ私の環境からコピーしました。検閲回避の通信の大半は搬瓦工(BandwagonHost)のプロキシ🪜へ直接つなぎ、杭州から出す必要があるルールだけoutboundを杭州のShadowsocksサーバーに変更しました。試すと遅延も許容範囲で、中国国内の中継を1段挟むようなものです。

ここまでで、ドメイン名を使えば上海から杭州のLANへアクセスできます。FakeIPモードなので、DNSが返した偽IPへのリクエストはMihomoが処理し、ドメインルールで杭州へ転送できるからです。ただしDNSを通らないIP直接指定のリクエストはMihomoでは転送できません。TUNは標準ではLAN宛ての通信を引き受けないためです。また、杭州から上海へのアクセスもまだできません。

そこで、Tailscaleの登場です!

OpenWrtではluci-app-tailscaleを使うと、Tailscaleを比較的わかりやすい画面で管理・設定できます。

asvow
asvow/luci-app-tailscale
LuCI support for tailscale
315 68GPL-3.0

インストール後は一度起動してログイン認証を済ませてから設定します。Tailscale側でこの端末のキー有効期限も無効にしておくとよいです。

詳細設定では、次のようにします。

  • ルートを有効化にチェック:ほかのサブネットへの経路をTailscaleが自動設定します。
  • DNSを許可はチェックしない:必要なのはIP通信のルーティングだけです。
  • 公開するサブネットは192.168.10.0/24:この端末がその範囲をルーティングできるとTailscaleに伝えます。
  • サブネット相互接続にチェック:文字どおりの意味です。
  • サブネットルートは192.168.7.0/24を選択:この範囲へのルーティングをTailscaleに任せます。

杭州側のTailscaleにも対応する設定が必要です。公開するサブネットとサブネットルートには、それぞれ正しい側のアドレス範囲を指定してください。

設定後にTailscaleを再起動すれば、サブネット間の接続ができあがります。上海からも杭州からも、相手側のサブネットのIPを直接指定してホストへアクセスできます。

あとがき

上海で契約したのは何やら「クラウドブロードバンド」というもので、これを解除してブリッジモードを有効にする手続きが非常に面倒です。いまだに終わっていません。

そのため、上の設定はすべて上海のソフトウェアルーターにグローバルIPがない状態で行っています。

幸い杭州側にはグローバルIPがあるので、Tailscaleのホールパンチングで直接接続でき、遅延は十数ミリ秒です。両側ともグローバルIPがなければ、運を天に任せるしかありません。自前のDERP中継を立てるか、数百ミリ秒の遅延に耐えることになります。

最後にもう一度上海電信へ愚痴を。ブリッジモードを有効にするだけで、契約書への署名、写真撮影、審査まで必要とは。泥棒でも警戒しているようです。