OONI 如何分辨壞掉的量測資料:從啟發式規則到匿名憑證¶
本文是 anoni.net 對下面這篇 OONI 工程文章的導讀與摘要,帶你逐節看懂原文在做什麼,不是逐字翻譯。原文另有約 20 張統計圖與多份完整資料表,想看數據細節請直接讀原文:
很多人靠 OONI 的公開資料集,判斷「某個網站在某個國家連不連得上」,anoni.net 自己的台灣 ASN 涵蓋觀測也建立在同一份資料上。只要有人往裡面灌假資料,或裝置設定錯誤產生誤導性的紀錄,這份資料的可信度就會被稀釋。OONI 在最近一篇工程文章1裡完整說明,他們如何找出這些壞掉的量測,以及新上線的匿名憑證(anonymous credentials)系統如何在不儲存個資的前提下擋掉濫用。這套「不留個資也能評估誰值得信任」的做法,本身就是一個值得社群參考的隱私工程範例,後面第五節會回到這點。
OONI(Open Observatory of Network Interference,開放網路干擾觀測站)是一個全球的網路審查觀測專案,手機 app OONI Probe 會連上一份網站清單,回報每個網站在當地連不連得上,結果一律進到公開資料集。任何人都能下載這份資料做分析,好處是開放,代價是任何人也都能往裡面送資料。這篇文章要回答的問題,就是在開放投稿的前提下,如何辨認並過濾掉品質有問題的量測。
這篇文章想解決的問題¶
OONI 想先用手上已經有的資料,建立一套辨認壞量測的基準,再看新的匿名憑證系統能把這個基準往上推多少。這裡說的啟發式(heuristic)是一組簡單、成本低的判斷規則,不追求百分之百準確,先用幾條經驗法則把可疑的量測篩出來。全文分成三大塊:先用這些簡單規則檢查既有資料能揪出多少問題(既有啟發式與四類發現),再想能補上哪些更進階的規則(新啟發式),最後處理找到壞資料之後要用什麼機制因應(緩解策略與匿名憑證)。
一、既有的指標與啟發式(Existing metrics and heuristics|Approach & Methodology)¶
這一節先不動用任何新技術,只問一件事:光靠 OONI 現在就收得到的資料,能不能認出壞掉的量測?他們挑了四個不需要犧牲使用者隱私的檢查角度:IP 地理位置對不上、量測數量暴衝、時間戳記兜不攏、作業系統與版本資訊互相矛盾。每個角度原文都附了但書(caveat),說明什麼情況下這個訊號會誤判。例如探針(probe)內建的 GeoIP 資料庫可能過期,導致 probe_cc(探針回報的國碼)本來就會跟真實 IP 對不上,分析時要先把這種正常誤差濾掉。這一節是後面所有發現的方法論基礎。
二、四類異常的實際發現(Assessment & Findings)¶
把上面四個角度實際套到資料上,得到四組發現。
IP 地理位置對不上¶
OONI 在 2025 年 3 月 19 到 21 日,於探針呼叫 /api/v1/check-in 端點時記錄 log,比對探針自己回報的國碼、ASN(自治系統編號)跟收集端看到的真實出口 IP。16,139 筆樣本裡有 1,196 筆對不上,約 7.41%。原文列出最常見的 10 組國碼錯配(回報國碼對照真實 IP 所在國碼):
| 回報國碼 | 真實 IP 國碼 | 筆數 |
|---|---|---|
| US 美國 | CA 加拿大 | 89 |
| CA 加拿大 | RU 俄羅斯 | 49 |
| CZ 捷克 | US 美國 | 43 |
| BS 巴哈馬 | US 美國 | 36 |
| CA 加拿大 | US 美國 | 30 |
| CA 加拿大 | SG 新加坡 | 30 |
| CZ 捷克 | GB 英國 | 25 |
| CA 加拿大 | KH 柬埔寨 | 18 |
| AU 澳洲 | KH 柬埔寨 | 18 |
| US 美國 | DE 德國 | 16 |
追下去發現絕大多數對不上的來源是 VPN。出現最多的供應商是 Datacamp、Cloudflare、M247 這些已知的 VPN 機房,其中「回報加拿大、真實 IP 在俄羅斯」那 49 筆全部來自 Cloudflare,對應的是用 WARP 這類 VPN 的使用者。表格裡多數組合都是同一個道理,探針以為自己在 A 國,真實流量卻從 B 國的 VPN 出口冒出來。結論是這些不一致幾乎都跟 VPN 有關,沒有看到明顯可歸因於惡意竄改或探針設定錯誤的量。
量測數量暴衝¶
他們看每個探針在 1 分鐘內跑出多少筆量測,正常的平均是 8 筆,99 百分位是 54 筆。篩出每分鐘超過 200 筆的極端案例後,發現一個自稱 ooniprobe-react-os、並非 OONI 官方發行版本的用戶端。它只針對 probe_cc = CN(中國)送資料,以每分鐘 200 筆(相當於每秒 3 筆)的速度送出 web_connectivity 量測,速率遠超正常範圍。更反常的是,這個來源送出量測的速度比同地區其他探針還快,量這麼大卻沒有出現對應的網路瓶頸。另一個案例是緬甸在 2025 年 1 月 6 日出現的陣發性暴衝。
時間戳記兜不攏¶
比對量測開始時間 measurement_start_time 跟 measurement_uid 裡內含的時間戳,看有沒有「太晚上傳」或「時間來自未來」的紀錄。2025 年 3 月 2 日到 4 月 1 日這段,3,440 多萬筆量測裡只有 0.82% 有時間異常,多數是過去、集中在 Linux。原文依平台拆解如下,Linux 的異常率 2.16% 明顯高於其他平台:
| 平台 | 過去異常(>1h) | 未來異常(>1h) | 異常合計 | 該平台總量 | 異常率 |
|---|---|---|---|---|---|
| ios | 2,375 | 0 | 2,375 | 240,843 | 0.99% |
| windows | 34,192 | 24,938 | 59,130 | 10,503,040 | 0.56% |
| android | 21,132 | 5,509 | 26,641 | 10,389,320 | 0.26% |
| macos | 906 | 0 | 906 | 3,103,961 | 0.03% |
| linux | 185,322 | 7,908 | 193,230 | 8,947,716 | 2.16% |
這裡有一個很具體的例子:大量異常來自委內瑞拉同一個 ASN,OONI 聯絡上當地夥伴後發現,是那批裝置的時區被設錯了。把委內瑞拉排除後,Linux 的異常數字大幅下降,其他平台幾乎不變。設定錯誤就足以產生誤導性的紀錄,不必然是惡意。
作業系統與版本資訊互相矛盾¶
檢查軟體名稱跟平台兜不兜得起來,例如 software_name = ooniprobe-android 卻標成 iOS。找到 718 筆 Android 軟體跑在非 Android 平台上,其中一部分追出來是 OONI 團隊成員自己開發用的機器,另一部分又是前面那個中國來源的 ooniprobe-react-os。他們也列出幾個沒見過的軟體名稱(Vladhog、murakami-ooniprobe、MySorgenia、Dismantle 等),逐一查證是什麼來路。很多看起來可疑的資料,多半來自開發過程或第三方 fork,跟攻擊無關。
四類發現合起來給出一個讓人安心的結論:OONI 目前沒有在資料裡找到大量惡意污染,絕大多數異常來自 VPN、設定錯誤、開發機器或非官方分支。防禦機制要做,但威脅目前不是迫在眉睫的大規模攻擊。
這個結論對我們有直接意義。anoni.net 的台灣 ASN 涵蓋分析、Tor Relay 觀測點都建立在 OONI 公開資料上,看到源頭沒有被大量污染,用起來可以比較放心。同時這四類發現也提醒我們,讀 ASN 資料時 probe_cc 不等於當地實際的連線狀況(ground truth)。VPN 造成的地理錯配、時區設錯這類雜訊本來就存在,做分析時要記得先濾掉。
三、想再補上的新啟發式(New heuristics)¶
既有規則之外,OONI 想再加幾種更進階的偵測。定位一直是最大的難題,因為 GeoIP 資料庫由探針自己查、又會過期。他們考慮的補強包括:向手機作業系統取得行動網路的國碼與電信商代碼(MCC/MNC)、詢問作業系統的定位服務、或改在伺服器端做 IP 到地點的對照。每種做法原文都附了限制,例如伺服器端對照會被翻牆工具擋在中間、看不到真實 IP,問定位權限則可能引起使用者疑慮。另外還想加上網路層與協定層的異常偵測,例如從 TLS 交握的指紋認出中間人設備(像是改寫流量的防毒軟體)。
四、找到壞資料之後如何處理(Strategies for mitigating faulty measurements)¶
偵測只是第一步,接下來是處置。OONI 定了兩條原則。第一,最終判定一筆量測是不是壞資料,要有人類審查介入,避免自動化把好資料誤殺。第二,除非牽涉使用者隱私,否則絕不回頭修改已經送進來的資料。因為要有人類把關,處置只能在壞資料已經進入資料管線之後才做。可用的手段包括封鎖行為異常的假名(pseudonym)、對投稿做限流、動態調整某地區某時段能接受的投稿量、或輪換簽發金鑰。這裡的假名是匿名憑證系統給「同一個網路裡的一台探針」的識別,同一網路內固定、跨網路無法被串連,也對應不到某個人的真實身分,第五節會說明它如何做到。文章也誠實點出兩難:如果規定「只有半年以上的探針才能投稿」來擋 sybil 攻擊(大量假身分灌資料),也會連帶影響到正常新探針的投稿。
五、匿名憑證系統如何運作(Assessing the effectiveness of the solution)¶
匿名憑證系統是整篇的重點。先看「土法煉鋼」的做法會踩到什麼坑:給每個探針一個 ID、伺服器端做白名單。問題是就算隨機 ID,只要固定不變就足以辨識出單一探針,本身就是隱私災難,而且探針換一個新 ID 就能繞過,變成打地鼠。如何在不長期儲存個資的前提下,同時做到存取控制與信任評分,就成了這套系統要解決的核心矛盾。
這套機制用一個生活化的比喻就好懂。像酒吧門口只要你出示一張「證明我已成年」的證件,店員確認過關就好,不需要知道你叫什麼、住哪裡、生日是哪天。OONI 的憑證則用來證明另一組事情,這台探針的資歷夠老、投稿數量夠多。
憑證由伺服器簽發,只存在探針本地、不存在伺服器,也不會再次外傳。它用密碼學把探針的資歷(age)與投稿數(msm_count)編碼進去,而且只證明落在某個「區間」,例如「投稿超過 1000 筆」、「存在超過一週」,不透露精確值。用區間而非精確數字是刻意的設計,因為精確的投稿數幾乎是獨一無二的指紋,會反過來讓探針被認出來,粗略的區間才不會洩漏身分。
投稿時,探針用憑證產生一段零知識證明(一種只證明某件事為真、但不透露細節的密碼學方法),伺服器只看到這段證明、看不到底下的真實數值,就能判斷這筆量測符不符合存取規則,例如「這個國家、這個 ASN 的探針,要投稿滿 1000 筆才收」。信任分數還會鎖定在特定的國碼與 ASN 組合,一台探針在某個網路累積的信譽,不能跨到另一個網路使用,這正是為了防止有人在低門檻網路先養好憑證、再拿去攻擊別的網路。
具體走一遍會像這樣:一台全新的探針一開始資歷淺、投稿數低,很多嚴格規則都還進不去,只能先老實跑量測。每投一筆,伺服器在驗證通過後回一張更新過的憑證,把投稿數往上加一。日子久了、量累積夠了,這台探針跨過「滿一週」、「滿 1000 筆」的門檻,之後送的量測就能被標成 verified。整個過程裡,OONI 從頭到尾沒拿到這台探針的固定 ID,也沒存下它的任何個資。
那有人會問,既然憑證只存在探針本地,複製一百份不就能假裝成一百台各有信譽的探針?關鍵在前面說的網路內固定這個性質。同一個網路裡,同一份憑證推導出來的假名是同一個,複製再多份,在同一個網路裡仍然被看成同一台探針,不會變成一百個各自獨立的可信身分。OONI 也很坦白,光靠憑證不能完全解決 sybil 攻擊,徹底的防禦要靠應用層的手段,例如限制新帳號註冊速率、對每個區域的投稿量設上限。憑證的作用是提高攻擊成本,逼對手先養出一批夠老、送過夠多量測的探針,沒那麼容易。
每筆量測最後會被標成 verified、unverified 或 failed 三種狀態,資料使用者可以自己決定要採信到什麼程度。這套系統上線後,有些效果要長期觀察才看得出來。OONI 會持續追蹤 verified、unverified、failed 三類量測的比例變化,用來診斷是不是某次用戶端更新讓協定實作出現錯誤、或老探針沒更新。他們也會統計各協定版本的探針數量,以及在伺服器端跑一筆驗證要花多少時間,及早抓出效能退化。
回到社群的角度,這套系統對 anoni.net 讀者的價值不只在 OONI 自己。「如何在不儲存個資的前提下做存取控制與信任評分」是很多系統都會遇到的難題,OONI 用區間揭露、憑證只存本地、放棄精準封鎖來換取匿名性,這套取捨思路對關心隱私設計的人是很好的教材,也呼應我們社群個人隱私指引的主題。
小結:這份資料能不能放心用¶
OONI 的公開資料目前沒有被大量惡意污染,看到的異常多半來自 VPN、時區設錯、開發機器這類無心之過,可以放心繼續用它來理解台灣與各地的封鎖狀況。想更深入匿名憑證背後的密碼學,OONI 另有兩篇姊妹文可以接著讀:一篇談這套系統的設計需求2,一篇宣布系統上線3。
原文十個大節回顧¶
看完全文,這張表把原文十個大節的重點與關鍵數字收在一起,方便日後回查或跳讀。
| 原文大節 | 重點 | 關鍵數字或結論 |
|---|---|---|
| Existing metrics and heuristics|Approach | 用既有資料建立偵測基準 | 四個不犧牲隱私的檢查角度 |
| IP geolocation mismatches | 探針回報位置對照真實 IP | 7.41% 對不上,多數是 VPN |
| Measurement volume anomalies | 單一探針投稿速率暴衝 | 中國 ooniprobe-react-os 每秒 3 筆 |
| Timestamp inconsistencies | 量測時間戳前後兜不攏 | 0.82% 異常,委內瑞拉時區設錯 |
| Probe OS, version metadata | 軟體名稱與平台互相矛盾 | 718 筆,含團隊開發機 |
| New heuristics | 想再補上的進階偵測 | MCC/MNC、伺服器端 GeoIP、TLS 指紋 |
| Mitigation strategies | 找到壞資料之後的處置 | 人類把關、不回改、限流、擋 sybil |
| Naive solution | 土法煉鋼會踩的坑 | 固定 ID 就能去匿名,還會變打地鼠 |
| Anonymous credentials solution | 憑證式信任評分 | 區間揭露、只存本地、沒有固定 ID |
| Future validation | 長期驗證指標 | 追蹤 verified/unverified/failed 比例 |
名詞對照¶
原文用了不少 OONI 專有欄位名詞,這裡整理一份對照,方便對照原文閱讀。
| 名詞 | 說明 |
|---|---|
| 啟發式(heuristic) | 一組簡單、成本低的判斷規則,不追求完美,先把可疑的量測篩出來 |
| OONI Probe | OONI 的手機與桌面 app,會去連一份網站清單、回報每個網站在當地連不連得上 |
| probe(探針) | 執行量測的那台裝置或那支程式 |
probe_cc |
探針回報的國碼(country code) |
probe_asn |
探針回報的 ASN |
| ASN | 自治系統編號(Autonomous System Number),一段 IP 位址的管理單位,通常對應一家 ISP 或機構 |
msm_count |
該探針累積投稿的量測數(measurement count) |
| check-in 端點 | 探針開始量測前呼叫的 API,會回報自己的國碼與 ASN |
web_connectivity |
OONI 最常見的測試,測某個網站在當地連不連得上 |
| ground truth | 當地實際的連線狀況,拿來跟探針回報的資料對照的「真實答案」 |
| sybil 攻擊 | 用大量假身分灌資料、扭曲觀測結果的攻擊 |
| pseudonym(假名) | 匿名憑證下代表「同區域、同 IP」一群探針的識別,不是個人身分 ID |
| verified、unverified、failed | 匿名憑證系統給每筆量測的三種信任標記 |