Cloudflare Zero Trust Root CA 証明書のダウンロードページを Pages で作る

# 目的

以下の変更により、Cloudflare Zero Trust Root CA 証明書はアカウントごとに生成され、個々のデバイスにインストールする必要があります。

https://qiita.com/khayama/items/042890b7a742ab901d93

ユーザ数が少ない場合やデバイスによって配布ツールがない場合には、アカウントごとに生成される証明書を個別にダウンロードしてもらう必要があります。

その際にダウンロードページを Pages で作ると、非常に手軽に構築できるので、手順と動作を確認します。

```mermaid
%%{init: {'themeCSS': 'img {width: 48px; height:48px;}'}}%%
graph 

subgraph Cloudflare

DefaultRootCA["<img src='https://cf-icons.pages.dev/ssl.svg' width='48' height='48'><br>Default Root CA Cert<br>(Expired)"]:::transparent

subgraph Account
PerAccountRootCA["<img src='https://cf-icons.pages.dev/ssl.svg' width='48' height='48'><br>Per-Account Root CA Cert"]:::transparent
Access[<img src='https://cf-icons.pages.dev/cloudflare-access.svg' width='48' height='48'><br>Access]:::transparent
Pages[<img src='https://cf-icons.pages.dev/pages.svg' width='48' height='48'><br>Pages]:::transparent
end

PerAccountRootCA <--> |"API Call<br>(Pages Function)"|Pages
Access <--> |Authentication|Pages
end

Admin[<img src='https://cf-icons.pages.dev/user.svg' width='48' height='48'><br>Admin]:::transparent
User[<img src='https://cf-icons.pages.dev/user-multi.svg' width='48' height='48'><br>User]:::transparent
MDM[<img src='https://cf-icons.pages.dev/gear.svg' width='48' height='48'><br>MDM]:::transparent

DefaultRootCA --> |"X<br>(No Public Link)"|User
PerAccountRootCA --> |Download<br>from<br>dashboard|Admin --> |Upload|MDM --> |Distribute|User
Pages --> |Download<br>through<br>Authentication|User

classDef hidden display: none;
classDef transparent fill-opacity:0,stroke-opacity:0;
```

# Pages を作成
以下のコードを使います。

https://github.com/kyouheicf/cf-root-ca

以下のように、簡易的な `html` と `functions` 処理の構成です。

```shell:
.
├── README.md
├── functions
│   ├── android.js
│   ├── ios.js
│   ├── macos.js
│   └── windows.js
└── index.html
```

ローカルで動作を確認する場合は以下のような `.dev.vars` を作成し、
`npx wrangler pages dev .` します。

```shell:.dev.vars
ACCOUNT_ID='YOUR_ACCOUNT_ID'
APITOKEN='YOUR_APITOKEN'
ROOT_CA_CERT_ID='YOUR_ROOT_CA_CERT_ID'
```

フォークした自分の GitHub からデプロイする場合は、以下の手順に沿って作成します。

https://developers.cloudflare.com/pages/get-started/git-integration/

CLI からデプロイする場合は、以下のコマンドを実行します。

```shell:
export URL='https://github.com/kyouheicf/cf-root-ca.git'
git clone $URL && cd $(basename $_ .git)
npx wrangler pages deploy .
```

Pages のプロジェクト名（Git のフォルダ名）は適宜変更する必要があるかもしれません。

# Access を有効化し、ポリシーを作成
以下の「Enable Access on your `*.pages.dev` domain」の手順で、Access を有効化します。

https://developers.cloudflare.com/pages/platform/known-issues/#enable-access-on-your-pagesdev-domain

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101361/212e03a0-c014-d3c8-1a16-25b7ba3fa1c7.png)

有効化後、Access > Application から確認できる以下のページに Application が作成されるため、適宜 Access ポリシーを作成し、認証されたユーザのみのアクセスに限定します。

https://one.dash.cloudflare.com/?to=/:account/access/apps

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101361/60df6b01-67c1-0ffe-0a84-5147c638a423.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101361/73304d4d-d840-0119-5a22-2e3fbbb05aaf.png)

App Launcher から表示して、ユーザが簡単にアクセスできるようにします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101361/c9c74ebd-75a4-07cf-6f3f-deffd6bccd42.png)

# Pages で環境変数を設定
以下の手順で環境変数を設定します。

- `ACCOUNT_ID`
- `APITOKEN`
- `ROOT_CA_CERT_ID`

https://developers.cloudflare.com/pages/functions/bindings/#environment-variables

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101361/f8a3783d-6919-b34e-f78f-9a5277b09681.png)

# 動作確認

[App Launcher](https://developers.cloudflare.com/cloudflare-one/applications/app-launcher/) もしくは `https://cf-root-ca.pages.dev/` 等の Pages のリンクから確認できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101361/7cc2f874-c81e-57cd-c14a-9d7a4f5330d6.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101361/a7cc1e27-2505-6dd3-118a-191df1ad5e68.png)

認証を経た上で、アカウントごとに生成される証明書を個別にダウンロードできることが確認できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101361/ea086056-546d-dd34-19c4-6c35de31f013.png)

# まとめ

Pages と Pages Functions を使って、簡単にページが構築できました。

アカウントに紐づいた環境変数や認証の文脈も加えられ、要件としては十分です。

個人的にも macOS, Windows, iOS, Android と異なるデバイス向けの証明書ダウンロードページとして活用できそうです。