macOS で qBittorrent を VPN インターフェースにバインドする方法
macOS の qBittorrent の詳細設定で Network Interface を設定し、utun 名を実際のトンネルに対応させ、クライアントを再起動して、転送でバインドを証明します。
Mac mini で qBittorrent を開き、Network Interface を utun4 に設定して再起動したあと、VPN は健全な接続を示しているのにトレントがメタデータ取得のまま止まるのを半日眺めて過ごした。設定そのものは間違っていなかった。名前が古くなっていたのだ。macOS はサービスが起動するたびに utun 番号を割り当てるので、前の週に正しかった utun4 はもう存在しないトンネルを指しており、クライアントはルートのないデバイスにソケットを結びつけていた。以下の手順が現在使っているものである。実行中のトンネルからインターフェースを読み取り、クライアントで選択し、セッションを再起動し、最後に転送と意図的な切断でバインドを証明する。
詳細設定を開き、インターフェースの項目を探す
qBittorrent のウィンドウで Cmd+, を押して環境設定を開き、詳細設定ページへ移動する。重要なのは Network Interface という項目である。ここにはシステムのインターフェース名が並び、既定では Any Interface になっている。つまり、クライアントが開くソケットごとにオペレーティングシステムが経路を選ぶ。プロジェクトの オプション解説 がこの項目と既定値を説明しており、中に入る名前は同じでないものの、どのプラットフォームでも同じ設定である。
ここでつまずく点が二つある。一覧に表示されるのは en0、en1、utun0 から utun9 といったデバイス名で、VPN 提供元の製品名は決して出てこない。そのため、まともな選択をする前に名前の対応を知っておく必要がある。もう一つは、選択が BitTorrent セッションの開始時に適用されることで、OK を押した瞬間ではない。保存されたように見える変更が、古いバインドのまま動いていることがある。
アプリケーションは Cmd+Q で正しく終了し、開き直す前にプロセスが消えたことを確認する。ウィンドウを閉じるだけでは隠れるだけで、隠れたクライアントはセッション、待ち受けポート、古いインターフェースを保持し続ける。
pgrep -fl qbittorrentVPN が実際に持っているインターフェースを見つける
まず提供元のクライアントで VPN に接続し、そのあとクライアントのメニューではなくシステム側の表示を読む。以下のコマンドは各インターフェースをアドレス付きで一覧し、どれをシステムが有効と見なしているかを示し、ルーティングテーブルを出力する。探すのは、提供元が配るプライベート範囲を持つ utun デバイスである。
ifconfig -a | grep -A4 '^utun'
scutil --nwi
netstat -rn -f inet | head -n 5三つの読み取りでどのデバイスがトンネルか分かる。utun の項目には VPN のプールに属する inet アドレスが必要である。scutil --nwi はシステムがどのインターフェースを有効と見なし、どれが主要かを示す。netstat -rn は既定ルートの向きを示し、utun にアドレスがあるのに既定ルートがまだ en0 を向いているなら、トンネルはすべての通信を運んでおらず、バインドが後でどう働くかが変わる。
二つのトンネルが同時に存在しうる場合、たとえば仕事用と個人用のプロファイルでは、両方の utun デバイスが現れ、役に立つのは片方だけである。バイトカウンターが決め手になる。カウンターを記録し、ページを読み込むか小さな転送を始めて、どちらが動いたかを見る。
netstat -ib | grep utun番号を安定したものと見なしてはいけない。再接続で同じトンネルに別の utun 名が付くことがあり、iCloud や Continuity のサービスが VPN 接続のはるか前に utun0 を押さえていることもある。
バインドをトンネルの範囲に合わせる
この項目はデバイスを結びつけるだけで、それ以上のことはしない。VPN が 0.0.0.0/0 を utun に流すフルトンネルなら、そのデバイスへのバインドでピア接続とトラッカー要求のすべてが VPN を通る。 VPN が一部のサブネットだけを流す分割トンネルなら、utun へのバインドはピアの通信を、それらのピアへの経路を持たないデバイスへ送るため、転送は漏れずに停止する。どちらの結果も Any Interface より安全だが、クライアントが動き続けるのは片方だけである。クライアントの外は何も変わらない。ブラウザや他のアプリは独自の経路を保つので、すべてのアプリを対象にする要件は VPN 側で強制する必要がある。
何かを選ぶ前に状況を読む。
| What you see | What it means for the bind |
|---|---|
| A utun with a provider address and the default route pointing at it | Full tunnel; the bind covers peer and tracker traffic |
| A utun with a provider address but the default route still on en0 | Split tunnel; the bind will stall transfers unless the provider routes 0.0.0.0/0 |
| No utun carrying a provider address | The VPN is down or connects on demand; bring it up before selecting |
| A utun number that changed since the last session | The saved name is stale; reselect and restart |
アドレスファミリーも重要である。IPv4 だけを割り当てる提供元では、バインドしたインターフェースに IPv6 アドレスがなく、IPv6 のピアは Wi-Fi から漏れ出すのではなく失敗する。別の話として、ソケットのバインドは名前解決を固定しない。トラッカーのホスト名は macOS のリゾルバで解決され、これは選択したデバイスではなくシステムの DNS 設定に従う。
正しく見える選択が失敗する三つの形
一つ目は再起動しないこと。項目は utun4 を示し、設定は構成済みに見えるのに、試験転送は Wi-Fi から出ていく。動いているセッションが古いバインドを保っているからである。完全に終了し、pgrep で確認し、開き直してから転送をやり直す。
二つ目は再接続後の古い名前である。結びつけたデバイスが消えるとピア接続が失敗し、クライアントはインターフェースが消えたという明確なメッセージではなく、トラッカーのエラーを報告しがちで、死んだトレントのように見える。ifconfig を読み直し、新しい名前を選び、再起動する。
三つ目は、バインドが閉じた形で失敗すると決めつけること。インターフェースの選択は、ソケットをデバイス名に結びつけるようシステムに求めるだけであり、その名前がない場合や再利用された場合に何が起きるかを設定画面は保証しない。次の節の切断テストだけが、意味のある証拠である。
実際の転送と切断で検証する
実行を許されている転送、たとえば Linux ディストリビューションのイメージを使い、VPN に接続した状態で開始する。前後でインターフェースごとのカウンターを見て、VPN クライアント自身のデータカウンターと比べる。ピア一覧が埋まるあいだ、両方が一緒に増えるはずである。
netstat -ib | grep utun
pgrep -fl qbittorrentそのあと VPN をそれ自身の画面から切断し、転送を観察する。ピアは離れていき、トンネルが落ちてまもなく新しい接続は失敗するはずだ。速度がそのまま続くなら、バインドは効いておらず、ファイアウォールではなく再起動の手順に戻ることになる。
再接続して選択した名前をもう一度確認する。トンネルが別の utun で戻ってくることがあるからだ。トンネルの種類、インターフェース名、VPN が落ちたときの期待される挙動を短く記録しておけば次のセッションが楽になる。この設定はマシンごと、提供元ごとのもので、クライアントの更新にも VPN アプリの変更にも耐えない。