Cloudflare ゾーンのデフォルト初期設定を取得する

# 目的

Cloudflare でゾーン登録をした際のデフォルト初期設定を一覧で把握する

# Terraform

## Terraform 準備

Terraform を使います。

- [Install Terraform · Cloudflare Terraform docs](https://developers.cloudflare.com/terraform/installing/)

以下のディレクトリとファイルを準備します。

```shell:
terraform % tree
.
├── provider.tf
├── terraform.tfvars
├── variable.tf
├── zone-setting-override.tf
└── zone.tf
```

```terraform:provider.tf
terraform {
  required_providers {
    cloudflare = {
      source  = "cloudflare/cloudflare"
      version = "~> 4.10"
    }
  }
}
provider "cloudflare" {
  email   = var.cloudflare_email
  api_key = var.cloudflare_api_key
}
```

```terraform:terraform.tfvars
cloudflare_email      = "YOUR_EMAIL"
cloudflare_api_key    = "YOUR_APIKEY"
cloudflare_account_id = "YOUR_ACCOUNT_ID"
```

以下の変数は、`sensitive = true` として出力に表示されないようにします。

- [Protect Sensitive Input Variables | Terraform | HashiCorp Developer](https://developer.hashicorp.com/terraform/tutorials/configuration-language/sensitive-variables)

```terraform:variable.tf
variable "cloudflare_email" { sensitive = true }
variable "cloudflare_api_key" { sensitive = true }
variable "cloudflare_account_id" { sensitive = true }
```

```terraform:zone-setting-override.tf
resource "cloudflare_zone_settings_override" "my_zone" {
  zone_id = cloudflare_zone.my_zone.id
}
```

```terraform:zone.tf
resource "cloudflare_zone" "my_zone" {
  account_id = var.cloudflare_account_id
  paused     = false
  plan       = "enterprise" # free
  type       = "full"
  zone       = "example.com"
}
```

## デフォルト初期設定の取得
- [cloudflare_zone_settings_override | Resources | cloudflare/cloudflare | Terraform | Terraform Registry](https://registry.terraform.io/providers/cloudflare/cloudflare/latest/docs/resources/zone_settings_override)

以下のコマンドをたたくと、デフォルト初期設定を一覧で把握できます。

`initial_settings` については、プランによる違いはありませんでした。

```shell
terraform init
terraform plan
terraform apply --auto-approve
terraform show -json | jq -r '.values.root_module.resources[] | select (.type == "cloudflare_zone_settings_override") | .values.initial_settings[]'
```

```json:zone_initial_settings.json
{
  "always_online": "off",
  "always_use_https": "off",
  "automatic_https_rewrites": "off",
  "binary_ast": "off",
  "brotli": "off",
  "browser_cache_ttl": 14400,
  "browser_check": "on",
  "cache_level": "aggressive",
  "challenge_ttl": 1800,
  "ciphers": [],
  "cname_flattening": "flatten_at_root",
  "development_mode": "off",
  "early_hints": "off",
  "email_obfuscation": "on",
  "filter_logs_to_cloudflare": "off",
  "h2_prioritization": "off",
  "hotlink_protection": "off",
  "http2": "on",
  "http3": "off",
  "image_resizing": "off",
  "ip_geolocation": "on",
  "ipv6": "on",
  "log_to_cloudflare": "on",
  "max_upload": 100,
  "min_tls_version": "1.0",
  "minify": [
    {
      "css": "off",
      "html": "off",
      "js": "off"
    }
  ],
  "mirage": "off",
  "mobile_redirect": [
    {
      "mobile_subdomain": "",
      "status": "off",
      "strip_uri": false
    }
  ],
  "opportunistic_encryption": "off",
  "opportunistic_onion": "on",
  "orange_to_orange": "off",
  "origin_error_page_pass_thru": "off",
  "origin_max_http_version": "1",
  "polish": "off",
  "prefetch_preload": "off",
  "privacy_pass": "on",
  "proxy_read_timeout": "100",
  "pseudo_ipv4": "off",
  "response_buffering": "off",
  "rocket_loader": "off",
  "security_header": [
    {
      "enabled": false,
      "include_subdomains": false,
      "max_age": 0,
      "nosniff": false,
      "preload": false
    }
  ],
  "security_level": "medium",
  "server_side_exclude": "on",
  "sort_query_string_for_cache": "off",
  "ssl": "full",
  "tls_1_2_only": "off",
  "tls_1_3": "on",
  "tls_client_auth": "off",
  "true_client_ip_header": "off",
  "universal_ssl": "",
  "visitor_ip": "on",
  "waf": "off",
  "webp": "off",
  "websockets": "on",
  "zero_rtt": "off"
}
```

# Zone Settings API

- [Get all Zone settings - Cloudflare API Documentation](https://developers.cloudflare.com/api/operations/zone-settings-get-all-zone-settings)
- [HTTPie を Cloudflare API / GraphQL 用に設定する - Qiita](https://qiita.com/khayama/items/1738c3b98e9c4108a35d)

```
export ZONE_ID='YOUR_ZONE_ID'

http -A creds GET https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/settings | jq -r '.result | ["editable","id","modified_on","value"],(.[]| [.editable,.id,.modified_on,.value|tostring])|@csv' > zone_settings.csv

csv2md zone_settings.csv > zone_settings.md
cat zone_settings.md | pbcopy
```

editable | id | modified_on | value
---|---|---|---
true | 0rtt | null | off
false | advanced_ddos | null | on
true | always_online | null | off
true | always_use_https | null | off
true | automatic_https_rewrites | null | off
true | brotli | null | off
true | browser_cache_ttl | null | 14400
true | browser_check | null | on
true | cache_level | null | aggressive
true | challenge_ttl | null | 1800
true | ciphers | null | []
true | cname_flattening | null | flatten_at_root
true | development_mode | null | off
true | early_hints | null | off
true | edge_cache_ttl | null | 7200
true | email_obfuscation | null | on
true | filter_logs_to_cloudflare | null | off
true | hotlink_protection | null | off
true | http2 | null | on
true | http3 | null | off
true | ip_geolocation | null | on
true | ipv6 | 2023-07-22T17:09:50.608440Z | on
true | log_to_cloudflare | null | on
true | long_lived_grpc | null | off
true | max_upload | null | 100
true | min_tls_version | null | 1.0
true | minify | null | {"css":"off","html":"off","js":"off"}
true | mirage | null | off
true | mobile_redirect | null | {"status":"off","mobile_subdomain":null,"strip_uri":false}
true | opportunistic_encryption | null | off
true | opportunistic_onion | null | on
true | orange_to_orange | null | off
true | origin_error_page_pass_thru | null | off
true | polish | null | off
true | pq_keyex | null | on
true | prefetch_preload | null | off
true | privacy_pass | null | on
true | proxy_read_timeout | null | 100
true | pseudo_ipv4 | null | off
true | response_buffering | null | off
true | rocket_loader | null | off
true | security_header | null | {"strict_transport_security":{"enabled":false,"max_age":0,"include_subdomains":false,"preload":false,"nosniff":false}}
true | security_level | null | medium
true | server_side_exclude | null | on
true | sort_query_string_for_cache | null | off
true | ssl | null | full
true | tls_1_2_only | null | off
true | tls_1_3 | null | on
true | tls_client_auth | null | off
true | true_client_ip_header | null | off
true | visitor_ip | null | on
true | waf | null | off
true | webp | null | off
true | websockets | null | on

# デフォルト初期設定まとめ

| `zone_settings`               | `initial_settings`                                           | Docs / Link                                                  |
| ----------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ |
| `always_online`               | `off`                                                        | [Always Online](https://developers.cloudflare.com/cache/how-to/always-online/) |
| `always_use_https`            | `off`                                                        | [Always Use HTTPS](https://developers.cloudflare.com/ssl/edge-certificates/additional-options/always-use-https/#always-use-https) |
| `automatic_https_rewrites`    | `off`                                                        | [Automatic HTTPS Rewrites](https://developers.cloudflare.com/ssl/edge-certificates/additional-options/automatic-https-rewrites/#automatic-https-rewrites) |
| `binary_ast`                  | `off`                                                        | [[SOLVED] BinaryAST availability depending on plan - Website, Application, Performance / Security - Cloudflare Community](https://community.cloudflare.com/t/solved-binaryast-availability-depending-on-plan/337044)<br />> The binary_ast setting still exists but BinaryAST is not supported. |
| `brotli`                      | `off`                                                        | [Brotli compression](https://developers.cloudflare.com/speed/optimization/content/brotli/) |
| `browser_cache_ttl`           | `14400`                                                      | [Browser Cache TTL](https://developers.cloudflare.com/cache/how-to/edge-browser-cache-ttl/#browser-cache-ttl) |
| `browser_check`               | `on`                                                         | [Browser Integrity Check](https://developers.cloudflare.com/fundamentals/security/browser-integrity-check/#browser-integrity-check) |
| `cache_level`                 | `aggressive`                                                 | [Caching levels](https://developers.cloudflare.com/cache/how-to/set-caching-levels) |
| `challenge_ttl`               | `1800`                                                       | [Challenge Passage](https://developers.cloudflare.com/fundamentals/security/challenge-passage/#challenge-passage) |
| `ciphers`                     | `[]`                                                         | [Customize cipher suites](https://developers.cloudflare.com/ssl/reference/cipher-suites/customize-cipher-suites/) |
| `cname_flattening`            | `flatten_at_root`                                            | [CNAME flattening](https://developers.cloudflare.com/dns/cname-flattening/) |
| `development_mode`            | `off`                                                        | [Development Mode](https://developers.cloudflare.com/cache/reference/development-mode/#development-mode) |
| `early_hints`                 | `off`                                                        | [Early Hints](https://developers.cloudflare.com/cache/advanced-configuration/early-hints/) |
| `edge_cache_ttl`              | `7200`                                                       | [Remove edge_cache_ttl zone setting · Issue #653 · cloudflare/terraform-provider-cloudflare](https://github.com/cloudflare/terraform-provider-cloudflare/issues/653)<br />>This setting is not officially supported, and doesn't actually change any edge behavior. It should not have been included in Terraform and should be removed. The proper way to control this is via page rules |
| `email_obfuscation`           | `on`                                                         | [What is Email Address Obfuscation?](https://developers.cloudflare.com/support/more-dashboard-apps/cloudflare-scrape-shield/what-is-email-address-obfuscation/) |
| `filter_logs_to_cloudflare`   | `off`                                                        | For [Cloudflare China Network](https://developers.cloudflare.com/china-network/)<br />> Whether edge logs should be filtered before being sent to US |
| `h2_prioritization`           | `off`                                                        | [Enhanced HTTP/2 Prioritization](https://developers.cloudflare.com/speed/optimization/protocol/#protocol-optimization) |
| `hotlink_protection`          | `off`                                                        | [Understanding Cloudflare Hotlink Protection](https://developers.cloudflare.com/support/more-dashboard-apps/cloudflare-scrape-shield/understanding-cloudflare-hotlink-protection/#understanding-cloudflare-hotlink-protection) |
| `http2`                       | `on`                                                         | [Understanding Cloudflare HTTP2 and HTTP3 Support](https://developers.cloudflare.com/support/network/understanding-cloudflare-http2-and-http3-support/#http2) |
| `http3`                       | `off`                                                        | [Understanding Cloudflare HTTP2 and HTTP3 Support](https://developers.cloudflare.com/support/network/understanding-cloudflare-http2-and-http3-support/#http3) |
| `image_resizing`              | `off`                                                        | [Cloudflare Image Resizing](https://developers.cloudflare.com/images/image-resizing/) |
| `ip_geolocation`              | `on`                                                         | [Configuring IP geolocation](https://developers.cloudflare.com/support/network/configuring-ip-geolocation/) |
| `ipv6`                        | `on`                                                         | [Understanding and configuring Cloudflare's IPv6 support](https://developers.cloudflare.com/support/network/understanding-and-configuring-cloudflares-ipv6-support) |
| `log_to_cloudflare`           | `on`                                                         | For [Cloudflare China Network](https://developers.cloudflare.com/china-network/)<br />> Whether to send edge logs to Cloudflare log receiver in US |
| `long_lived_grpc`             | `off`                                                        | Enable long timeout for grpc connections                     |
| `max_upload`                  | `100`                                                        | [Max upload size](https://developers.cloudflare.com/cache/concepts/default-cache-behavior/#customization-options-and-limitations) |
| `min_tls_version`             | `1.0`                                                        | [Minimum TLS Version](https://developers.cloudflare.com/ssl/edge-certificates/additional-options/minimum-tls/#minimum-tls-version) |
| `minify`                      | `"css":"off"`<br />``"html":"off"``<br />``"js":"off"``      | [Auto Minify](https://developers.cloudflare.com/speed/optimization/content/auto-minify/#auto-minify) |
| `mirage`                      | `off`                                                        | [Cloudflare Mirage](https://developers.cloudflare.com/speed/optimization/images/mirage/) |
| `mobile_redirect`             | `"mobile_subdomain": ""`<br />`"status": "off"`<br />`"strip_uri": false` | [Mobile Redirect](https://developers.cloudflare.com/speed/optimization/other/mobile-redirect/#mobile-redirect) |
| `opportunistic_encryption`    | `off`                                                        | [Opportunistic Encryption](https://developers.cloudflare.com/ssl/edge-certificates/additional-options/opportunistic-encryption/#opportunistic-encryption) |
| `opportunistic_onion`         | `on`                                                         | [Understanding Cloudflare Tor support and Onion Routing](https://developers.cloudflare.com/support/firewall/learn-more/understanding-cloudflare-tor-support-and-onion-routing) |
| `orange_to_orange`            | `off`                                                        | [Change Orange to Orange (O2O) setting](https://developers.cloudflare.com/api/operations/zone-settings-change-orange_to_orange-setting)<br />> Orange to Orange (O2O) allows zones on Cloudflare to CNAME to other zones also on Cloudflare. |
| `origin_error_page_pass_thru` | `off`                                                        | [Configuring Custom Pages (Error and Challenge)](https://developers.cloudflare.com/support/more-dashboard-apps/cloudflare-custom-pages/configuring-custom-pages-error-and-challenge/) |
| `origin_max_http_version`     | `1`                                                          | [HTTP/2 to Origin](https://developers.cloudflare.com/cache/concepts/enable-http2-to-origin/) |
| `polish`                      | `off`                                                        | [Cloudflare Polish](https://developers.cloudflare.com/images/polish/) |
| `pq_keyex`                      | `on`                                                        | post quantum key exchange |
| `prefetch_preload`            | `off`                                                        | [Prefetch URLs](https://developers.cloudflare.com/speed/optimization/content/prefetch-urls/) |
| `privacy_pass`                | `on`                                                         | [Privacy Pass](https://developers.cloudflare.com/fundamentals/security/privacy-pass/) |
| `proxy_read_timeout`          | `100`                                                        | [Change Proxy Read Timeout setting](https://developers.cloudflare.com/api/operations/zone-settings-change-proxy_read_timeout-setting)<br />> Maximum time (sec) between two read operations from origin. |
| `pseudo_ipv4`                 | `off`                                                        | [Enable Pseudo IPv4](https://developers.cloudflare.com/support/network/understanding-and-configuring-cloudflares-ipv6-support/#enable-pseudo-ipv4) |
| `response_buffering`          | `off`                                                        | [Setting up Response Buffering](https://developers.cloudflare.com/support/network/setting-up-response-buffering/) |
| `rocket_loader`               | `off`                                                        | [Rocket Loader](https://developers.cloudflare.com/speed/optimization/content/rocket-loader/) |
| `security_header`             | `"enabled": false`<br />`"include_subdomains": false`<br />`"max_age": 0`<br />`"nosniff": false`<br />`"preload": false` | [HTTP Strict Transport Security (HSTS)](https://developers.cloudflare.com/ssl/edge-certificates/additional-options/http-strict-transport-security/#http-strict-transport-security-hsts) |
| `security_level`              | `medium`                                                     | [Security Level](https://developers.cloudflare.com/fundamentals/security/security-level/) |
| `server_side_exclude`         | `on`                                                         | [What does Server-side Excludes (SSE) do?](https://developers.cloudflare.com/support/more-dashboard-apps/cloudflare-scrape-shield/what-does-server-side-excludes-sse-do/) |
| `sort_query_string_for_cache` | `off`                                                        | [Query String Sort](https://developers.cloudflare.com/cache/advanced-configuration/query-string-sort/) |
| `ssl`                         | `full`                                                       | [Encryption modes](https://developers.cloudflare.com/ssl/origin-configuration/ssl-modes/) |
| `tls_1_2_only`                | `off`                                                        | Warning: Argument is deprecated<br /><br />tls_1_2_only has been deprecated in favour of using `min_tls_version = "1.2"` instead.<br />Deprecation notice: Please use the 'min_tls_version' endpoint for future requests. |
| `tls_1_3`                     | `on`                                                         | [TLS 1.3](https://developers.cloudflare.com/ssl/edge-certificates/additional-options/tls-13/) |
| `tls_client_auth`             | `off`                                                        | [Authenticated Origin Pulls (mTLS)](https://developers.cloudflare.com/ssl/origin-configuration/authenticated-origin-pull) |
| `true_client_ip_header`       | `off`                                                        | [True-Client-IP (Enterprise plan only)](https://developers.cloudflare.com/fundamentals/get-started/reference/http-request-headers/#true-client-ip-enterprise-plan-only) |
| `universal_ssl`               | `""`                                                         | [Disable Universal SSL certificates · Cloudflare SSL/TLS docs](https://developers.cloudflare.com/ssl/edge-certificates/universal-ssl/disable-universal-ssl/) |
| `visitor_ip`                  | `on`                                                         | Enable sending headers to the origin that contain the visitor IP (e.g., Cf-Connecting-IP, X-Forwarded-For).  If false then headers are stripped from requests to the origin. <br/>This can also be done by `Remove visitor IP headers` of [Managed Transforms](https://developers.cloudflare.com/rules/transform/managed-transforms/reference/) |
| `waf`                         | `off`                                                        | WAF is deprecated for this zone, Managed Rulesets should be used instead (1027) |
| `webp`                        | `off`                                                        | [Cloudflare Polish](https://developers.cloudflare.com/images/polish/) |
| `websockets`                  | `on`                                                         | [Using Cloudflare with WebSockets](https://developers.cloudflare.com/support/network/using-cloudflare-with-websockets/) |
| `zero_rtt`                    | `off`                                                        | [0-RTT Connection Resumption](https://developers.cloudflare.com/speed/optimization/protocol/0-rtt-connection-resumption/) |



# 参考：プランによる `readonly_settings` の違い
Free プランと Enterprise プランを比べてみると、

Free プランでは一部の機能が `readonly` のため、有効化や制御できないものが確認できます。

```shell:
terraform show -json | jq -r '.values.root_module.resources[] | select (.type == "cloudflare_zone_settings_override") | .values.readonly_settings'
```

## Enterprise プランの場合

```json:enterprise_readonly_settings.json
[
  "advanced_ddos"
]
```

## Free プランの場合

```json:free_readonly_settings.json
[
  "advanced_ddos",
  "http2",
  "long_lived_grpc",
  "mirage",
  "origin_error_page_pass_thru",
  "polish",
  "prefetch_preload",
  "proxy_read_timeout",
  "response_buffering",
  "sort_query_string_for_cache",
  "true_client_ip_header",
  "webp",
  "image_resizing"
]
```