CDNで起きる問題

こんにちは マネックスラボのMです。

私はラボでサービスの企画~開発をしていますが、
いわゆるシステムエンジニアとかプロジェクトマネージャという役割の経験はあっても、
インフラの経験はありません。
CDNはインフラの領域だと勝手に思っていますが、
開発をする上で知っていなくてはいけないことだと思いますし、
実際にCDNに関係した問題にいくつか直面しましたのでその経験について記載したいと思います。

CDNとは

Content Delivery Network
詳しくはググれば分かりやすい記事がたくさん出てきますが
ざっくりまとめると以下のようなものです。
・世界各地にデータセンター(エッジサーバ)がある
・Webページなどのコンテンツの配信元はオリジンサーバと呼ばれる
・エッジサーバでオリジンサーバのWebページ、画像などをキャッシングすることで高速なインターネットを実現する
・DoS/DDoS攻撃などの攻撃に有効な防御策を保有している ※製品による

CDNシェア

Cloudflare
Amazon CloudFront
Akamai
の順で契約数が多く、この3つだけで90%近くを占めているそうです。
Cloudflareが圧倒的に多く、無料プランがあるため新興サイトなどに人気。
企業だけに絞るとAkamaiが人気らしいです。

直面した問題:フォーム送信が確実に行われない

実際に発生した問題であり、CDNを除外したことで解消した問題です。
ただし、私はCDN側の設定を調べ尽くしたわけではないため設定ミスによって起きていたという可能性もあります。

・システムAからシステムBにサーバ間のAPI通信
・認証に使用する変数をBodyにセットしてPOST送信
 ※AとBの間はインターネットに出る、かつCDNあり
という仕組みがありまして、当然普段は問題なく動作していました。
ある時にシステムBの担当者から「認証情報がないリクエストが来ている。」
という問い合わせが来て調査をしたのですが、原因が全く分かりませんでした。

事象として分かっていることは以下
・AからのリクエストがBに到達している
・Bが受信したフォーム(Body)が空である
・Aが受信したレスポンスは500 Internal Server ErrorでCDNから受信している
・Bはこのリクエストに対して400 認証エラーを返却しており500が返ることはありえない

受信しているエラーについてCDN側に問い合わせると以下の回答(要約)
・エッジサーバとオリジンサーバの間のTCPコネクションに異常があったかもしれない
・もしオリジンサーバが正常でもこれが起きたなら、エッジサーバの永続的コネクションを無効にするか、オリジンサーバよりも低く設定せよ
※これを読んだときに、オリジンであるBは簡単に手出しできるシステムではなかったため
見向きもしなかったのですが、この内容に忠実に対応したら解消したかもしれません。

起きている事象から想像すると
一定確率で以下のようなことになっているのではないかと推測しました。
・CDNはリクエストをBに送信している(がフォームは欠落している)
・CDNはレスポンスをBから受信する前にAに500 Internal Server Errorを返却している

そしてどう対応したかというと、AとBの間のインターネットおよびCDNを外しました。
※前述の対応案は見向きしなかったため、CDNが悪いと決めつけてかかっていました。
それによってこの事象は発生しなくなったのです。

直面した問題:DoS対策がサーバ間通信も対象になっていないか

CDNを利用する理由の一つに流量制限があるかと思います。
例えば、認証に使用するサーバに、クライアントからのアクセスと
サーバからのアクセスの両方がある場合
認証に使用するサーバのドメインに流量制限をかけると、
クライアントからのDoS攻撃対策になりますが
それだけだとサーバからの認証アクセスも制限の対象になってしまいます。
サーバからのアクセスは制限の対象から除外したりできるんですが、
パブリッククラウドなどを多用していると除外作業も大変です。
またCDN側の設定の管理も煩雑になるため実際にはCDN側で対応するのではなく、
そもそもサーバ間通信はCDNを通すべきではない。というのが一般的かもしれませんね。


当たり前だよね、っていう内容かもしれませんが、
いくつものシステムが、クラウドで絡み合うと結構難しくなってきます。
実際に直面している問題だったので記録兼ねて共有してみました。