kenjuの日記

About Programming, Mathematics and Security

CloudFrontを経由してS3のPrivate Objectsを配信する実装方法まとめ

tl;dr

  • CloudFrontを経由してS3のPrivate Objectsを配信する実装方法には「署名付きURLを用いた認証」と「署名付きCookieを用いた認証」の2パターンが存在
  • サービスの要件として「絶対にURLの漏洩によるデータ流出のリスク」を避けなければならない場合、「署名付きCookie」の選択肢を取るしかない

背景

S3などのデータストレージに配備したコンテンツを、「有料会員」「Admin権限を有するユーザーのみ」「本人のみ」など、役割や権限ごとに管理したい場合がある。

その場合、インフラ構成として

  • データストレージはS3
  • CDNはCloudFront
  • Application ServerはEC2

を使っているとすると、大まかに以下の2つの選択肢がある。

  1. 署名付きURLを用いた認証
  2. 署名付きCookieを用いた認証

仕事で署名付きCookieを用いてPrivate Contentsを配信する必要が出たので、それぞれの選択肢の利点・欠点を整理してみる。

解決したい課題

S3 Objectsを、一部のユーザーのみに配信すること。

解決方法

“Private Cache Distribution”パターンを用いる。かいつまんで言うと、以下の流れ:

  • S3はエッジサーバー経由でのみコンテンツ配信を行う(つまり、ダイレクトアクセスを禁止する)
  • EC2(Application Server)側で、署名付きURL/Cookieを発行する
  • エッジサーバーで、署名付きURL/Cookieを有する場合のみ、S3 Objectsへのレスポンスを許可する

f:id:itiskj:20170802150747p:plain

(引用:CDP:Private Cache Distributionパターン - AWS-CloudDesignPattern

この実装方法として、

  1. 署名付きURLを用いた認証
  2. 署名付きCookieを用いた認証

の2つが存在する。署名付きURLを用いた認証と、署名付きCookieを用いた認証方法は若干要件が異なるため、自分たちの要件にあった認証方法を選択する必要がある。

docs.aws.amazon.com

1. 署名付きURLを用いた認証

利点

  • Cookie発行より考慮することが少ないため、実装がよりシンプル
  • 個別のファイルごとのアクセス制限が容易
  • ユーザーがCookieをサポートしていない場合でも対応できる(独自のHTTP Clientなど)

欠点

  • URLが漏洩した場合、誰でもアクセスできてしまう
    • もちろん、「短い時間だけ発行する」「共通の署名URLは決して発行せず、必ずユーザーごとに動的に署名付きURLを発行する」という対策はとれる。現実的にほぼセキュリティは担保できるかもしれないが、サービスの特性上「どれだけ短期間だとしても少しの漏洩リスクも許容できない(例:秘匿性の高い情報を扱うサービス)」場合、「署名付きCookieを用いた認証」を選択せざるを得ない

2. 署名付きCookieを用いた認証

利点

  • 個別のファイルごとではなく、複数の制限されたファイルごとに一括でアクセス管理したい場合に便利
  • 新しくURLを発行する必要が無いため、今まで公開していたコンテンツをPrivate化することもできる柔軟性を持つ
  • 署名付きURLより秘匿性が高い
    • Cookie漏洩リスクは依然として存在する点には注意。つまり、Cookieが漏れる弱点がアプリケーションの他の箇所にある場合、Private Contentsが漏洩する可能性が残る

欠点

  • 署名付きURLの発行よりは、EC2(Application Server)側での関心事が増えるため、実装コストが高い場合が多い