Cloudflare Pages + Access (綁定 O365 Entra ID) 部署方案 ¶
運用 Cloudflare Pages 的全球高速邊緣 CDN 託管 Material for MkDocs,並透過 Cloudflare Zero Trust Access 與 Microsoft 365 / Microsoft Entra ID (Azure AD) 單一登入 (SSO) 整合,打造無須架設 VPN 的企業級零信任內部私有知識庫。
1. 方案架構與核心優勢¶
傳統企業內部文件庫往往依賴內部伺服器搭配公司 VPN 存取,常面臨連線延遲高、維護負擔重與行動裝置體驗不佳等痛點。本方案採用 Cloudflare 邊緣零信任 (Edge-based Zero Trust) 架構:
- 零信任安全邊緣防護 (Zero Trust Network Access, ZTNA):所有對知識庫的 HTTP 請求在抵達靜態檔案前,直接在 Cloudflare 全球 300+ 邊緣節點進行身分攔截與驗證,未授權者無法接觸站點內容。
- 無縫整合 Microsoft 365 (Entra ID):員工直接使用現有的公司 O365 帳號、企業多因素驗證 (MFA) 與安全性群組 (Security Groups) 登入。
- 全球邊緣極速體驗:Cloudflare Pages 提供無上限頻寬與極低延遲,靜態資源秒開。
- 慷慨的免費方案 (Free Tier):
- Cloudflare Pages:免費版提供無限制頻寬與請求數。
- Cloudflare Zero Trust:提供高達 50 個免費使用者名額,非常適合中小企業或團隊內部技術庫。
- 自動化 PR 預覽環境:每次送出 Pull Request 時自動產生獨立預覽環境,且同樣能套用 Access 防護規則。
驗證與存取流程架構圖¶
sequenceDiagram
autonumber
actor User as 企業員工 (Browser)
participant CF_Edge as Cloudflare Edge (Pages + Access)
participant Entra as Microsoft Entra ID (O365)
participant Site as MkDocs 靜態內容
User->>CF_Edge: 存取知識庫 (例如: docs.company.com)
CF_Edge->>CF_Edge: 檢查 CF_Authorization Cookie
alt 尚未通過驗證
CF_Edge-->>User: 302 重導向至 Microsoft 365 登入頁
User->>Entra: 輸入 O365 帳密 + MFA 驗證
Entra-->>User: 簽發身分權杖並重導向回 Cloudflare Callback
User->>CF_Edge: 攜帶授權碼回傳 Cloudflare
CF_Edge->>Entra: 交換 JWT 權杖並驗證群組與網域規則
CF_Edge-->>User: 設定 CF_Authorization Cookie (安全 HttpOnly)
end
CF_Edge->>Site: 讀取授權頁面快取
Site-->>User: 成功瀏覽 MkDocs 知識庫內容 2. 事前準備 (Prerequisites)¶
在配置前,請備妥以下管理權限與資源:
- Cloudflare 帳戶:已將自訂網域託管於 Cloudflare(若使用預設
*.pages.dev亦可,但自訂網域可獲得最完整的 Access 政策控制)。 - Microsoft 365 / Microsoft Entra ID 管理員權限:具備在 Entra ID 系統管理中心建立「應用程式註冊 (App Registration)」之權限。
- GitHub 儲存庫:包含 MkDocs 專案原始碼(
mkdocs.yml、docs/、requirements.txt)。
3. 步驟一:在 Microsoft Entra ID 註冊應用程式¶
首先需在微軟雲端建立應用程式,供 Cloudflare Access 進行 OpenID Connect (OIDC) 驗證。
1. 建立應用程式註冊¶
- 登入 Microsoft Entra 系統管理中心(或 Azure Portal ➔ Microsoft Entra ID)。
- 前往 身分識別 (Identity) ➔ 應用程式 (Applications) ➔ 應用程式註冊 (App registrations)。
- 點選 + 新增註冊 (New registration):
- 名稱:輸入易辨識的名稱,例如
Cloudflare Access - Tech Docs。 - 支援的帳戶類型:選擇「僅此組織目錄中的帳戶 (僅限單一租用戶 Single tenant)」。
- 重新導向 URI (Redirect URI):
- 平台選擇 Web。
- URI 填入:
https://<your-team-name>.cloudflareaccess.com/cdn-cgi/access/callback - (註:
<your-team-name>為您在 Cloudflare Zero Trust 設定的團隊網域名稱)。
- 名稱:輸入易辨識的名稱,例如
- 點選 註冊 (Register)。
2. 記錄重要參數¶
在註冊完成的「概觀 (Overview)」頁面,記錄以下資訊:
- 應用程式 (用戶端) 識別碼 (Application / Client ID)
- 目錄 (租用戶) 識別碼 (Directory / Tenant ID)
3. 產生用戶端密碼 (Client Secret)¶
- 在左側選單進入 憑證與密碼 (Certificates & secrets) ➔ 用戶端密碼 (Client secrets) 標籤頁。
- 點選 + 新增用戶端密碼 (New client secret)。
- 設定說明與有效期限(例如 180 天或 24 個月),點選 新增。
- 立即複製「值 (Value)」(離開頁面後將無法再次查看)。
4. 設定 API 權限 (API Permissions)¶
- 前往 API 權限 (API permissions),確認已預設具備 Microsoft Graph 的
User.Read(Delegated)。 - 若需要依據 Entra ID 安全性群組 (Security Groups) 進行存取授權:
- 點選 權杖設定 (Token configuration) ➔ + 新增群組宣告 (Add groups claim)。
- 勾選 安全性群組 (Security groups),確定新增。
4. 步驟二:在 Cloudflare Zero Trust 配置身分識別提供者 (IdP)¶
將微軟 Entra ID 綁定為 Cloudflare Access 的登入驗證源。
- 登入 Cloudflare One / Zero Trust 控制台。
- 進入 Settings (設定) ➔ Authentication (驗證)。
- 在 Login methods (登入方式) 區塊點選 Add new (新增)。
- 選擇 Azure AD / Microsoft Entra ID:
- Name:自訂名稱(例如
Microsoft 365 Entra ID)。 - Application ID:貼上步驟一記錄的
Client ID。 - Application secret:貼上步驟一記錄的
Client Secret。 - Directory (Tenant) ID:貼上步驟一記錄的
Tenant ID。 - Support groups:若需要依群組篩選權限,請切換為開啟。
- Name:自訂名稱(例如
- 點選 Save (儲存)。
- 儲存後可點擊該登入方式旁的 Test (測試) 按鈕,會彈出微軟登入視窗,確認能成功授權並抓取到使用者身分與群組資訊。
5. 步驟三:部署 MkDocs 至 Cloudflare Pages¶
可以選擇透過 GitHub Actions 自動化發布 或 Cloudflare Pages 內建 Git 整合 進行建置。
推薦做法:使用 GitHub Actions 發布¶
此方式可沿用既有的語法檢查與嚴格建置規範,並將建置完成的 site/ 目錄直接推送至 Cloudflare Pages。
建立 .github/workflows/deploy-cloudflare-pages.yml:
name: Deploy MkDocs to Cloudflare Pages
on:
push:
branches:
- main
pull_request:
branches:
- main
permissions:
contents: read
deployments: write
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build-and-deploy:
runs-on: ubuntu-latest
name: Build & Deploy to Cloudflare Pages
steps:
- name: 檢出儲存庫代碼 (完整歷史以支援 git 外掛)
uses: actions/checkout@v7
with:
fetch-depth: 0
ref: ${{ github.head_ref || github.ref }}
- name: 設定 Python 環境
uses: actions/setup-python@v7
with:
python-version: "3.11"
cache: "pip"
- name: 安裝相依套件
run: pip install -r requirements.txt
- name: 建置 MkDocs 靜態網站 (嚴格模式)
env:
MKDOCS_GIT_COMMITTERS_APIKEY: ${{ secrets.GITHUB_TOKEN }}
DISABLE_MKDOCS_2_WARNING: "true"
run: mkdocs build --strict
- name: 發布至 Cloudflare Pages
uses: cloudflare/wrangler-action@v3
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
command: pages deploy site --project-name=windcold-kb
[!NOTE] 金鑰設定與自建 GitLab 替代方案
需在 GitHub 儲存庫 Secrets 中配置:
CLOUDFLARE_API_TOKEN:具備Cloudflare Pages: Edit權限之 API Token。CLOUDFLARE_ACCOUNT_ID:Cloudflare 儀表板中的帳戶 ID。(註:若專案代碼託管於企業自建 GitLab,可透過 GitLab Runner 執行 Wrangler CLI 推送部署,詳見 Self-Hosted GitLab CI/CD 部署方案。)
6. 步驟四:在 Cloudflare Access 建立存取防護政策¶
在專案部署上線後,需套用 Access Application 政策,限制未經授權之訪客。
1. 建立 Access Application¶
- 在 Cloudflare Zero Trust 控制台,點選 Access (存取) ➔ Applications (應用程式)。
- 點選 Add an application (新增應用程式) ➔ 選擇 Self-hosted (自託管)。
- 設定基本設定:
- Application name:例如
內部技術知識庫。 - Session Duration:憑證有效期間(例如
24 小時或1 個月)。 - Application domain:
- 填入綁定之自訂子網域(例如
docs.yourcompany.com)或 Pages 預設網域名稱。
- 填入綁定之自訂子網域(例如
- Application name:例如
- 在 Identity providers 區塊:
- 勾選剛才建立的 Microsoft 365 Entra ID。
- (選用)取消勾選 One-time PIN,以強制全員必須使用 O365 登入。
2. 配置存取規則 (Access Policies)¶
點選 Next 進入政策制定頁面:
- Policy name:例如
僅限全體正職員工。 - Action:選擇 Allow (允許)。
- Configure rules (設定規則):
- 方式一(依 Email 網域):
- Selector 選擇
Emails ending in➔ 填入公司企業網域@yourcompany.com。
- Selector 選擇
- 方式二(依 Entra ID 安全性群組):
- Selector 選擇
Azure Group/SAML Group➔ 填入 Entra ID 中對應群組之 Object ID(如研發部門、架構小組)。
- Selector 選擇
- 點選 Save 完成防護設定。
7. 最佳實踐與安全性強化¶
A. 關閉或限制 *.pages.dev 原始網域存取¶
Cloudflare Pages 在建立時會預設附帶一個 project.pages.dev 網址。為防止外部人員繞過自訂網域的 Access 防護:
- 做法一(最推薦):將 Access Application 的 Application Domain 同時涵蓋
*.pages.dev網址。 - 做法二:在 Cloudflare Pages 專案設定中的 Custom Domains 啟用 Access 保護,並在 Access 政策中將預設網域納入防護清單。
B. HTTP 安全標頭設定 (_headers)¶
可在 MkDocs 的 docs/ 或根目錄建立 _headers 檔案,MkDocs 建置後複製到 site/_headers,Cloudflare Pages 會自動解析並注入安全回應標頭:
/*
X-Frame-Options: DENY
X-Content-Type-Options: nosniff
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: document-domain=()
C. 取得當前已登入使用者資訊(選用)¶
當使用者通過 Cloudflare Access 驗證後,Cloudflare 會在轉發的請求中注入 JWT Header:
Cf-Access-Authenticated-User-Email:登入者的 Email。Cf-Access-Jwt-Assertion:可供客戶端 JavaScript 或 Worker 驗證的完整加密 JWT。
8. 常見問題與除錯要點 (Troubleshooting)¶
Q1: 微軟登入時出現 AADSTS50011: The reply URL specified in the request does not match?¶
原因:Entra ID 應用程式註冊中的重新導向 URI (Redirect URI) 與 Cloudflare 送出的回呼網址不一致。 解法:檢查 Entra ID 的「驗證 (Authentication)」設定,Redirect URI 格式必須完全符合: https://<your-team-name>.cloudflareaccess.com/cdn-cgi/access/callback(注意末尾無多餘斜線,協定為 https)。
Q2: 員工登入成功,但出現 Cloudflare Access 403 Forbidden?¶
原因:該員工帳號不符合 Access Policy 的規則(例如群組未匹配,或 Email 網域不相符)。 解法:在 Cloudflare Zero Trust 儀表板檢視 Logs ➔ Access,查看該筆連線的評估記錄 (Audit Logs),確認其攜帶的 Email 與 Groups 宣告是否符合 Policy 條件。
Q3: 本地執行 mkdocs serve 時是否需要登入?¶
原因:不需要。Cloudflare Access 運作於 Cloudflare 的雲端邊緣伺服器上,本地開發與預覽完全不受影響。