推廣與翻譯匿名網路 Tor、Tails 與 OONI 觀測工具
「匿名網路社群 anoni.net」的核心文件系統。儲存庫裡有兩個目錄:對外的多語系文件網站,以及支撐它的共用腳本與 CI 檢查。
anoni-net-docs/
├── docs/ # MkDocs 多語系文件網站(zh-TW、zh-CN、en)
└── tools/ # 共用腳本:編輯標準掃描、前端測試、資料產生、部署
兩個目錄的授權不同,見下方「授權」一節。
文件站觀測頁用到的兩個工具在 2026-10 拆成獨立的 repo,commit 歷史一併帶過去:
| 工具 | repo | 授權 |
|---|---|---|
| Pulse:Tor 中繼監控系統,提供觀測頁圖表的 API | anoni-net/pulse |
MIT |
| ASN Coverage:OONI 觀測資料的 ASN 涵蓋率分析 CLI | anoni-net/asn-coverage |
GPL-3.0 |
基於 MkDocs Material 的多語系網站,提供正體中文、簡體中文與英文三個版本。
網站分區:
| 分區 | 內容 |
|---|---|
| 指南 | 概念、工具、場景、進階、報告五組。工具依「連線層」、「環境層」、「觀測層」、「日常隱私基本功」分類 |
| 在地脈絡 | 台灣的觀測資料與法規制度(個資法、VASP、揭弊者保護) |
| 小工具 | 在瀏覽器內執行的隱私工具:威脅模型盤點、密語產生、QR code 產生與讀取、metadata 清除、網址清理、隱形字元偵測、瀏覽器指紋示範 |
| 互動與呈現 | 洋蔥路由與會合點的動畫,以及 Tor 中繼地球儀 |
| 資訊更新 | 部落格與 Tor、Tails、Arti、OONI 的軟體更新日誌 |
| 社群 | 參與方式、翻譯流程、貢獻者百科、架設中繼與 onion 服務、讀懂觀測資料 |
| 關於我們 | 專案介紹、聯絡方式、離線內容管理 |
技術特點:
- 三語系內容分別存放於
docs/zh-TW/、docs/zh-CN/、docs/en/,各有一份 mkdocs 設定檔。預設語系 zh-TW 建在根路徑 - 外掛:
blog、rss、charts(Vega-Lite)、social(Open Graph 卡片)、privacy(建置時把 CDN 資源取回本地)、git-revision-date-localized、redirects - 小工具區的運算全部在瀏覽器內完成,不送出使用者輸入。對應的守門測試放在
tools/ - PWA 與離線閱讀:
docs/zh-TW/sw.js提供離線路徑,建置時由docs/hooks/offline_index.py產出各語系的offline-index.json,離線內容管理頁據此列出可下載的章節 - 三種部署目標:Clearnet(S3 加 Cloudflare)、Tor Onion(同一個 bucket 的另一個 prefix)、IPFS(IPNS 名稱指向最新版本)
跨子專案的腳本,多數零外部相依,由 GitHub Actions 在 PR 觸發。
| 群組 | 內容 |
|---|---|
| 編輯標準 | docs_style_lint.py 把社群首頁寫作風格規範可機器判斷的部分做成檢查。三語系都掃,中英各一組規則。細節見 tools/README.md |
| 前端守門測試 | 小工具區每一支 js 的行為驗證:取樣與熵、QR code 編碼往返、指紋示範頁不送出資料、網址清理不誤刪必要參數、隱形字元偵測的誤判案例。分析事件另有白名單測試,擋住搜尋詞之類的內容被送出 |
| 離線與 PWA | service worker 的離線路徑、語言偏好導向、離線索引分組、離線內容管理頁的介面,以及預快取清單與建置產物的比對 |
| 建置一致性 | check_theme_assets.py 比對 overrides/base.html 與 sw.js 寫死的主題資產雜湊與實際安裝的版本,升級 mkdocs-material 漏同步時會擋下來 |
| 地球儀資料 | gen_*.py 產生 docs/zh-TW/games/tor-network/ 的靜態 JSON,publish_games_data.sh 在正式機重生並發布會持續變動的那幾份 |
| 互動與版面檢查 | headless Chrome 執行的手勢、取景與版面檢查 |
| 部署 | cf_purge.py 分批並行清除 Cloudflare 快取,s3_restore_mtime.py 讓內容沒變的檔案被 aws s3 sync 跳過 |
- Python: 3.12+
- 套件管理: uv
- Node.js: 用於
tools/的前端測試(可選,僅需標準庫)
curl -LsSf https://astral.sh/uv/install.sh | shcd docs
uv sync
source .venv/bin/activate
mkdocs serve # 預設語系 zh-TW,http://127.0.0.1:8000三語系的建置驗證用 run_*.sh,各自 export 該語系需要的環境變數再建置到 output/:
sh run.sh # zh-TW(預設語系,建在根路徑)
sh run_zh-cn.sh # zh-CN
sh run_en.sh # en直接執行 mkdocs build -f mkdocs_en.yml 會因為 DOCS_DIR 之類的環境變數落回預設值而產生假警報,驗證三語系請走這三支腳本。build_docs_anoni*.sh 是正式機的部署腳本,內含伺服器專用路徑,本機不要執行。
# 編輯標準自檢,CI 對變更的 Markdown 執行同一支
python3 tools/docs_style_lint.py docs/zh-TW/<變更的檔案>.md
# 改到小工具或 service worker 時,一併執行對應測試
node tools/test_sw_offline.mjsmain 是開發分支,docs 是建置觸發分支。PR 合併進 main 只代表內容進了儲存庫,正式站讀取的來源是 S3,需要推 docs 分支才會建置並上傳:
git push origin origin/main:refs/heads/docsworkflow 執行完,clearnet 與 onion 兩份產物就上線。沒有自動把 main 同步到 docs 的機制,屬於刻意設計:要發布哪些內容、什麼時候發布,由人決定。
推了 docs 也不一定會建置。觸發路徑限定在會改變產物的檔案(docs/**、根目錄的 BECOME_ANONI*.md、tools/cf_purge.py 與 tools/s3_restore_mtime.py 及兩者的測試、.github/workflows/build_docs.yml 自己)。只動 tools/ 其他檔案時推 docs 不會建置,需要重新建置時從 Actions 頁面用 workflow_dispatch 手動觸發。
| Workflow | 觸發 | 內容 |
|---|---|---|
BuildDocs |
push docs 分支、手動 |
建置三語系、處理 Open Graph 圖片、以 aws s3 sync --delete 上傳 clearnet 與 onion 產物、由 cf_purge.py 清除這次產出網址的 Cloudflare 快取 |
docs-style-lint |
PR | 對變更到的 Markdown 與小工具 UI 字串執行編輯標準掃描。error 級擋 merge,warn 級只標 annotation |
invisible-chars |
PR | 全站隱形字元掃描。零寬字元、BOM、Markdown 裡的不斷行空白會擋 merge |
tools-tests |
PR | tools/ 底下零相依的測試,執行完不到十秒 |
games-checks |
PR | Tor 中繼地球儀的互動與版面檢查(headless Chrome) |
- 線上文件: https://anoni.net/docs/
- GitHub Repo: https://github.com/anoni-net/docs
- Tor Onion:
docs.anoninetru5tflukgfaehun7q6khowgmymcff3gtk5oyesqazhmfxtyd.onion - IPFS 閘道: https://ipfs.anoni.net/(社群自架,pin 的做法見鏡像文件)
- 詳細開發指南: 請參閱 AGENTS.md
我們歡迎任何形式的貢獻。第一次來,照下面四條路徑找到自己的起點:
- 看到錯字或失效連結 → 開 文件錯誤 Issue,或小修直接送 PR。
- 想翻譯一篇文章 → 開 翻譯認領 Issue,流程見中文化與文件翻譯。
- 想提新主題、補在地案例,或推薦來源 → 用內容提案或來源建議 Issue。
- 想參與推廣、活動或維運 → 到 Matrix 社群 Public Space 打聲招呼。
工具操作與安全情境類內容(tools、scenarios、advanced)由維護者技術審核才合併,其餘內容輕量審核。寫作風格的單一來源是社群首頁的寫作風格規範,檔名、PR 流程與翻譯規範見貢獻者百科,送 PR 前可先執行 tools/docs_style_lint.py 自檢。完整入門見如何參與與認領主題。流程、分支與 CI、授權見 CONTRIBUTING.md,互動規範見行為準則。
找人:Matrix Public Space(帳號申請來信 whisper@anoni.net)、GitHub Discussions、加密共筆 Cryptpad。
本儲存庫內不同目錄適用不同授權,請以各目錄的 LICENSE 與下表為準(並非所有程式碼皆為 MIT)。
| 範圍 | 授權 |
|---|---|
docs/ 網站內容(Markdown 等) |
CC-BY 4.0 |
tools/ 腳本與測試 |
MIT(不含 tools/data/) |
docs/zh-TW/games/tor-network/ 的外部資料 |
各自沿用原始授權,清單見 NOTICE |
- 根目錄
LICENSE為 CC-BY 4.0 全文,作為文件與網站內容之預設授權標示。 - 地球儀的外部資料中,
ooni.json為 CC BY-NC-SA 4.0,禁止商業使用,重製前請先看NOTICE。 tools/data/放的是資料來源檔,座標部分取自 OpenStreetMap 採 ODbL,不在tools/的 MIT 範圍內,見NOTICE。
Copyright © 2023-2026 anoni.net Docs Project
Promoting and translating Tor, Tails, and OONI measurement tools for anonymous networks
The core documentation system for the "Anonymous Network Community anoni.net". The repository holds two directories: the public multilingual documentation site, and the shared scripts and CI checks that support it.
anoni-net-docs/
├── docs/ # MkDocs multilingual documentation site (zh-TW, zh-CN, en)
└── tools/ # Shared scripts: style linting, frontend tests, data generation, deployment
The two directories are under different licenses. See the License section below.
The two tools behind the docs site's measurement pages were split into their own repositories in 2026-10, with their commit history:
| Tool | Repository | License |
|---|---|---|
| Pulse: Tor relay monitoring, serving the API behind the measurement charts | anoni-net/pulse |
MIT |
| ASN Coverage: a CLI for ASN coverage analysis of OONI measurements | anoni-net/asn-coverage |
GPL-3.0 |
A multilingual site built on MkDocs Material, published in Traditional Chinese, Simplified Chinese, and English.
Site sections:
| Section | Content |
|---|---|
| Guides | Concepts, tools, scenarios, advanced topics, and reports. Tools are grouped by connection layer, environment layer, measurement layer, and everyday privacy basics |
| Local Context | Taiwan-specific measurement data and regulation (PDPA, VASP, whistleblower protection) |
| Utilities | Privacy tools that run entirely in the browser: threat-model inventory, passphrase generator, QR code generator and reader, metadata stripper, URL cleaner, invisible-character detector, browser fingerprint demo |
| Interactive | Onion routing and rendezvous animations, plus the Tor relay globe |
| Updates | Blog plus changelogs for Tor, Tails, Arti, and OONI |
| Community | How to participate, translation workflow, contributor handbook, running relays and onion services, reading measurement data |
| About | Project introduction, contact, offline content manager |
Technical features:
- Content for the three locales lives in
docs/zh-TW/,docs/zh-CN/, anddocs/en/, each with its own mkdocs config. The default locale zh-TW is built at the site root - Plugins:
blog,rss,charts(Vega-Lite),social(Open Graph cards),privacy(fetches CDN assets locally at build time),git-revision-date-localized,redirects - Everything in the utilities section computes in the browser and sends no user input anywhere. The matching guard tests live under
tools/ - PWA and offline reading:
docs/zh-TW/sw.jshandles the offline path, anddocs/hooks/offline_index.pyemits a per-localeoffline-index.jsonat build time that the offline content manager reads to list downloadable sections - Three deployment targets: clearnet (S3 plus Cloudflare), Tor Onion (a second prefix in the same bucket), and IPFS (an IPNS name pointing at the latest build)
Cross-subproject scripts, mostly dependency-free, triggered by GitHub Actions on pull requests.
| Group | Content |
|---|---|
| Style linting | docs_style_lint.py turns the machine-checkable parts of the writing style rules on the community site into a linter. It scans all three locales with separate Chinese and English rule sets. See tools/README.md |
| Frontend guard tests | Behavioral checks for every script in the utilities section: sampling and entropy, QR code encode/decode round-trip, the fingerprint demo sending nothing, the URL cleaner not stripping required parameters, false-positive cases for invisible-character detection. Analytics events have their own allowlist test that keeps content such as search terms from being sent |
| Offline and PWA | Service worker offline paths, language preference routing, offline index grouping, the offline content manager UI, and a precache-list comparison against build output |
| Build consistency | check_theme_assets.py compares the theme asset hashes hardcoded in overrides/base.html and sw.js against the installed version, catching a missed sync after a mkdocs-material upgrade |
| Globe data | gen_*.py produces the static JSON under docs/zh-TW/games/tor-network/, and publish_games_data.sh regenerates and publishes the files that keep changing |
| Interaction and layout checks | Gesture, framing, and layout checks driven by headless Chrome |
| Deployment | cf_purge.py purges Cloudflare cache in parallel batches, and s3_restore_mtime.py lets aws s3 sync skip files whose content has not changed |
- Python: 3.12+
- Package Manager: uv
- Node.js: For the frontend tests in
tools/(optional, standard library only)
curl -LsSf https://astral.sh/uv/install.sh | shcd docs
uv sync
source .venv/bin/activate
mkdocs serve # default locale zh-TW, http://127.0.0.1:8000To verify all three locales, use the run_*.sh scripts. Each exports the environment variables that locale needs and builds into output/:
sh run.sh # zh-TW (default locale, built at the site root)
sh run_zh-cn.sh # zh-CN
sh run_en.sh # enRunning mkdocs build -f mkdocs_en.yml directly lets variables such as DOCS_DIR fall back to their defaults and raises spurious warnings, so verify locales through these three scripts. The build_docs_anoni*.sh scripts are for the production host and contain server-specific paths; do not run them locally.
# Style self-check; CI runs the same linter on changed Markdown
python3 tools/docs_style_lint.py docs/zh-TW/<changed-file>.md
# When touching a utility script or the service worker, run its test
node tools/test_sw_offline.mjsmain is the development branch and docs is the build trigger. Merging a PR into main only means the content landed in the repository. The production site reads from S3, so publishing requires pushing the docs branch:
git push origin origin/main:refs/heads/docsOnce the workflow finishes, both the clearnet and onion builds are live. There is no automatic sync from main to docs, by design: a human decides what ships and when.
Pushing docs does not always trigger a build. The trigger paths are limited to files that change the output (docs/**, BECOME_ANONI*.md at the repo root, tools/cf_purge.py and tools/s3_restore_mtime.py with their tests, and .github/workflows/build_docs.yml itself). Touching other files under tools/ will not build; use workflow_dispatch from the Actions page when a rebuild is genuinely needed.
| Workflow | Trigger | Content |
|---|---|---|
BuildDocs |
push to docs, manual |
Builds all three locales, processes Open Graph images, uploads clearnet and onion output with aws s3 sync --delete, then purges the Cloudflare cache for the produced URLs via cf_purge.py |
docs-style-lint |
PR | Runs the style linter over changed Markdown and utility UI strings. Error-level rules block merge, warn-level rules only annotate |
invisible-chars |
PR | Repository-wide invisible-character scan. Zero-width characters, BOM, and non-breaking spaces in Markdown block merge |
tools-tests |
PR | The dependency-free tests under tools/, finishing in under ten seconds |
games-checks |
PR | Interaction and layout checks for the Tor relay globe (headless Chrome) |
- Online Documentation: https://anoni.net/docs/
- GitHub Repo: https://github.com/anoni-net/docs
- Tor Onion:
docs.anoninetru5tflukgfaehun7q6khowgmymcff3gtk5oyesqazhmfxtyd.onion - IPFS Gateway: https://ipfs.anoni.net/ (community-run; see the mirror guide for pinning)
- Detailed Development Guide: See AGENTS.md
We welcome contributions of all kinds. Pick your starting point:
- Typo or broken link → open a bug issue, or send a small PR directly.
- Translate an article → open a translation issue; see the i18n workflow.
- Propose a topic, add a local case, or suggest a source → use the content or source issue forms.
- Help with outreach, events, or ops → say hi in the Matrix community Public Space.
Tool and operational-security content (tools, scenarios, advanced) is reviewed by maintainers before merge; everything else is lighter. The single source of truth for writing style is the writing style page on the community site, file naming and the PR process are in the contributor handbook, and tools/docs_style_lint.py is available for a local self-check. See CONTRIBUTING.md for workflow, branches, CI, and licensing, and the Code of Conduct. Reach us via Matrix Public Space (account requests: whisper@anoni.net), GitHub Discussions, or Cryptpad.
This repository contains multiple licenses. Use the table below and each subdirectory's LICENSE file (not all code is MIT).
| Scope | License |
|---|---|
docs/ site content (Markdown, etc.) |
CC-BY 4.0 |
tools/ scripts and tests |
MIT (excluding tools/data/) |
Third-party data under docs/zh-TW/games/tor-network/ |
Retains its original license; see NOTICE |
- The root
LICENSEfile is the full CC-BY 4.0 text used as the default license notice for documentation and site content. - Among the globe datasets,
ooni.jsonis CC BY-NC-SA 4.0 and prohibits commercial use. ReadNOTICEbefore redistributing. tools/data/holds source data files whose coordinates come partly from OpenStreetMap under ODbL. They fall outside the MIT license coveringtools/; seeNOTICE.
Copyright © 2023-2026 anoni.net Docs Project