Cloudflare for SaaS (旧 SSL for SaaS) でカスタムホスト利用する際のフロー図

# 目的

ドキュメントで英語の文字だけを読んでもわかりづらい部分があるので、フロー図を作ってわかりやすく整理しておきます。

（ついでに Qiita で `mermaid` 使う練習）

- [Cloudflare for SaaS · Cloudflare for Platforms docs](https://developers.cloudflare.com/cloudflare-for-platforms/cloudflare-for-saas/)
>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101361/ae423ab8-b974-d6ef-7dad-ccc2fbed2258.png)


# カスタムホスト作成（Add Custom Hostname）
- [Verify custom hostnames · Cloudflare for Platforms docs](https://developers.cloudflare.com/cloudflare-for-platforms/cloudflare-for-saas/domain-support/hostname-verification/)
- [Validate certificates · Cloudflare for Platforms docs](https://developers.cloudflare.com/cloudflare-for-platforms/cloudflare-for-saas/security/certificate-management/issue-and-validate/validate-certificates/)

カスタムホスト作成時には、このようなフローになります。
以下、ポイントを解説します。

- カスタムホスト利用開始時に、ダウンタイムが許容されるかで `Pre-validation` を実施すべきかを決める
- ダウンタイムが許容される場合
    - どの検証方法も使えるが、先に DNS 宛先を設定し、自動 `Auto` 検証を使うことで手間を省くことできる（もちろん他の検証方法も利用可能）
- ダウンタイムが許容されない場合
    - 両方の検証において、事前に `Pre-validation` を実施し、ホスト名と証明書の両方が `Active` であることを確認した上で、DNS 宛先を切り替えることでダウンタイムを回避できる
- ワイルドカード証明書を使う場合には、TXT ベースの DCV（証明書ドメイン認証）が必須

```mermaid:
flowchart TD
    A[Add Custom Hostname] --> X
    subgraph X[Custom Hostname]
    H[Hostname validation check</br>- no recheck / one-time only]
    V[Certificate validation check</br>- DCV must be renewed]
    end
    X --> B{Downtime OK?}
    subgraph Y[Hostname validation check]
    1[CNAME</br>Auto]
    2[Apex Proxying</br>Auto]
    3[HTTP token</br>Manual]
    4[TXT record</br>Manual]
        subgraph P[Pre-validation]
        3
        4
        end
    end
    J[Pre-validate Both Checks First] --> P
    J --> R
    B -->|Yes| C[Point DNS Record First]
    C -->|CNAME| 1
    C -->|A/AAAA| 2
    1 --> W[Hostname</br>Active]
    2 --> W
    P --> S[Hostname</br>Active]
    S --> D[Point DNS Record]
    W --> K
    D -->|CNAME/A/AAAA| F[Traffic Flow Start]
    subgraph I[Certificate validation check]
    5[TXT based</br>DCV Delegation]
    6[TXT record</br>Manual]
    7[HTTP token</br>Manual]
        subgraph R[Pre-validation]
            subgraph M[Enable Wildcard]
            5
            6
            end
        7
        end
    8[HTTP token</br>Auto]
    end
    B ---->|No| J
    C --> 8
    R --> U[Certficate</br>Active]
    U --> D
    8 --> Z[Certficate</br>Active]
    Z --> K
    K{Both OK?} -->|Yes| F
```

# 固定 IP (Static IP) オプションの必要性
- [Cloudflare IP addresses · Cloudflare Fundamentals docs](https://developers.cloudflare.com/fundamentals/get-started/concepts/cloudflare-ip-addresses/#customize-cloudflare-ip-addresses)
> **Static IP addresses**: Cloudflare sets static IP addresses for your domain. For more details, contact your account team.

Zone Apex など、DNS 宛先設定に A/AAAA レコードを使う必要がある場合は 固定 IP (Static IP) オプションを別途追加して利用することが望ましい

  - 通信フローに関して、A/AAAA レコードの宛先が [Cloudflare IP Ranges](https://www.cloudflare.com/ips/) の範囲であれば、問題なく機能するが [Cloudflare IP Ranges](https://www.cloudflare.com/ips/) が変更されない保証はない
  - 固定 IP (Static IP) オプションであれば、固定である（変更されない）ことが保証される
  - Apex Proxying によるホスト名検証に関しては初回の一度きり完了すればよいが、該当の SaaS ゾーンに紐づいた Apex Proxying 用の IP に変更があった場合は、新規カスタムホスト名検証時に都度変更を周知する必要がある

# 証明書更新（Renew）
- [Renew certificates · Cloudflare for Platforms docs](https://developers.cloudflare.com/cloudflare-for-platforms/cloudflare-for-saas/security/certificate-management/issue-and-validate/renew-certificates/)

証明書更新時には、このようなフローになります。
自動更新（Auto-Renew）となるように設計することが推奨です。

```mermaid:
flowchart TD
  10{Expiring in 30 days?} -->|Yes|1
  10 -->|No|20[No Renew happens]
  1[Renew Check Start]-->2{Wildcard?}
  2-->|No|3{Proxied?}
  3-->|Yes|4[HTTP token</br>Auto]
  3-->|No|00
  2-->|Yes|000
  subgraph 0[Certificate validation check]
    4
    subgraph 00[HTTP Manual or TXT]
      6[HTTP token</br>Manual]
      subgraph 000[Wildcard]
        7[TXT based</br>DCV Delegation]
        8[TXT record</br>Manual]
      end
    end
  end
  4-->9[Auto-Renew]
  7-->9
  6-->99[Manual-Renew]
  8-->99
```

# 手動による検証再始動

- [Immediate validation checks · Cloudflare for Platforms docs](https://developers.cloudflare.com/cloudflare-for-platforms/cloudflare-for-saas/reference/troubleshooting/#immediate-validation-checks)
> You can send a PATCH request to request an immediate validation check on any certificate. The PATCH data only needs include the same ssl object as the original request.

ダッシュボードから Custom Hostname > **Refresh** をクリックするか、同じ `ssl` 設定で `PATCH` リクエストを送ることで、Hostname / Certificate validation check を再始動できます。
（一旦、Hostname validation check が `Active` になった後は、Hostname validation check は再始動しません。）

- [Edit Custom Hostname - Cloudflare API Documentation](https://developers.cloudflare.com/api/operations/custom-hostname-for-a-zone-edit-custom-hostname)

```shell:
export EMAIL='YOUR_EMAIL'
export APIKEY='YOUR_APIKEY'
export ZONE_ID='YOUR_ZONE_ID'
export CUSTHOST_UUID='YOUR_CUSTOM_HOSTNAME_ID'

curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/custom_hostnames/$CUSTHOST_UUID" \
  -X 'PATCH' \
  -H "X-Auth-Email: $EMAIL" \
  -H "X-Auth-Key: $APIKEY" \
  -H "Content-Type: application/json" \
  --data-raw '{"ssl":{"method":"txt","type":"dv","settings":{"min_tls_version":"1.2"}}}'
```

# 【参考】HTTP 検証エンドポイント / TXT 検証レコードの例

- Hostname validation check
    - HTTP token
        - url: `http://$CUSTOM_HOSTNAME/.well-known/cf-custom-hostname-challenge/<custom-hostname-UUID>`
    - TXT record
        - name: `_cf-custom-hostname.$CUSTOM_HOSTNAME`
- Certificate validation check
    - HTTP token
        - name: `http://$CUSTOM_HOSTNAME/.well-known/acme-challenge/<TOKEN>`
        - Ref. [Challenge Types - Let's Encrypt](https://letsencrypt.org/docs/challenge-types/)
    - TXT record (Manual)
        - `_acme-challenge.$CUSTOM_HOSTNAME`
    - TXT based DCV Delegation
        - CNAME: `_acme-challenge.$CUSTOM_HOSTNAME`
        - target: `$CUSTOM_HOSTNAME.<Target-UUID>.dcv.cloudflare.com`
        - Ref. [Out now! Auto-renew TLS certificates with DCV Delegation](https://blog.cloudflare.com/introducing-dcv-delegation/)