Mullvadのexit IPは驚くほど識別可能
(tmctmt.com)- Mullvad は1台のサーバーに複数のexit IPを持つが、WireGuardキーに基づいて決定論的に割り当てられるため、接続のたびにランダムには変わらない
- 9台のサーバーでpubkeyを繰り返し変更して集めた 3,650件のデータポイント は、理論上可能な8.2兆通りの組み合わせのうち、わずか284通りにしか割り当てられなかった
- 各サーバーのexit IPはプール内の近い パーセンタイル位置 に置かれ、ある組み合わせは複数サーバーでおおむね81パーセンタイルに対応していた
- 原因は、pubkeyやトンネルアドレスをseedにし、プールサイズを上限として seedベースのRNG でexit IPのindexを選んでいる構造にあるとみられる
- IPログのfloat範囲が重なると、異なるMullvadサーバーを使っていてもアカウント間の相関付けが可能になり、匿名性リスク が高まる
Mullvadのexit IPがフィンガープリント用ベクトルになる仕組み
- Mullvad は1台のサーバーに複数のexit IPを提供しており、同じサーバーに接続した2人のユーザーでも、通常は互いに異なる公開IPを受け取る
- サーバー数は 578台 で、Proton VPNの20,000台より少ないため、1つのIPにユーザーを集中させない垂直スケーリングは、過度なIPブロックや速度制限を避けるうえで有利だ
- しかし、サーバーに接続するたびにexit IPがランダムに変わるわけではなく、WireGuardキーを基に決定論的に選択される
- WireGuardキーは1〜30日ごとにローテーションするが、サードパーティクライアントではローテーションされない
- サーバーごとに独立した固定exit IPが割り当てられるなら、いくつかのサーバーでのIP組み合わせだけで、他のMullvadユーザーと区別できる可能性がある
9台のサーバーで観測されたexit IPの組み合わせ
- pubkeyを繰り返し変更 しながら、9台のサーバーのexit IPを収集するスクリプトを一晩実行し、3,650件のpubkeyデータポイントを得た
- 各サーバーのexit IP範囲は次のように観測された
| Hostname | Start IP | End IP | # IPs |
|---|---|---|---|
| au-syd-wg-101 | 103.136.147.5 | 103.136.147.64 | 60 |
| cl-scl-wg-001 | 149.88.104.4 | 149.88.104.14 | 11 |
| de-ber-wg-007 | 193.32.248.245 | 193.32.248.252 | 8 |
| dk-cph-wg-002 | 45.129.56.196 | 45.129.56.226 | 31 |
| fi-hel-wg-201 | 185.65.133.10 | 185.65.133.75 | 66 |
| us-lax-wg-001 | 23.234.72.36 | 23.234.72.126 | 91 |
| us-nyc-wg-602 | 146.70.168.132 | 146.70.168.190 | 59 |
| us-sjc-wg-302 | 142.147.89.212 | 142.147.89.224 | 13 |
| za-jnb-wg-002 | 154.47.30.145 | 154.47.30.155 | 11 |
- これらのサーバーのプールサイズを掛け合わせると、8.2兆通り超 のexit IP組み合わせがあり得るように見える
- 実際にテストされたすべてのpubkeyは、そのうち284通りの組み合わせのいずれかにしか割り当てられなかった
- 可能な組み合わせ数に比べて観測された組み合わせ数が極端に少ないことは、サーバーごとのIP選択が独立していないことを示す手がかりになる
異なるIPが同じパーセンタイルに置かれるパターン
- exit IPは、プールの開始IPからどれだけ離れているかで 数値上の位置 を計算できる
- たとえば
au-syd-wg-101における103.136.147.53は、103.136.147.5から数えると1-based indexで49になる - 観測された組み合わせのIP位置を各サーバーのプールサイズで割ると、異なるサーバーでもほぼ同じ 比率 が現れる
| Server | IP | Position | Pool size | Ratio |
|---|---|---|---|---|
| au-syd-wg-101 | 103.136.147.53 | 49 | 60 | 0.816 |
| cl-scl-wg-001 | 149.88.104.12 | 9 | 11 | 0.818 |
| de-ber-wg-007 | 193.32.248.251 | 7 | 8 | 0.875 |
| dk-cph-wg-002 | 45.129.56.220 | 25 | 31 | 0.806 |
| fi-hel-wg-201 | 185.65.133.63 | 54 | 66 | 0.818 |
| us-lax-wg-001 | 23.234.72.109 | 74 | 91 | 0.813 |
| us-nyc-wg-602 | 146.70.168.179 | 48 | 59 | 0.813 |
| us-sjc-wg-302 | 142.147.89.222 | 11 | 13 | 0.846 |
| za-jnb-wg-002 | 154.47.30.153 | 9 | 11 | 0.818 |
- 各IPはそのプール内の近いパーセンタイルに置かれており、上の例はおおむね 81パーセンタイル に相当する
- このパターンのため、Mullvadは全サーバーで互いに隣接した位置のexit IPばかりを割り当てているように見える
原因はseedベースの乱数選択とみられる
cl-scl-wg-001とza-jnb-wg-002は、観測された284通りのIP組み合わせ全体で常に同じIP indexを共有していた- この2台の共通点は プールサイズ11 であり、同じseedと同じboundsを持つ乱数呼び出しが同じ結果を返す構造と一致する
- 静的なseedでRNGを初期化したあと、同じ範囲で乱数を引けば同じ結果が繰り返される
- Mullvadはpubkeyまたはトンネルアドレスをseedにし、プールサイズを上限値として seedベースのRNG でexit IP indexを選んでいるように見える
- boundsが変わってもRNGのエントロピープールは影響を受けず、Rustでは最初の呼び出しで同じfloatが生成され、それにboundsが掛けられる方式と整合する
- この動作は
min + round((max - min) * float)のように単純化して考えられるが、かなり単純化した表現かもしれない - この性質のため、プールサイズが異なっても、同じseedから得られたfloatが各サーバープール内の近い比率の位置にマッピングされる
- Mullvadクライアント はRustで書かれているため、バックエンド言語もRustである可能性はあるが、これはクライアント実装に基づく推測にとどまる
random_rangeがboundsの変化に応じてどう動作するかを正確に予測するのは難しく、boundsの増加がエントロピーと混ざって別の値を生むと考えがちだが、実際の観測結果はそうではない
IPログの相関によって生じる匿名性リスク
- 特定のIP組み合わせに対して取り得るfloat値の最小値と最大値を推定するツールとして、mullvad-seed-estimator が提供されている
- スクリーンショット中の特定のIP集合は 0.2909〜0.2943 のfloat値として解釈され、その差は0.0034である
- これはMullvadユーザーのうち 0.34% がこのIP群を共有することを意味し、アクティブユーザーを100,000人とざっくり見積もると340人に相当する
- 当初予想したほど一意ではないものの、99%以上の精度 は決して低くない
- たとえばフォーラム管理者が、前日にBANしたユーザーのsockpuppetと疑われる新規アカウントを確認する際、両アカウントが異なるMullvadサーバーを使っていても、IPログが
0.4334 - 0.4428と0.4358 - 0.4423のように重なるfloat範囲を持っていれば、同一人物である確率は99%を超える - データ漏えいや法的手続きによって入手したIPログにも同じ相関手法を適用すれば、VPNの背後にいるユーザーが匿名性を失う可能性がある
保護方法
- 1つのpubkeyでサーバーを複数回切り替えないこと が推奨される
- Mullvadアプリでログアウトして pubkeyを強制ローテーション できる
1件のコメント
Hacker Newsのコメント
Mullvadで働く共同CEO兼共同創業者です。記事で述べられている挙動の一部は意図したもので、一部はそうではなく、原因もブログ記事の説明と完全に同じではありません。
緩和策として、意図していない挙動に対するパッチをすでにインフラの一部でテスト中なので、今日再現を試みると結果が紛らわしくなるかもしれません。
意図した挙動についても受け入れ可能か再評価する予定で、そこには複数のプライバシー要素とユーザー体験の間のトレードオフがあります。
この理解は1時間前に把握して以降、運用チームと即座に対応を議論し、この文章を書きながら整理した現時点の判断なので、変わる可能性があります。
セキュリティ研究をしている方には、セキュリティ・プライバシー問題を見つけたとき、たとえすぐ公開する予定でも、まず管理者やベンダーに知らせてほしいです。
mullvad tunnel getで確認でき、mullvad tunnel set rotation-intervalで変更できます。記事で好まれていた緩和方法もこれです。個人的には半固定IPは大きな問題ではありません。目的はISPや政府によるネットワークレベルの監視を防ぐことであり、一部の事業者は固定IPv4を機能として販売してもいます。
プライバシーVPNでは、IP空間が小さいほど、外部から見える1つのIPの背後により多くのユーザーを混ぜられるので利点もあります。DAITAのようにトンネルへダミートラフィックを入れる技術とマルチホップの入口を組み合わせれば、一日中NetFlowを見続ける監視者に対して実際により難しくできると考えています。
中核的な発見であるサーバー間のIPプール内の位置相関は、実際には意図していない挙動を含んでいるようです。Mullvadチームと一緒に働いた経験から見て、すぐ対処されると思います。
異なる「身元」が欲しいなら、WireGuardキーをローテーションするか、異なるキーを使う必要があります。
記事では「サーバーへ接続するたびに出口IPはランダムではなくWireGuardキーを基準に決定的に選ばれ、そのキーは1〜30日ごとにローテーションされる。サードパーティクライアントを使うとローテーションされない」とありましたが、WireGuardは設計上https://www.wireguard.com/protocol/コネクションレスなプロトコルなので接続という概念はなく、トラフィックが流れるときにだけ2〜3分ごとに再キーイングのハンドシェイクがあるだけです。
同じWireGuardキーでも「接続」するたび、たとえば再キーイングのハンドシェイクごと、あるいは15分ごとに出口IPが変わるなら、トランスポート層ではQUICを除くほぼすべてのトンネル内接続が切れて張り直しになり、アプリケーション層では「同じCookieで新しいIP」を疑うサービスがログアウト、CAPTCHA、リスクスコアの増加を引き起こすでしょう。
どちらもユーザー体験が悪く、さらに悪いことに「この人はずっと別のIPから再接続しているからMullvad利用者だ」といった形で、ユーザーをより固有にフィンガープリントできてしまう可能性があります。
「フォーラム管理者が前日にブロックしたユーザーの別アカウントではないかと疑ってIPログを見たところ、異なるMullvadサーバーを使っていたのに、2つのアカウントが重なる浮動小数点範囲 0.4334〜0.4428 と 0.4358〜0.4423 にマッピングされ、99%を超える確率で同一人物とみなせる」という例は、情報機関がVPNを設計するならこう作りそうだという印象を与えます。
しかもこの方式はユーザーが異なるサーバーを選ぶことに依存しているので、なおさらそうする理由がありません。
私にとっては大きな問題で、複数のVPN出口ノード間での相関分析を可能にしますが、それだけです。自動的にユーザーを識別できるようにするわけではありません。
ただし識別の難易度は大きく下がり、要求条件は依然として高いままです。早く修正されてほしいです。
「ハッシュのような機微な値で作ろう」という類いのミスが、しかもMullvadで、いまだに起きるとは信じがたいです。単にランダム化すればよかったのではと思います。
もちろん他の情報機関もありますが、最も懸念すべきなのはそこです。直接運営しているか、そういうアイデアを知って真似しているか、あるいは提携機関が運営するサービスへのアクセス権を持っているはずだからです。でなければ私への脅威ではないでしょう。
また、Mullvad利用者がVPN経由で匿名性を剥奪された公開事例はなく、代わりに別のオペレーショナルセキュリティの失敗で特定された例しか知られていません。もし情報機関がこの能力を持っていたなら、ほぼ20年間データを持ちながら使わなかったことになり、信じがたいです。
記事の数字だけでどうやって「99%を超える確率」が出てくるのか分かりません。最初のブロックIPのシードと2番目のシードがどちらも 0.4423〜0.4358 の範囲にあると強く仮定しても、この範囲はMullvad利用者全体の0.65%を含むという意味でしかありません。
ユーザーが10万人なら650人で、「容疑者」を99%以上除外したというだけで、複数の出口IPにまたがって1人の個人を99%以上の精度で識別したことにはなりません。
ベイズ的に見れば、潜在シードの重なりは2つのIPが同一人物、少なくとも同じMullvadアカウントである強い証拠になりますが、筆者が言っているのはそういうことではないように見えます。
たいていの小規模Webサイトではかなり強い証拠になります。
VPNの目的には、訪問先サイトに対してユーザーを匿名化することは含まれないので、Mullvadが固有の出口IPを強制していないからといって驚くことではありません。匿名性を望むユーザーはTorのようなネットワークを使うべきです。
公開VPNを使うなら、誰がリクエストを送ったのか、終端IPを含めて誰にも分からないことを望むはずです。
その理屈だとVPNはTorrentに使うべきではないことになります。終端IPについて匿名化してはいけないという意味になるからです。しかし実際にはTorrentで非常によく機能します。
プライベートVPNの話なら、Mullvadはそうではありません。
長い間Mullvadを使ってきましたし、私の国で合法である限り、自分の名前が記載されたクレジットカードでMullvad VPNサービスを買い続け、使い続けるつもりです。
VPNは100%匿名ではなく、そう設計されてもいません。代わりに、法律を守る成人にある程度のプライバシーを提供するためのものです。
ほとんどの人は、同僚や近所の人に自分の私生活、好きなもの、買うもの、することを知られると気まずいでしょう。だからほとんどの人はプライバシー保護のためにVPNを使うべきです。
定義上「ほとんどの人」はオンラインで100%の匿名性を望んだり期待したりしておらず、個人生活や人間関係において少しのプライバシーを望んでいるだけです。
VPNは、オンライン犯罪を行いながら政府から100%匿名でいたい犯罪者を守るものではなく、そのつもりもありません。この区別は重要です。「ほとんどの人」は犯罪者ではなく、Mullvadや他のVPNプロバイダーにそのような非現実的期待をしていません。
この論理だけで報告を退けることはできません。発見自体は依然として妥当です。
欠けている点があります。Mullvadに連絡したのか気になります。セキュリティチームがどう対応したかも見られていたら興味深かったでしょう。
後になって、このコメントを書いたことを後悔しました。不要でしたが、今削除すると変に見えそうです。
人々がVPNをTorに近いものだと期待しているのは驚きです。
そう言い換えると筋が通らないように見えますし、出口ノードを支配すればTorユーザーでさえ匿名性を剥奪できることも考える必要があります。
「出口IPは接続するたびにランダム化されるのではなくWireGuardキーを基準に決定的に選ばれ、このキーは1〜30日ごとにローテーションされる。サードパーティクライアントを使うと決してローテーションされない」という部分が少し分かりにくいです。
リポジトリに方法が詳しく書かれているなら、サードパーティが標準アプリクライアントのようにキーのローテーションをできないようにしているものが何なのか分かりません。
筆者はよく見つけたし、Mullvadのミスだったというのも十分あり得ます。こんなに単純なことが見逃されていたのはかなり衝撃的ですが、自分でも見落としていたかもしれません。
複数サーバー間のIP相関を除いて考えると、最初はなぜ1つのサーバー内でユーザーIPを安定させるのかも疑問でした。しかし、他のVPNは通常サーバーごとにIPが1つなので、それを模倣しているのだという筆者の説明を見ると納得できます。
ユーザーがあるサービスにアクセス可能なサーバーを見つけた場合、再びそのサーバーへ接続したときに同じIPを受け取り、再び動作する可能性があるという利点があります。
ただし複数サーバー間のIP相関は、
rand.seed(user_pub_key + server_id)のような形で修正すべきです。IPinfoで働いています。私たちはVPN検知の事業をしていますが、正直に言ってMullvadについては善意に解釈したいです。
私たちのようなIPジオロケーション提供者に不正確なジオロケーション情報を提出しようとしなかったVPNプロバイダー3社のうちの1社がMullvadでした。この問題も修正するはずだと確信しています。