こんにちは!インフラやセキュリティの世界へようこそ。
初めてサーバーを構築したり、自分が作ったWebサイトをインターネットに公開したりする時って、ワクワクしますよね。でも同時に、「世界中からサイバー攻撃を受けたらどうしよう…」と、夜も眠れなくなるような不安を感じる方も多いのではないでしょうか。
実は、インターネットの世界は、私たちが暮らしている現実の街とそっくりです。
あなたが建てた素敵な一軒家(Webサーバー)に、世界中から「泥棒」や「セールスの勧誘」がやってくるイメージを持ってみてください。正面玄関の鍵をしっかりかけるのは当然ですが、もし玄関の前で怪しい人物を追い払えたら、家の中まで入られずに済んで安心ですよね?
今回は、クラウドの最前線である「エッジ(CDN)」という仕組みを使って、サーバーを守る強力な門番を置く方法について、一歩ずつ優しく学んでいきましょう!
—
1. エッジセキュリティ(CDN)ってなに? 家の防犯に例えてみよう
私たちが普段使っているAWSの CloudFront などのCDN(コンテンツ配信ネットワーク)は、いわば「あなたの家の外構(敷地の入り口)」のようなものです。
もしCDNを使わずにサーバーを公開していると、世界中からやってきたアクセスが直接、あなたのサーバーの玄関ドアをガチャガチャとノックすることになります。これでは、悪意ある大量のアクセス(DDoS攻撃など)が来たら、サーバーはすぐにパンクしてしまいますよね。
そこで、敷地の入り口(世界中に散らばるCDNのエッジサーバー)に、屈強な門番を立たせるのです。
この門番は、怪しい人物を見つけたら、「おっと、君は怪しいから中には通せないよ!」とその場で追い返してくれます。これが、エッジレベルでの攻撃遮断の基本概念です。
—
2. 地理的制限(Geo-blocking)で不審な国からの侵入を防ぐ
門番の仕事の1つに、「特定の地域からの客お断り」があります。これをセキュリティ用語で地理的制限(Geo-blocking)と呼びます。
例えば、あなたのサービスが「日本国内向け」のサービスだとします。その場合、普段の生活ではあまりアクセスしてこないような国から、大量のアクセスが来るのは不自然ですよね。
もちろん、海外にいる正当なユーザーを弾いてしまうリスク(誤検知)もあるため慎重になる必要がありますが、「明らかに攻撃元として有名な国からのアクセスをシャットアウトする」というアプローチは、初期の防犯対策として非常に効果的です。
CloudFront などのCDNでは、マネジメントコンソールやIaC(Infrastructure as Code)を使って、非常に簡単な設定で特定の国からのアクセスをブロックできます。例えば、AWSのTerraformを使う場合、以下のような設定を書くことで国ごとの制限が可能です。
# CloudFrontディストリビューションにおける地理的制限(Geo-blocking)の例
# 日本国内のみからのアクセスを許可し、それ以外をブロックする設定です
resource "aws_cloudfront_distribution" "my_app_distribution" {
# ...(中略:オリジンや証明書などの基本設定)...
restrictions {
geo_restriction {
# 許可または制限する方法を指定します ("whitelist" または "blacklist")
restriction_type = "whitelist"
# ホワイトリスト方式なので、ここに指定した国のコード以外は全て遮断されます
items = ["JP"]
}
}
# ...(中略)...
}
このように設定しておくだけで、日本以外の国からのアクセスは、あなたのサーバーのドアを叩くことすらできず、エッジの段階でピシャリと追い返されます。サーバーのCPUやメモリを無駄に消費せずに済むため、リソースの節約にもなるんです。
—
3. 恐怖の「キャッシュ汚染」とは? 防犯における「毒見役」の話
さて、CDNのもう一つの重要な機能に「キャッシュ」があります。これは、一度アクセスされたページの写真(画像やHTML)を門番の手元にコピーしておき、2人目以降の客にはサーバーの代わりに門番が素早く渡す仕組みです。毎回サーバーまで行かなくて済むので、表示スピードが劇的に速くなります。
しかし、ここに一つ大きな罠があります。それが「キャッシュ汚染(Cache Poisoning)」です。
もし、悪意ある攻撃者が、ちょっとおかしな細工をしたリクエストを送り、それが門番のキャッシュとして保存されてしまったらどうなるでしょうか?
そのあと、次にやってきた普通の一般ユーザーが、その「おかしなキャッシュ」を門番から渡されてしまい、サイトが改ざんされたり、おかしな挙動を引き起こしたりしてしまうのです。これは、まるで門番が毒入りの料理をそのままお客さんに配ってしまうようなものですよね。
これを防ぐためには、CDNの門番に対して「どの情報を見てキャッシュを分けるべきか(Cache Key)」を細かく教えてあげる必要があります。
防御のためのヘッダー設定
サーバーからCDNに対して、「このデータは誰がアクセスしても同じだからキャッシュしていいよ」「でも、このリクエストパラメータが含まれている時は、別物として扱ってね」と伝えるために、HTTPレスポンスヘッダーを活用します。
例えば、PHPや各種Webサーバーの設定で、以下のようなヘッダーを意識してみましょう。
<?php
// PHPでのキャッシュ制御ヘッダー出力の例
// 攻撃者がURLのパラメータ等を利用してキャッシュを汚染するのを防ぐため、
// キャッシュのキーに含めるべきヘッダーをCDNに伝えます。
// このページは動的なコンテンツを含むため、安易にCDN側で不正なパラメータ付きのキャッシュをさせない
header("Vary: Accept-Encoding, User-Agent, X-Custom-Security-Token");
// ブラウザやCDNに対するキャッシュの有効期限(例: 60秒間のみ許可)
header("Cache-Control: public, max-age=60, s-maxage=60");
?>
このように、Vary ヘッダーなどを適切に設定してあげることで、CDNの門番は「おっ、さっきの人とパラメータが違うから、これは別の料理として新しくサーバーに取りに行こう!」と判断できるようになり、キャッシュ汚染を防ぐことができるのです。
—
4. 一歩ずつ、確実なセキュリティ対策を
今回は、エッジセキュリティ(CDN)を用いた攻撃の分散と遮断について、地理的制限やキャッシュ汚染の対策を交えてお話ししましたがいかがでしたでしょうか?
「難しそう…」と感じた方もいるかもしれませんが、セキュリティの基本は現実世界の防犯と同じです。
1. 怪しい客は敷地の入り口(エッジ)でシャットアウトする(Geo-blockingなど)
2. 門番が渡すキャッシュが汚されないように、正しいルール(ヘッダー設定)を教え込む
この2つを意識するだけでも、あなたのWebサイトの安全性は段違いに向上します。
完璧な要塞を一度に作る必要はありません。まずは身近なところから、一歩ずつ設定を見直して、安全なインフラ環境を育てていきましょうね!
コメント