ウェブアクセラレータを使ったコンテンツ保護

この記事はさくらインターネット Advent Calendar 2020 13日目の記事です。

ワンタイムURLを使ったコンテンツ保護

特定多数にコンテンツを配信したい場合、パスワード認証後にコンテンツを
ダウンロードしたりすることになると思います。

ただ、CDNと合わせて利用すると、BASIC認証が使えなかったり、URLを変えると
キャッシュも別のものとして扱われCDNを活用できないことがあります。

ウェブアクセラレータにはワンタイムURLという機能があるので、それを使った
コンテンツ保護をご紹介します。

ワンタイムURLって何?

ワンタイムURLは有効期限を決めたURLを発行する機能です。

  • ある時間までアクセス可能なURLのようなものを作ることができる
  • 有効期限を過ぎると403 Forbbidenとなる

どうやって使うの?

以下のマニュアルで公開していますが、実際に設定をしながら説明します。

Step1 非公開コンテンツの応答にシークレットを付与する

有効なワンタイムURL経由でのみアクセスしたいコンテンツの応答に
シークレット(秘密鍵)を返す設定をします。

今回はウェブサーバを用意するのが面倒なのでさくらのレンタルサーバを
使っていますが、Apacheであれば同様にできます。

今回は以下のようなディレクトリ構成です。

www
├── index.html
└── secret
    ├── .htaccess ← ここに記載
    ├── himitsu.jpeg
    └── himitsu.mp4

secretのディレクトリにあるコンテンツは非公開にしたいので、secretに入っている
.htaccessにシークレットのヘッダを応答するように書きます。

secretのディレクトリにあるコンテンツは1時間(3600秒)キャッシュしてほしい場合は
Cache-Controlで設定しておきます。

Header set X-WebAccel-Secret "Himi2NoSecret!"
Header set Cache-Control "s-maxage=3600"

応答するシークレットは他人に推測されない文字列を設定してください。

wwwの下のindex.htmlにはX-WebAccel-Secretのヘッダはつかないので通常通り
アクセスできます。

ここで、シークレットキーなのにアクセスされたらバレルやん!レンタルサーバに
直接アクセスしたらコンテンツ見えてしまうやん!って思った方は正解ですが、
それは、後ほど説明します。

Step2 ウェブアクセラレータに設定する

ウェブアクセラレータにサイトを作成して登録します。

今回はワンタイムURLのテストを行うだけなので、サブドメインで登録します。

登録したサイトを有効化をして、以下の状態になったことを確認します。

Step3 ウェブアクセラレータ経由でアクセスしてみよう

実際に公開ドメイン名でアクセスしてみましょう
https://xxxxxxx.user.webaccel.jp/

おそらく、www/index.htmlにあるものが表示されたと思います。
こちらにはX-WebAccel-Secretを付与していないので通常通り表示されます。

Step4 /secret/himitsu.jpgにアクセスしてみる

http://xxxxxxx.user.webaccel.jp/secret/himitsu.jpeg にアクセスしてみると

403 Forbbidenでアクセスできません

X-WebAccel-Secretに設定したシークレットを使ってURLを生成してみる。
こちらはURLを生成するPHPスクリプトです。

<?php
$base_url="http://xxxxxxx.user.webaccel.jp";
$file_path="/secret/himitsu.jpeg";
$secret = "Himi2NoSecret!";
$limit_time = sprintf("%08x", time()+600);  // 10分間(600s)有効

echo generateURL($base_url, $file_path, $secret, $limit_time) . "\n";

function generateURL($base_url, $file_path, $secret, $limit_time) {
    $md5 = md5("/" . $file_path . "/" . $secret . "/" . $limit_time ."/" );
    $url = $base_url . $file_path . "?webaccel_secure_time=" . $limit_time . "&webaccel_secure_hash=" . $md5;
    return $url;
}

このようなURLが生成できるはずなので、こちらを使ってアクセスしてみます。

http://xxxxxxx.user.webaccel.jp/secret/himitsu.jpeg?webaccel_secure_time=5fbdf873&webaccel_secure_hash=a82e1a55b2ec4da163a542e2354269f7

無事コンテンツが表示されました。

生成から10分の有効期限でURLを生成したので10分待ってみると・・・

無事Forbiddenとなりアクセスできませんでした。

このように一時的に有効なURL(ワンタイムURL)を使うことによって、同一コンテンツを
ウェブアクセラレータにキャッシュさせつつ、特定のユーザに配信することが可能になります。

しかし、レンタルサーバに直接アクセスすると・・・

もちろん・・・アクセスできてしまいます。
ウェブアクセラレータからの接続以外は拒否するようにしないといけません。
ウェブアクセラレータの接続元IPアドレスのみ許可する方法もありますが、
オリジンガードという機能が提供されていますので、それを利用してみます。

Step5 オリジンガードを設定しよう

ウェブアクセラレータのサイト設定にあるオリジンガードトークンを使います。

トークン発行を押すと以下のようなランダムなトークンが発行されます。

このトークンがオリジンへのリクエストに付与されるようになりますので、
このトークンがついているときのみ、アクセスを許可するようにします。

.htaccessを以下のように書き換えてみましょう

RewriteEngine On
RewriteCond %{HTTP:X-WebAccel-Guard} !^T0VAn64Kt8QD8crDEFPGqg$
RewriteRule ^(.*)$ - [F,L]
Header set X-WebAccel-Secret "Himi2NoSecret!"
Header set Cache-Control "s-maxage=3600"

直接アクセスができなくなりました。

まとめ

ウェブアクセラレータのワンタイムURL機能とオリジンガード機能を組み合わせることで、
一時的にアクセスできるURLを作ることができます。

有料コンテンツの配布に使うような、特定多数への配信にぜひご活用ください。

最後に

1月末ごろにLet’s Encryptの証明書を使ったSSL自動発行・更新機能がウェブアクセラレータに
リリースされる予定ですのでお楽しみに!