CDNでWebサービスのコンテンツ配信を行う際のポイント、そして誤解

# そもそも なぜCDNが必要なのか

※すぐにアーキテクチャを知りたい人は読み飛ばして下さい

多くのユーザが利用するWebサービスであれば、**高速なコンテンツ配信**を提供するためです。
これはCDNが地理的に分散していることによるレイテンシの最小化（結果としてラウンドトリップ時間の短縮）、高負荷に耐える専用ネットワーク及び配信サーバによって大容量のトラフィックを処理できることに由来します。

また、CDNがコンテンツをキャッシュするためコンテンツ配信元であるWebサーバ（これをオリジンサーバと言います）の**負荷を軽減**できるメリットもあります。

CDNサービスは一般的にオリジンサーバへのアクセスよりも安価であるため、**コスト削減**にもつながる場合もあります。

---
CDNとは何かや、各クラウドベンダのCDNに関する説明を以下のリンクから確認できます。

* [【初心者向け】CDNとは？ メリット、注意点等を徹底解説](https://knowledge.sakura.ad.jp/33411/?gclid=Cj0KCQiA-JacBhC0ARIsAIxybyOFCSImwUhAqGXY6GTwciXNvEDnBpK2QKxvaQ3edfylP0BoFv_dgbwaAjaVEALw_wcB)
* [高速・安定CDN ウェブアクセラレータ | さくらインターネット](https://www.sakura.ad.jp/services/cdn/)
* [Cloud CDN の概要 | Google Cloud](https://cloud.google.com/cdn/docs/overview?hl=ja)
* [Amazon CloudFront とは何ですか?](https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/Introduction.html)
* [Cloudflare CDN](https://www.cloudflare.com/ja-jp/cdn/)

# CDNを用いた標準的なWebサービスの構成

では、CDNを用いてどのようなアーキテクチャを構成できるか見てみます。
ここでは[【初心者向け】CDNとは？ メリット、注意点等を徹底解説](https://knowledge.sakura.ad.jp/33411/?gclid=Cj0KCQiA-JacBhC0ARIsAIxybyOFCSImwUhAqGXY6GTwciXNvEDnBpK2QKxvaQ3edfylP0BoFv_dgbwaAjaVEALw_wcB) から画像を引用し説明します。

まず、初回アクセスはCDNにコンテンツが記録されていないため、オリジンサーバにアクセスし、それをユーザに返します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190147/ad22e209-ff9a-f35d-9b43-f60f1e126a54.png)
以降は、CDNがキャッシュにコンテンツを記録するため、オリジンサーバを経由することなく、ユーザに返します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/190147/7cce1997-74c4-630a-f501-834a3afdf466.png)

# CDNやセキュリティに関する設定

CDNを導入するタイミングは様々です。
最初からCDNとオリジンサーバ等、Webサービスを構成するコンポーネントをまとめて扱えれば見落とすことがなくても、コストパフォーマンスの点から後からCDNを導入したために見落としてしまうポイントがあります。
どのタイミングでCDNを導入する場合であっても以下の設定ポイントに気をつけて下さい。

* キャッシュする
  * 静的コンテンツをキャッシュする
  * ユーザ固有のコンテンツはキャッシュしない
* DDoS保護とWAFを導入する
* オリジンサーバへのアクセスを制限する

以下ではこれらの詳細について見てきます。
※もちろん上記以外にも気にするべきポイントはありますが、ここでは割愛します。

## 静的コンテンツをキャッシュする

静的コンテンツとはCSS（`text/css`）、JavaScript（`text/javascript`、`application/javascript`）、フォント（`font/*`）、画像（`image/*`）、動画（`video/*`）、音声ファイル（`audio/*`）、PDF（`application/pdf`）のような常に同じコンテンツです。
これはユーザによって変化しないコンテンツであるためキャッシュ保存のメリットがあります。

キャッシュを設定するには、基本的にCDNの仕様に従って行います。
一般的には、オリジンサーバ側でCDNが指定するヘッダ（例えば `Cache-Control`）を設定します。

* [CloudFront がコンテンツを配信する方法](https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/HowCloudFrontWorks.html)
* [Webサーバ設定ファイルの記述方法](https://manual.sakura.ad.jp/cloud/webaccel/manual/settings-webserver.html)
* [静的コンテンツをキャッシュに保存する](https://cloud.google.com/cdn/docs/best-practices?hl=ja#auto-cache)

## 機密情報を含むコンテンツはキャッシュしない

機密情報を含むコンテンツがキャッシュされてしまうと第三者がそれを閲覧可能になり、情報漏えいにつながります。

機密情報を含むコンテンツまたはキャッシュさせたくないコンテンツもCDNの仕様に従い設定します。
一般的には、オリジンサーバ側でCDNが指定するヘッダ（例えば `Cache-Control`）に`no-cache`ディレクティブ、`private`ディレクティブ等を設定します。

* [CloudFront が特定のファイルをキャッシュしないようにするにはどうしたらよいですか?](https://aws.amazon.com/jp/premiumsupport/knowledge-center/prevent-cloudfront-from-caching-files/)
* [Webサーバ設定ファイルの記述方法 - 注意](https://manual.sakura.ad.jp/cloud/webaccel/manual/settings-webserver.html)
* [キャッシュ保存の禁止](https://cloud.google.com/cdn/docs/caching?hl=ja#preventing-caching)
* [CDN を導入する上で確認すべき注意点とは？- CDNベンダー独自の設定とルール](https://blog.redbox.ne.jp/howto-step-cdn-checkpoint.html)

## DDoS保護とWAFを導入する

DoS攻撃（Denial of Service attack）とは、Webサービス等に対して過剰なアクセスを行い高負荷をかけ、サービスを停止させるようなサイバー攻撃です。
このDoS攻撃に際して、対象サービス等に対して複数のマシンから大量に行うことをDDoS攻撃（Distributed Denial of Service attack）と言います。
ここでは、DDoS攻撃からサービスを守る機構をDDoS保護と呼ぶことにします。

そしてWAF（Web Application FireWall）は、シグネチャまたはブラックリストを用いてWebサービスを守る仕組みです。最も上位のレイヤー（レイヤ7）でリクエストの中身を分析し、SQLインジェクション、OSコマンドインジェクション、クロスサイトスクリプティング等の攻撃から防御します。

* [DDoS攻撃とは？ 意味と読み方、対策方法](https://www.ntt.com/business/services/network/internet-connect/ocn-business/bocn/knowledge/archive_18.html)
* [高度なネットワーク DDoS 対策を構成する](https://cloud.google.com/armor/docs/advanced-network-ddos?hl=ja)
* [WAFとFireWall・IPSの違い](https://blog.redbox.ne.jp/cdn-waf.html)

CDNにDDoS保護及びWAFが統合され提供される場合もありますが、利用するCDNの仕様を理解しこれらの機構を適切に導入します。

* [AWS WAF、AWS Shield、AWS Firewall Manager とは](https://docs.aws.amazon.com/ja_jp/waf/latest/developerguide/what-is-aws-waf.html)
* [AWS WAF を使用してコンテンツへのアクセスの管理](https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/distribution-web-awswaf.html)
* [Google Cloud Armor の概要](https://cloud.google.com/armor/docs/cloud-armor-overview?hl=ja)
* [CDN+WAFの組み合わせが選ばれる理由](https://blog.redbox.ne.jp/cdn-waf.html)
* [攻撃遮断くん](https://manual.sakura.ad.jp/cloud/marketplace/shadan-kun.html)

## オリジンサーバへのアクセスを制限する

CDNからのみオリジンサーバへアクセス可能な設定を行うことで、DDoS保護やWAFによってサイバー攻撃から守ることができます。
もしオリジンサーバに直接アクセスできてしまうと、DDoSやその他脆弱性を突く攻撃に晒される可能性があります。

オリジンサーバへのアクセス制御方法は、やはりCDNまたはCDNを提供するクラウドベンダの仕様に従って設定します。
例えばCDNからのアクセスのみ許可するIPアドレス制限や、AWS CloudFrontの場合はカスタムヘッダー、GCPのCloud CDNの場合はネットワークエンドポイントグループ、さくらのクラウドの場合はオリジンガードのような仕組みを用います。

* [オリジンリクエストへのカスタムヘッダーの追加](https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/add-origin-custom-headers.html)
* [カスタムオリジン上のファイルへのアクセス制限](https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/private-content-overview.html#forward-custom-headers-restrict-access)
* [外部バックエンドを設定する](https://cloud.google.com/cdn/docs/setting-up-cdn-with-ex-backend-internet-neg?hl=ja)
* [オリジンガード機能の利用](https://manual.sakura.ad.jp/cloud/webaccel/manual/settings-originguard.html)

# よくある？誤解：1つのクラウドベンダに閉じた設計にするべきだ

私が見聞きした誤解についてポエムします。

<!--
稀に「全てAWSにすれば上手く行く」「AWSのCloudFront、S3、その他あれこれを使って設計するのがベストプラクティスだ」という主張を見かけます。
-->
確かに同一クラウドベンダで統一すれば各サービスは親和性が高く、設計ミスも自ずと減らせる場合もあります。

しかし重要なのは各コンポーネントの基本的な仕組みを理解し、要点を押さえた上で構築することです。
要点を抑えることで、自分たちが払えるコストやスキルセット等を加味し、適切なサービスを選択できます。

これらのポイントさえ押さえておけば、無理にCDNを特定にクラウドベンダのサービス（例えばCloudFront）にこだわる必要も、オリジンを同一クラウドベンダ内に置く必要もありません。