Cloudflare SSL mode による HTTPS 化を確認する

# はじめに

Cloudflare では、以下の SSL mode を活用することで、Cloudflareーオリジン間の通信について、HTTPS を使うように制御できます。

>  [Origin Server - SSL modes · Cloudflare SSL docs](https://developers.cloudflare.com/ssl/origin-configuration/ssl-modes)
> ![image-20210623002113843](https://cdn.jsdelivr.net/gh/kyouheicf/image@master/uPic/image-20210623002113843.png)

Cloudflareーオリジン間の通信が、実際に HTTPS で行われるかどうかを調査します。

# 確認方法

オリジン Web サーバーに Apache を使います。

> [Cloudflare からの HTTP リクエストヘッダを可視化する - Qiita](https://qiita.com/khayama/items/0787728497918f2e68d6)

デフォルトでは Cloudflare によって、HTTP リクエストヘッダ `X-Forwarded-Proto` と `Cf-Visitor` は同じ値に設定されます。

>[How does Cloudflare handle HTTP Request headers? – Cloudflare Help Center](https://support.cloudflare.com/hc/en-us/articles/200170986-How-does-Cloudflare-handle-HTTP-Request-headers-)

今回は、オリジンサーバーで以下のように接続プロトコルごとに `X-Forwarded-Proto` を上書きするように設定を追加します。

```/etc/httpd/conf/httpd.conf
RequestHeader set X-Forwarded-Proto "http"
```

```/etc/httpd/conf.d/ssl.conf
<VirtualHost _default_:443>
RequestHeader set X-Forwarded-Proto "https"
</VirtualHost>
```

設定を反映するために、`sudo systemctl restart httpd` でサービスを再起動します。
その後に、以下のコマンドで確認できます。

```shell
curl -s http://khayama.ml | grep -e Cf-Visitor -e X-Forwarded-Proto
curl -s https://khayama.ml | grep -e Cf-Visitor -e X-Forwarded-Proto
```

## Cloudflareーオリジン間の通信が HTTP の場合
`X-Forwarded-Proto: http` となります。
例えば、SSL mode を Flexible にした場合、クライアントーオリジン間を `https` で接続すると、Cloudflareーオリジン間の通信は `http` になります。

```shell
% curl -s https://khayama.ml | grep -e Cf-Visitor -e X-Forwarded-Proto
Cf-Visitor: {"scheme":"https"} <br />
X-Forwarded-Proto: http <br />
```

## Cloudflareーオリジン間の通信が HTTPS の場合
`X-Forwarded-Proto: https` となります。
例えば、SSL mode を Strict (SSL-Only Origin Pull) にした場合、クライアントーオリジン間を `http` で接続すると、Cloudflareーオリジン間の通信は `https` になります。

```shell
% curl -s http://khayama.ml | grep -e Cf-Visitor -e X-Forwarded-Proto 
Cf-Visitor: {"scheme":"http"} <br />
X-Forwarded-Proto: https <br />
```

# 確認結果

以下のようになりました。

| SSL mode                      | Client --> Cloudflare         | Cloudflare --> Origin |
| ----------------------------- | ----------------------------- | --------------------- |
| Off                           | HTTP                          | HTTP                  |
| Off                           | HTTPS --> HTTP (301 Redirect) | -                     |
| Flexible                      | HTTP                          | HTTP                  |
| Flexible                      | HTTPS                         | HTTP                  |
| Full                          | HTTP                          | HTTP                  |
| Full                          | HTTPS                         | HTTPS                 |
| Full (Strict)                 | HTTP                          | HTTP                  |
| Full (Strict)                 | HTTPS                         | HTTPS                 |
| Strict (SSL-Only Origin Pull) | HTTP                          | HTTPS                 |
| Strict (SSL-Only Origin Pull) | HTTPS                         | HTTPS                 |

# 完全に HTTPS 化するには
「Always Use HTTPS」の機能を使えば、クライアントーCloudflare間の通信に対して HTTP を HTTPS にリダイレクトできます。

> [How to make your site HTTPS-only](https://blog.cloudflare.com/how-to-make-your-site-https-only/)
>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101361/06234c1b-b34a-1e5e-c1bf-f96596646012.png)

ただし、SSL mode = Off と「Always Use HTTPS」は併用できません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101361/dbc576f7-9efe-95c1-7c54-9ab7df603459.png)

「Always Use HTTPS」を組み合わせた場合の結果は、以下のようになります。

| SSL mode                      | Client --> Cloudflare         | Cloudflare --> Origin |
| ----------------------------- | ----------------------------- | --------------------- |
| Off                           | HTTP                          | HTTP                  |
| Off                           | HTTPS --> HTTP (301 Redirect) | -                     |
| Flexible                      | HTTP --> HTTPS (301 Redirect) | -                     |
| Flexible                      | HTTPS                         | HTTP                  |
| Full                          | HTTP --> HTTPS (301 Redirect) | -                     |
| Full                          | HTTPS                         | HTTPS                 |
| Full (Strict)                 | HTTP --> HTTPS (301 Redirect) | -                     |
| Full (Strict)                 | HTTPS                         | HTTPS                 |
| Strict (SSL-Only Origin Pull) | HTTP --> HTTPS (301 Redirect) | -                     |
| Strict (SSL-Only Origin Pull) | HTTPS                         | HTTPS                 |