Cloudflare Gateway 套件註冊表安全怎麼設?先看 pkg.* 與 TLS 解密
如果你想在 CI 或開發者網路中限制某個 npm、PyPI 或 Cargo 套件,光封鎖 registry 網域通常不夠:同一個套件可能從公開 registry、Artifactory、Nexus 或其他 mirror 下載。Cloudflare 在 2026 年 8 月 13 日宣布 Gateway package registry security,改用下載 URL 的 registry protocol 來辨識套件,並提供 pkg.* selector 寫 HTTP policy。
先抓住這個功能的邊界:它是 Gateway 流量辨識與 policy 控管,不是 lockfile、套件簽章或依賴掃描的替代品。
先確認七種支援的套件生態系
Cloudflare 官方文件目前列出七種支援的套件生態系:
| 生態系 | 可辨識的下載類型 | namespace 概念 |
|---|---|---|
| npm | package tarball | scope,例如 @babel |
| PyPI | wheel | — |
| RubyGems | gem | — |
| Cargo | crate | — |
| Go | module zip | module path |
| Maven | JAR | group ID |
| NuGet | nupkg | — |
初始版本偵測的是 download operation。resolve metadata 或 publish 使用不同的 endpoint、host 或 HTTP method,不能直接假設也會被同樣方式分類。若你的目標是控制 npm install 拉下來的檔案,先用下載流量驗證,不要把所有 package registry API 都當成同一種操作。
TLS 解密是必要前提
Package registry security 要檢查的流量必須先通過 TLS decryption,否則 Gateway 看不到足以辨識套件的 URL 結構。這也是設定失敗時最先要查的地方:如果 policy 沒有命中,不要先改 pkg.name,先確認該裝置或 CI 流量是否真的經過 Gateway 以及 TLS 解密範圍。
設定前可以先完成這份前置檢查:
- 確認開發者或 CI 流量走的是 Cloudflare Gateway HTTP proxy。
- 確認需要檢查的流量已啟用 TLS decryption,並處理裝置端信任憑證。
- 用 Gateway HTTP log 找一筆實際套件下載,而不是只測 registry 首頁。
- 記下生態系、套件名稱、版本、namespace 和 host,作為 policy 的測試輸入。
- 先在低風險環境驗證 Allow/Block 優先順序,再擴大套用範圍。
pkg.* selector 各自負責什麼
HTTP policy 可使用五個 selector:
| Selector | 用途 | 注意事項 |
|---|---|---|
pkg.ecosystem | 判斷 npm、pypi、cargo 等生態系 | Dashboard 要先選單一 ecosystem,才能展開其他欄位 |
pkg.name | 套件名稱 | 先指定 ecosystem 再指定名稱 |
pkg.version | 套件版本 | 支援依生態系的版本比較,不是 npm ^1.2.3 這種 range 語法 |
pkg.namespace | npm scope、Maven group ID 或 Go module path | 只有支援 namespace 的生態系會顯示 |
pkg.purl | Package URL | 只能在 API 表達式使用,Dashboard 沒有這個欄位 |
例如要封鎖特定 npm 套件,可以用:
pkg.ecosystem == "npm" and pkg.name == "event-stream"要封鎖某個版本以下的套件,官方文件示範的是:
pkg.ecosystem == "npm" and pkg.name == "lodash" and pkg.version < "4.17.21"這些是 Cloudflare 的 wirefilter 表達式,不是 .npmrc 或 package.json 設定。寫進 policy 前先確認動作是 Block,並在 HTTP log 驗證實際命中欄位。
版本比較不要直接套用 npm range
pkg.version 會依生態系採用不同的版本語意:npm 和 Cargo 使用 SemVer,PyPI 使用 PEP 440,Go、Maven、NuGet 也各自有對應規則。Cloudflare 支援 ==、!=、>、>=、<、<= 這些比較運算子,但不支援 npm ^1.2.3、PyPI ~=1.4 或 Maven interval notation。
因此 policy 應該把版本邊界寫成可驗證的比較,而不是把 lockfile 裡的 range 原樣貼上。若套件版本無法依該 ecosystem 解析,條件可能不會命中;這時要回到 log 確認 Cloudflare 實際解析到的版本字串。
私有 mirror:用 package selector 加 host 分流
Cloudflare 是依 URL 路徑的 registry protocol 辨識套件,不是依固定 hostname 清單。這代表公開 registry.npmjs.org、公司 Artifactory、Nexus 或自建 mirror,只要下載 URL 符合對應格式,都可能被辨識成 npm 流量。
如果組織要求 npm 只能從內部 mirror 下載,可以拆成兩條有優先順序的 policy:
# 高優先順序:允許公司 mirrorpkg.ecosystem == "npm" and http.request.host == "npm.internal.example.com"
# 低優先順序:封鎖其他 npm 下載pkg.ecosystem == "npm"先 Allow、後 Block 的順序很重要。否則第二條可能先把內部 mirror 也擋住。若只想限制單一內部套件,也能把 pkg.namespace、pkg.name 和 http.request.host 組合起來,讓同一個 package 從其他 host 下載時被阻擋。
這個功能不能替你完成哪些安全工作
Package registry security 可以辨識下載並套用 HTTP policy,但以下工作仍要保留在原本的供應鏈流程:
- lockfile 與 checksum:確認建置拿到的是預期內容,可參考 pnpm tarball integrity 錯誤的驗證順序。
- 依賴更新與漏洞修補:Gateway policy 不會替你決定何時升級套件。
- publish 權限與套件來源治理:初始版本的偵測重點是 download,不要把它當成 package publish 的審核器。
- 未被分類的流量:官方文件說明 detection 是 fail-open;URL 無法分類時會以一般非套件流量繼續,不會因分類失敗而阻擋安裝。
結論:先讓 log 看見,再讓 policy 阻擋
導入 Cloudflare Gateway 套件註冊表安全時,順序應該是 TLS decryption、實際下載 log、selector 欄位、policy 優先順序,最後才是擴大阻擋範圍。pkg.* 讓規則可以從「封鎖整個 registry」縮小到 ecosystem、套件、namespace 和版本;但 lockfile、checksum 和漏洞管理仍然是建置流程自己的責任。
常見問題
Q: 只設定 pkg.name 為什麼不能在 Dashboard 直接選?
A: Cloudflare 的 Dashboard 會先要求選定單一 Package Ecosystem,才會提供套件名稱、版本和 namespace 欄位。若用 in 或 not in 一次比對多個 ecosystem,這些巢狀欄位會被停用。
Q: pkg.purl 可以在 Dashboard 的 HTTP policy 使用嗎?
A: 目前不行。pkg.purl 可在 API 的 wirefilter expression 使用,Dashboard 不提供這個 selector;若只在 Dashboard 設定,應改用 ecosystem、name、version、namespace 和 host 組合。
Q: 分類失敗會讓 npm install 直接停掉嗎?
A: Cloudflare 文件把 package detection 定義為 fail-open。URL 無法分類時會依一般非套件流量處理,因此不要把分類失敗當成阻擋保證;重要依賴仍應靠 lockfile、checksum 和建置驗證。
參考資料:
Cloudflare Changelog:Detect and control software package downloads with package registry security
回報錯字、失效連結,或告訴我你想看的延伸主題。