こんにちは!クラウドインフラやKubernetesの裏側で、日々飛び交うパケットの機嫌を取りながらSREをやっているライターの私です。
みなさんは、GCP(Google Cloud)の「Cloud CDN」を使ったことはありますか?世界中に張り巡らされたGoogleの巨大なネットワーク網を使って、ユーザーの近くから画像や動画などのコンテンツを爆速で配信してくれる、とっても頼もしいやつですよね。
さて、このCloud CDN、普段は「誰でも見られる公開ファイル」を高速化するのに使われがちですが、実は「限られた人だけに見せたい有料動画」や「社外秘の機密ドキュメント」を守るための、めちゃくちゃ強力なセキュリティ機能も持っているんです。
それが今回お話しする「署名付きURL(Signed URLs)」と「署名付きCookie(Signed Cookies)」です。
「なんだか名前からして難しそう……」「暗号とか署名とか、セキュリティの専門用語はいやだなぁ」と思ったそこのあなた!大丈夫です。一歩ずつ、私たちの身近な世界に置き換えて優しく紐解いていきましょう!
—
1. なぜ「秘密のコンテンツ」を守る仕組みが必要なの?
Cloud CDNの基本は、インターネットの海原にドカンと店を構えて、「誰が来ても同じファイルを高速で渡す」ことです。URLさえ知っていれば、地球の裏側からでも一瞬でアクセスできます。
でも、こんなシチュエーションを想像してみてください。
あなたがオンラインスクールを運営していて、会員だけが見られる高価なプログラミング講座の動画を配信しているとします。もし、その動画のURLがSNSで拡散されてしまったらどうなるでしょうか? お金を払っていない人たちに、見放題になって大赤字ですよね。
だからといって、アクセスするたびにサーバーで「この人は会員ですか?」と厳重にチェックしていたら、サーバーが悲鳴を上げてしまいますし、Cloud CDNを使う意味が薄れてしまいます。
「サーバーの負荷を上げずに、でもURLを知っているだけの人や、期限が切れた人はシャットアウトしたい!」
そんなわがままを華麗に叶えてくれるのが、今回の主役である「署名付きURL」なのです。
—
2. 郵便配達と「合言葉付きの鍵」でイメージしてみよう
この仕組みを、現実世界の「特別な郵便配達」に例えてみましょう。
通常のCloud CDNは、宛先(URL)さえ書かれていれば、郵便局員(エッジサーバー)は中身も見ずに配達してくれます。
これに対して「署名付きURL」は、封筒に「今日の日付まで有効で、さらにマスターの直筆サインが入った特殊な消印」が押してあるようなものです。
1. 発行する(サインをする):
サーバー側で、「このURLは〇月〇日の15:00まで有効ですよ」という情報と、誰にも真似できない「秘密のハンコ(暗号署名)」をURLの尻尾にくっつけてユーザーに渡します。
2. 配達する(確認する):
ユーザーがそのURLを使ってアクセスすると、Googleの世界中にあるエッジサーバー(郵便局)がそのハンコをペロッと確認します。
3. 判断する:
「お、ちゃんと本物のハンコが押してあるな! しかもまだ有効期限内だ。よし、中身を渡そう!」となります。もし期限が切れていたり、誰かが勝手にURLを書き換えたりしていれば、ハンコの辻褄が合わなくなるので、エッジサーバーは「ハイ、通行止め!」と一瞬で追い返します。
サーバーの本体までリクエストが届く前に、Googleのエッジ側で「ポイッ」と弾いてくれるので、オリジナルのサーバーが無駄な負荷を負わずに済むというわけですね。
—
3. 「署名付きURL」と「署名付きCookie」はどう使い分けるの?
ここで、「URLとCookie、どっちを使えばいいの?」という疑問が湧いてきますよね。基本の考え方はとてもシンプルです。
- 署名付きURL (Signed URLs):
- 向いている用途: 単体の画像、PDF、個別の動画ファイルなど。
- 特徴: ファイル1つ1つに個別のアドレスと有効期限をバシッと設定できます。
- 署名付きCookie (Signed Cookies):
- 向いている用途: 会員制サイトの動画ポータルや、たくさんの画像が並ぶWebアルバムなど。
- 特徴: 一度「パスポート(Cookie)」をブラウザに渡してしまえば、そのサイト内にある保護されたファイル群へ、わざわざURLを書き換えなくても一気にアクセスできるようになります。
「数個のファイルをピンポイントで守りたいならURL、サイト全体でガッチリ守るならCookie」と覚えておけば間違いありません!
—
4. 実務でどう設定する? ざっくりとした流れとコード例
「仕組みはわかったけど、実際にどう設定するの?」というエンジニアの方向けに、ざっくりとした構築の流れを見ていきましょう。
ステップの全体像
1. Cloud CDN(バックエンドバケットやバックエンドサービス)を有効にする。
2. 署名を作成するための「秘密鍵(Secret Key)」をGCP側(Cloud Storageやバックエンド)に登録する。
3. アプリケーション側(バックエンドのサーバーなど)で、ユーザーのログイン認証が終わったタイミングで、有効期限付きの署名入りURL(またはCookie)を動的に生成してユーザーに返す。
Pythonを使った署名付きURL生成のイメージ
実務では、バックエンドのプログラム(PythonやNode.jsなど)を使って署名付きURLを動的に作ることが多いです。PythonでGCP公式ライブラリを使うと、こんな感じで書くことができます。
import datetime
from google.cloud import storage
def generate_signed_url_for_cdn(bucket_name, blob_name, service_account_email, private_key_path):
"""
Cloud CDN(またはGCPストレージ)用の署名付きURLを生成するサンプル関数
"""
# ストレージクライアントの初期化(秘密鍵とサービスアカウントを使用)
storage_client = storage.Client.from_service_account_json(private_key_path)
bucket = storage_client.bucket(bucket_name)
blob = bucket.blob(blob_name)
# 有効期限の設定(ここでは「今から1時間後」に設定)
expiration_time = datetime.timedelta(hours=1)
# 署名付きURLを発行する
url = blob.generate_signed_url(
version="v4",
expiration=expiration_time,
method="GET",
# Cloud CDNのドメインを使う場合はここでホスト名を書き換えるなどの調整を行います
)
print(f"生成された署名付きURL: {url}")
return url
# 【使い方コメント】
# ユーザーがログインして「この動画を見たい」とリクエストした際に、
# この関数を呼び出して返されたURLをフロントエンドに渡してあげます。
このように、プログラム側で「いつまで有効か」を計算し、GCPの秘密鍵で暗号化されたハッシュをURLに付与してあげることで、安全なアクセス制御が実現できます。
—
5. 現場のSREが教える、ハマりやすい注意点
最後に、実務の現場でこの手のエッジセキュリティを導入した先輩たちが、思わず冷や汗をかいた「ハマりどころ」をいくつかシェアしておきますね。
1. サーバーとクライアントの「時計のズレ」に注意!
署名付きURLは「有効期限」が命です。もしユーザーの端末や、URLを発行するサーバーの時計が正確に同期されていないと、「まだ時間内のはずなのに期限切れと言われる」「未来の時間のURLができて弾かれた」というカオスなトラブルが起きます。NTPによる時刻同期はインフラの基本中の基本ですが、改めて確認しておきましょう。
2. CDNのキャッシュ戦略との兼ね合い
「署名付きURL」の大きなメリットは、URLごとにパラメータ(署名)が異なるため、「その署名が正しい場合のみ、CDNにキャッシュさせる」というスマートな動きができる点です。ただし、URLのクエリパラメータが少しでも変わると別物扱いになってキャッシュが効かなくなるため、CDN側のキー設定(Cache Key)には注意を払いましょう。
—
まとめ
今回は、Cloud CDNの「署名付きURL」と「署名付きCookie」について、郵便配達の仕組みに例えながら優しく解説しました。
- Cloud CDNの署名付きURL/Cookieは、URLに「期限付きの消印(暗号署名)」を押すことで、オリジナルのサーバーを汚さずに不正アクセスをブロックする技術。
- 個別のファイルならURL、サイト全体の保護ならCookieを使い分ける。
- サーバーの時刻同期と、動的なURL生成の仕組みを組み合わせることで、有料・機密コンテンツも安全に爆速配信できる!
最初は難しく見えるクラウドのセキュリティ機能も、こうして身近な仕組みに置き換えてみると、パケットたちがどんな気持ちでネットワークを駆け巡っているのかが見えてきてワクワクしてきませんか?
あなたのインフラ構築やアプリ開発の現場で、この知識が少しでもお役に立てれば嬉しいです。それでは、また次回の技術解説でお会いしましょう!
コメント