yangble5 安裝腳本校驗

校驗

執行之前,先自己核對

首頁上有兩條路:把一行字貼給 AI agent,或者自己在終端機跑 curl … | sh。 兩條路最後執行的是同一份腳本,而這種安裝方式的安全性,完全建立在「你信任 yangble5.com 這個網域,而且連線沒有被中間人竄改」之上。這一頁讓你不必只靠信任 —— 你可以自己驗。

先比對那一行。我們發佈給 AI agent 的字串只有一條,長這樣:
Install yangble5 by following https://yangble5.com/AGENTS.md
沒有旗標、沒有端點網址、沒有金鑰。你手上那一行只要跟它不是逐字相同 —— 多一個字、換一個網域、多一個 --api —— 就不是我們的。這一頁後面所有的雜湊校驗,都擋不住那種情況; 首頁那一節解釋為什麼。

目前公告的 SHA256

即時讀取自 /install.sh.sha256/install.ps1.sha256,沒有任何一個雜湊值寫死在這個頁面裡。

install.sh (macOS / Linux)

讀取中…

install.ps1 (Windows)

讀取中…

顯示「尚未公告」代表什麼?代表這台伺服器上還沒有放校驗檔,不代表腳本是安全的,也不代表可以跳過驗證。這種情況下請直接去 GitHub 上的原始碼比對,或乾脆不要執行。我們寧可你不裝,也不要你在沒有校驗的情況下裝。

逐步核對

macOS / Linux

# 1. 下載,先不要執行
curl -fsSL https://yangble5.com/install.sh -o install.sh

# 2. 算出你手上這份的雜湊
shasum -a 256 install.sh
#   沒有 shasum 的話:
sha256sum install.sh

# 3. 跟上面公告的值逐字元比對。不一樣就停在這裡。

# 4. 或者讓機器幫你比(對就印 OK,不對會直接失敗)
curl -fsSL https://yangble5.com/install.sh.sha256 -o install.sh.sha256
shasum -a 256 -c install.sh.sha256

# 5. 自己讀過一遍。用編輯器或 cat,不要用 less/more ——
#    AI agent 的 shell 沒有 tty,分頁器不是把整份倒進對話紀錄就是卡住等按鍵。
cat install.sh

# 6. 先空跑:把它打算做的每一件事印出來,一個檔案都不寫
shasum -a 256 -c install.sh.sha256 && sh install.sh --dry-run

# 7. 看過計畫、同意了,才真的安裝
sh install.sh

Windows(PowerShell)

# 1. 下載,先不要執行
irm https://yangble5.com/install.ps1 -OutFile install.ps1

# 2. 算出雜湊
Get-FileHash .\install.ps1 -Algorithm SHA256

# 3. 跟公告值比對(PowerShell 輸出是大寫,大小寫不影響)
$expected = '<貼上上面公告的值>'
$actual = (Get-FileHash .\install.ps1 -Algorithm SHA256).Hash
if ($actual -ieq $expected) { 'OK - 相符' } else { 'MISMATCH - 不要執行' }

# 3b. 或者讓機器幫你抓公告值來比,不符就 throw,後面都不會跑
irm https://yangble5.com/install.ps1.sha256 -OutFile install.ps1.sha256
$expected = ((Get-Content .\install.ps1.sha256 -Raw) -split '\s+')[0]
if ((Get-FileHash .\install.ps1 -Algorithm SHA256).Hash -ine $expected) { throw 'MISMATCH' }

# 4. 自己讀過一遍
notepad .\install.ps1

# 5. 先空跑,再真的安裝
powershell -NoProfile -File .\install.ps1 -DryRun
powershell -NoProfile -File .\install.ps1

用 certutil(不想開 PowerShell 的話)

certutil -hashfile install.ps1 SHA256

要傳 e-mail/邀請碼的話

管線不會把參數傳進去:curl … | sh 給不了腳本 argv, irm … | iex 給不了 scriptblock 參數。而且安裝腳本是全自動的, 它不會停下來問你任何事,所以該問的必須事先問完再傳進去:

curl -fsSL https://yangble5.com/install.sh | sh -s -- --email you@example.com
sh install.sh --dry-run --invite YOUR-INVITE-CODE

& ([scriptblock]::Create((irm https://yangble5.com/install.ps1))) -Email you@example.com
powershell -NoProfile -File .\install.ps1 -DryRun -Invite YOUR-INVITE-CODE

# 或用環境變數,兩支腳本都認
YANGBLE5_EMAIL=you@example.com YANGBLE5_INVITE=YOUR-INVITE-CODE sh install.sh
$env:YANGBLE5_EMAIL = 'you@example.com'

對不上怎麼辦

  • 不要執行那個檔案。先做這一件事,其他都之後再說。
  • 把下載到的檔案刪掉,不要留著「等一下再看」。
  • 可能只是我們發佈了新版而校驗檔還沒同步 —— 但你沒辦法從外面分辨這個和真正的攻擊,所以處理方式相同:先當作有問題。
  • GitHub issues 回報,附上你算到的雜湊、頁面顯示的雜湊,以及下載時間。
  • 如果你是透過公共 Wi-Fi 或不受信任的網路下載的,換一個網路重試一次再下結論。

這個校驗能證明什麼、不能證明什麼

啟動器到底設了哪些環境變數

首頁寫的是「export 十一個變數,外加一個 unset」。下面是那十一行的逐字原文, 出自 install.shwrite_config()——就是產生 ~/.yangble5/env.sh 的那一段。沒有省略任何一項;如果你自己數出來不是十一個,那是我們寫錯了,請開 issue 告訴我們。 (這一頁不寫行號。行號會隨腳本改動而位移,一個過期的行號讀起來卻跟正確的一模一樣; 函式名稱不會這樣騙人。grep -n 'write_config()' install.sh 一秒就能定位。)

# ~/.yangble5/env.sh —— 只被 ~/.yangble5/bin/yangble5-* 這幾支啟動器 source。
# 這些值只存在於啟動器啟動的那個行程裡,不會寫進你的 shell。

# 1-3 先把 ~/.yangble5/credentials「解析」成 KEY=VALUE(不是 source),再 export
export YANGBLE5_API YANGBLE5_API_KEY YANGBLE5_MODEL

# 4 Claude Code 的設定與登入目錄。你原本的 ~/.claude 不受影響,靠的就是這一行。
export CLAUDE_CONFIG_DIR="${HOME}/.yangble5/claude"

# 5-7 把 Claude Code 指向這個端點
export ANTHROPIC_BASE_URL="${YANGBLE5_API}"
export ANTHROPIC_AUTH_TOKEN="${YANGBLE5_API_KEY}"
export ANTHROPIC_MODEL="${YANGBLE5_MODEL}"

# 8-10 三個數值上限。下面是預設值,可以用環境變數覆寫,但一律要先通過數字範圍檢查。
export CLAUDE_CODE_MAX_CONTEXT_TOKENS=1000000
export CLAUDE_CODE_MAX_OUTPUT_TOKENS=65536
export API_TIMEOUT_MS=600000

# +一個 unset。ANTHROPIC_API_KEY 的優先序高於 ANTHROPIC_AUTH_TOKEN,
#   留著它會把你真正的 Anthropic 金鑰送到這個代理。移出啟動器環境。
unset ANTHROPIC_API_KEY

# 11 Codex 的家目錄,指向下面那份隔離設定
export CODEX_HOME="${HOME}/.yangble5/codex"

兩個容易被略過、但很重要的細節。

env.shcredentials 的方式是逐行拆成 KEY=VALUE, 而不是 .(source)。憑證檔是資料;source 它就等於把裡面每一個值變成可執行的 shell 程式碼。 解析器讀不動它讀到的東西。讀完之後,其中三個(端點、模型別名、金鑰)還會再被同一組允許字元 檢查一次,不合格就直接退出(離開碼 6)—— 因為安裝腳本的檢查只管得住它自己寫進去的內容, 管不住之後誰去編輯那個檔案。

YANGBLE5_KEY_ID 也會在解析時被賦值,但沒有被 export, 所以它不算在十一個裡面,也不會出現在啟動的行程環境中。 Windows 版是同一組名稱,拆在 yangble5-claude.cmdyangble5-codex.cmd 兩支啟動器裡,用 setlocal 隔離, ANTHROPIC_API_KEY 則是被設成空值。

它在你的磁碟上寫了哪些東西

完整清單,分成永久留下暫存兩類。除了下面這些路徑,安裝腳本不寫任何地方 —— 特別是不寫 ~/.claude~/.codex.bashrc.zshrc.profile,也不改 PATH

永久:留在你磁碟上的東西

暫存:安裝期間存在,離開時刪除

這一段以前不在這一頁上,而上面那句「除了這些路徑不寫任何地方」因此是錯的。 安裝腳本還會用 mktemp -d 開一個暫存目錄,位置由 $TMPDIR 決定 (沒設的話多數系統是 /tmp),名字是 tmp. 加隨機字元。 建立它的是 install.shvalidate_settings(),建完立刻 chmod 700它跟你的家目錄無關,所以任何只掃 $HOME 的檢查都看不到它 —— 這正是這句話錯了那麼久還沒被抓到的原因。

安裝過程中會在那裡出現十個檔案。下表的「含金鑰」欄是實測結果:在一次完整安裝中側錄暫存目錄、 再到副本裡搜尋那把金鑰字串。

安裝腳本在 mktemp -d 暫存目錄裡建立的十個檔案。「含金鑰」欄是實測結果,不是推論。
檔名內容含金鑰額外 chmod何時刪除
curlrc.<pid>curl 的設定檔,含 x-api-keyauthorization 兩個標頭600每次呼叫結束
resp.<pid>HTTP 回應本體,註冊那一次就是金鑰送達的地方每次呼叫結束
credentials.<pid>~/.yangble5/credentials 的暫存版寫檔後立刻
write.<pid>寫檔中繼站,每一個產生的檔案都經過它,所以金鑰也經過每寫一個檔就刪
curlerr.<pid>curl 的 stderr每次呼叫結束
env.<pid>env.sh 的暫存版(金鑰在這裡是變數引用,不是字面值)寫檔後立刻
codex.<pid>codex/config.toml 的暫存版寫檔後立刻
install_info.<pid>INSTALL_INFO 的暫存版寫檔後立刻
register.json註冊請求本體:機器指紋、標籤,以及你自己傳的 e-mail/邀請碼600只在離開時
probe.json驗證用的那一次 /v1/messages 請求本體只在離開時

權限:真正的邊界是目錄,不是檔案。十個裡面只有 curlrcregister.json 另外做了 chmod 600 (分別在 http_call()obtain_key() 裡),其餘八個沿用你當下的 umask。 擋住同一台機器上其他使用者的是外面那層 700 的目錄。 這在單人機器上沒有差別;在共用主機上,這是你該知道的實際邊界。

刪除:trap cleanup EXIT HUP INT TERM 涵蓋這四種離開方式, 但涵蓋不了 SIGKILL、斷電與當機。 正常結束、或你按 Ctrl-C,整個目錄會被 rm -rf,那裡不會留下任何東西。 被 kill -9 或機器直接斷掉時目錄會留著;我們實測過一次:在 HTTP 呼叫進行中送出 SIGKILL,磁碟上留下 curlrcregister.jsonprobe.jsoncurlerr 四個檔案, 其中 curlrc 裡有完整的金鑰。 遇到這種情況,刪掉 $TMPDIR 底下那個 tmp. 目錄再重跑一次安裝就好。

被覆蓋的檔案,以及怎麼還原

要寫的檔案已經存在、而且內容不同時,安裝腳本先 cp -p 出一份 <檔名>.bak-<時間戳> 再覆蓋;內容一樣就印 unchanged 並跳過。 跑完它會把每一份備份的完整路徑,連同可以直接貼回終端機的還原指令一起印出來。 輸出的格式是這樣(時間戳由 date +%Y%m%d-%H%M%S 產生,路徑是絕對路徑; 下面是版型,不是某一次執行的紀錄):

  Files replaced this run — each was copied first

      <絕對路徑>/env.sh.bak-<時間戳>
        restore with:  cp -p "<絕對路徑>/env.sh.bak-<時間戳>" "<絕對路徑>/env.sh"

      Exempt on purpose: ~/.yangble5/INSTALL_INFO is rewritten every run
      and is owned entirely by the installer, so it is not backed up.
      Nothing else is exempt.

一份備份都沒有的時候,它印的是 no existing file was overwritten, so nothing was backed up,而不是沉默。 Windows 版印的是 Copy-Item -LiteralPath … -Destination … -Force,行為一致。

最保險的做法

不用管線,直接從版本控制拿:

git clone https://github.com/shark0120/yangble5
cd yangble5
# 讀原始碼、看 commit 歷史,然後自己決定要不要跑
git log --oneline -20

這一頁跟首頁一樣是單一檔案:HTML 裡沒有任何第三方請求 —— 沒有 CDN、沒有網頁字型、沒有分析追蹤、沒有 cookie。 頁面自己發出的執行期請求只有同源的那兩個 .sha256 檔(首頁另外會讀同源的 /pool/status,讀不到才退回 /health)。整頁存下來離線讀也可以 —— 那兩個雜湊會顯示「尚未公告」, 頁面不會拿一個看起來合理的舊值來充數。
但邊緣會加東西,這點必須講:本站經 Cloudflare 供應,回應帶有 Report-ToNel 標頭,指向 a.nel.cloudflare.com。那是網路錯誤回報(NEL), 不在這個檔案裡,但它確實會讓瀏覽器在連線失敗時把錯誤回報給 Cloudflare。 你開 devtools 就看得到,所以我們自己先說。要完全避開就從 GitHub 拿原始碼,別經過這個網域。