Cloudflare のIPアドレスってどうなってる？

:::note info
この記事は [筑波NSミライラボ Advent Calendar 2023](https://qiita.com/advent-calendar/2023/tsukuba-ns-mirailabo) 13日目の記事です。
:::

この記事では、CloudflareでIPアドレスがどのようにIPアドレスを効率的に活用しているのかについて紹介します。

筑波大学情報科学類1年の@appare45です。

この記事は、2023年12月3日に [UNTIL.LT#0x03](https://until-tsukuba.github.io/events/2023/until-lt0x03/) で発表した内容の解説です。

<iframe src="https://docs.google.com/presentation/d/e/2PACX-1vSKF_M2hLeKbFW9ghhAxmDMxeKq-6eM-_CBjGGwuBYmvGFOwrwb8EABn1MV07AycQ2yTbY-D3Xq2AEi/embed?start=false&loop=false&delayms=3000" frameborder="0" width="960" height="409" allowfullscreen="true" mozallowfullscreen="true" webkitallowfullscreen="true"></iframe>

## Cloudflareとは

みなさんはCloudflareというサービスをご存知ですか？

もしかしたら、次のような画面を見たことがあるかもしれません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625810/67a1fba6-3d44-944d-3feb-31b6a3cf0100.png)

このとき中央に表示されている雲のマークのサービスがCloudflareです。

Cloudflareは簡単に言うとサービスとユーザの間でプロキシを提供するサービスです。

通常のサービスではサービス提供サーバとユーザが直接接続されます。

一方、サービスがCloudflareを使うとサーバとユーザの間Cloudflareが挟まり、ファイアウォールやキャッシュなどの恩恵を受けられます。

![Qiita ver.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625810/34828abd-21fc-90e0-f7c0-4a3e7a000e2c.png)

しかし、Cloudflareのサーバが一箇所にしかない場合どうなるでしょう。ユーザは遠回りしなければならなくなり、非常に**時間がかかる**ことになります。

![Qiita ver (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625810/3bb1311d-99f3-7606-5e1f-e2a9c6560396.png)

そこでCloudflareは世界中にサーバを置くことで、高速なサービス提供を可能にしています。

![Qiita ver (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625810/550bd22c-41d8-f1c8-24ee-1e937f54372f.png)

この場合、自動的にユーザに最も近いCloudflareのサーバが割り当てられるようになる必要があります。

これにより、逆にユーザとサービスの距離が遠くても近くのCloudflareが一部の仕事を肩代わりしてくれるので、ユーザは高速にサービスを使うことができます。

ところでユーザはどのように **近い** Cloudflareのサーバを見つけるのでしょうか？

答えはCloudflareが1つのIPアドレスを世界中で共有しているからです。

ここからは、CloudflareがどのようにIPアドレスの共有しているかを解説します。

## ユーザとCloudflareの接続

まず、ユーザがどのように最も近いCloudflareに接続されるかを解説します。

はじめに、IPアドレスからどのように目的地に到達するかを解説します。

通信はASを通って目的のIPアドレスに伝えられます。IPアドレスはBGPというプロトコルでAS同士が通信することで、目的地を伝えられます。

ASはASから近くのAS（IX）と通信するため、最短の経路を導き出すことができます。

Cloduflareはこの仕組みをうまく利用しています。東京のCloudflareのサーバは東京のASに対して、IPアドレスを・アメリカのCloudflareのサーバはアメリカのASに対してIPアドレスを伝えます（アナウンス）。

![Qiita ver (1).jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625810/b5349a99-69fa-86d6-f785-cc3e97afdc91.jpeg)


これにより東京のASを経由した人は東京のサーバに接続され、アメリカのASを経由した人はアメリカのサーバに接続されます。

このように、一つのIPアドレスが複数の異なるサーバのいずれかに接続される仕組みを`IP Anycast`といいます。

試しに筑波大学のコンピュータで試してみると次の結果が確認できました。

```bash
violet03:~$ traceroute -A 104.16.132.229
traceroute to 104.16.132.229 (104.16.132.229), 30 hops max, 60 byte packets
 1  _gateway (130.158.231.254) [AS37917]
 2  130.158.231.253 (130.158.231.253) [AS37917]
 3  130.158.9.109 (130.158.9.109) [AS37917]
 4  130.158.3.217 (130.158.3.217) [AS37917]
 5  150.99.189.193 (150.99.189.193) [AS2907] 
 6  150.99.8.45 (150.99.8.45) [AS2907]
 7  210.171.224.134 (210.171.224.134) [*]  
 8  172.70.120.2 (172.70.120.2) [AS13335]  
 9  104.16.132.229 (104.16.132.229) [AS13335] 
```

この中で`AS`から始まる部分がASのIDを意味しています。AS番号を調べてみると次のような流れでCloudflareにアクセスしていることがわかりました。

`UTINS`（筑波大学）→`SINET`（学術情報ネットワーク）→`IIJ`（IIX）→`Cloudflare`

- UTINSはSINETに接続するだけ
- SINETはCloudflareのIPアドレスを知らないので上流にあるIIJに接続
- IIJはCloudflareのIPアドレスを知っているのでCloudflareの東京に接続する

![Qiita ver (3).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625810/49d74112-05e1-f234-7f21-63f0c30103ab.png)


## Cloudflareからサービスへの接続

Cloudflareというと、CDNのイメージが強いかと思いますが、実際にはVPNのようなサービス（WARP）やプロキシのように動作してファイアウォールを設定することもできます。

そのためには、Cloudflareからサービスの提供元（オリジン）のサーバに接続する必要があります。しかし、サービスによっては日本からのアクセスのみ許可したり、Cloudflareからのアクセスを認識する必要があります。

そもそも、Cloudflareはアクセス元のIPアドレスをまとめてリクエストを投げる形になります。

昨今ではIPv4は枯渇しており、非常にお金がかかってしまいます。そのためCloudflareはIPアドレスを可能な限り節約したいと考えています。

もし仮に4箇所のデータセンタに1万台のマシンがあってそれぞれに一つづつIPアドレスを割り当てることとなった場合、4万個のIPアドレスが必要になります。

この方法は、Cloudflareのサーバと目的のサーバが1:1で対応するので、`IP Unicast` と呼ばれます。

![Qiita ver (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625810/6d2242a2-958b-9ef1-10c8-273554ad6e40.png)

Cloudflare全体でIPアドレスを共有する単純な方法としては、送信用に専用のサーバを用意しすべての送信を担当させるパターンです。

![Qiita ver (5).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625810/c304891f-063f-26df-2bd8-b3f65e1a4b25.png)

この場合は、IPアドレスを簡単に節約できます。しかし、

- 発信用のサーバを経由するため時間がかかる
- 発信用のサーバがダウンした場合にすべてのサーバが送信できなくなる

という問題があります。

そこで、Cloudflareではこの2つの中間として、データセンタごとにIPアドレスを割り振ることにしました。

![Qiita ver.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625810/922a82d4-28a6-70f0-66e4-906ae71de2c0.png)

この方法だと、

- 接続は1:1で高速
- 必要なIPアドレスの数はほどほど
- それぞれが独立しているので安定している

という、いいとこ取りをすることができます。

## IPアドレスをデータセンタ内で共有する

では、どのように1つのIPアドレスをデータセンタ内で共有するのでしょうか？

ここではNATのような技術が用いられています。

### NATとは

NATを使うとインターネット上で使うIPアドレス（グローバルIP）をローカル上で使うアドレス（ローカルIP）に変換して共有することができます。

詳しくはこちらの記事が非常にわかりやすいのでご確認ください。

https://squid-ink-cafe.com/lag/lag-ready-05/

ちなみに、NATと似たものにNAPTというものがあります。NATではグローバルIPをローカルIPに変換するのではなく、機器ごとにポートを割り当てることでグローバルIPを共有しています。

CloudflareではこのNAPTをロードバランサーのように使えるUnidoegというソフトウェアを開発しました。

Unimogではデータセンタ内でのマシンの負荷が分散するように自動でパケットを割り当てます。Unimogではデータセンタ内のマシンにそれぞれポートをレンジで割り当てています。

さらにUnimogはどのIPアドレスがどのデータセンタに割り当てられているかを、把握しています。

そのため、サービスから特定のIPアドレスに接続が要求された場合には受け取ったデータセンタのUnimogがそのIPアドレスを持っているデータセンタにその通信を自動的に転送します。

![Qiita ver (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3625810/7f41ef26-f507-28a0-dd6e-0135668dc3ea.png)

このようにして、Cloudflareは送信側、受信側に対してもIPアドレスを節約しています。

## 終わりに

この記事ではCloudflareがどのようにIPアドレスを節約しているかを紹介しました。

個人的のもかなり興味深い話が多かったのでお楽しみいただければ幸いです。