【TIPS】特定のコンテンツを指定時間のみアクセス可能にしたい(ワンタイムURLを利用する)

ウェブアクセラレータで特定のコンテンツを指定時間、アクセス可能なURLを発行する方法に関するページです。

前提条件

  • オリジンサーバ側で、ワンタイムURL対象とするファイルや、ディレクトリのレスポンスヘッダにシークレットキー(X-WebAccel-Secret)を指定する設定が必須となります。
  • オリジンサーバ上の対象コンテンツに直接アクセスされた際のレスポンスヘッダには、シークレットキー(X-WebAccel-Secret)の情報が含まれます。
    第三者にシークレットキーを取得されないためにも、オリジンサーバには、ウェブアクセラレータからのアクセスのみ許可する オリジンガード機能 と併用してご利用下さい。
  • ウェブアクセラレータから配信されるコンテンツのレスポンスヘッダには、シークレットキー(X-WebAccel-Secret)は含まれません。
  • 2つ以上のシークレットキーを指定する場合は、シークレットキー(X-WebAccel-Secret)の値を「, (カンマ)」区切りで設定、もしくは、複数のシークレットキー(X-WebAccel-Secret)のヘッダを付与します。
    「, (カンマ)」が含まれる場合、区切り文字と判定されるため、シークレットキーの文字列としては使用できません。
  • 設定後、シークレットキーを変更した場合、ウェブアクセラレータのコントロールパネルからキャッシュ削除を実行して下さい。キャッシュ削除後から新しいシークレットキーが反映されます。
    配信を停止することなくシークレットキーを変更する場合は、 シークレットキーのローテーション手順 をご確認ください。

設定手順

STEP1 事前確認

  • ワンタイムURLの設定を入れる前に、正しくウェブアクセラレータが設定され、キャッシュされているのをご確認ください。
  • 本手順では、STEP4の項目で、オリジンガード機能を設定する様、案内をしておりますが、既にオリジンガードを利用中の場合はスキップして下さい。

STEP2 レスポンスヘッダの設定(オリジンサーバ側での作業)

ワンタイムURL対象のファイルやディレクトリのレスポンスヘッダにシークレットキーを付与する設定を行います。

Apache利用の場合(httpd.confや.htaccess等)

  • さくらのレンタルサーバなど、ウェブサーバ(Apache)の設定ファイルが編集出来ないサーバは、.htaccessへ記述することで利用可能です。
  • シークレットキーは任意の文字列になりますので、第三者に特定されない文字列にされることをお勧め致します。

ファイル対象

  • 以下の例では、対象のファイルが「/images/example.jpg」、シークレットキーを「secretkey」とした場合です。
<Files ~ "example\.jpg$">
  Header set X-WebAccel-Secret "secretkey"
</Files>

ディレクトリ対象

  • ワンタイムURL対象をファイルでなくディレクトリにする場合は、.htaccessに以下の記述を行い、対象ディレクトリ内に設置して下さい。
  • 以下の例では、シークレットキーを「secretkey」とした場合です。
Header set X-WebAccel-Secret "secretkey"

nginx利用の場合

  • シークレットキーは任意の文字列になりますので、第三者に特定されない文字列にされることをお勧め致します。
  • nginxには、locationのプレフィックスに優先順位がありますので、ご注意ください。優先順位を誤りますと、追加分のadd_headerが反映されない事があります。

ファイル対象

  • 以下の例では、対象のファイルが「/images/example.jpg」、シークレットキーを「secretkey」とした場合です。
location = /images/example.jpg {
  add_header x-webaccel-secret "secretkey";
}

ディレクトリ対象

  • ワンタイムURL対象をファイルでなくディレクトリにする場合は、「/images/」といった様に、ディレクトリ名を指定して下さい。
  • 以下の例では、シークレットキーを「secretkey」とした場合です。
location /images/ {
  add_header x-webaccel-secret "secretkey";
}

STEP3 レスポンスヘッダの確認

レスポンスヘッダが正しく設定できているか、オリジンサーバ内で確認します。

確認方法

  • オリジンサーバ上で、以下のコマンドを実行し、X-Webaccel-Secretが表示されるか確認します。
  • 以下の例は、ドメインが「cdn.example.com」、対象ファイルが「/images/example.jpg」、シークレットキーの文字列が「secretkey」の場合です。
# curl -v -o /dev/null -H 'Host: cdn.example.com' http://localhost/images/example.jpg

実行結果

・・ ・・ ・・ ・・ 一部省略 ・・ ・・ ・・ ・・
> GET /images/example.jpg HTTP/1.1     ←対象ファイル
> User-Agent: curl/7.29.0
> Accept: */*
> Host: cdn.example.com            ←対象ドメイン名
>
< HTTP/1.1 200 OK
< Server: nginx/1.13.6
< Date: Fri, 12 Jul 2019 11:27:12 GMT
< Content-Type: image/jpeg
< Content-Length: 108578
< Last-Modified: Fri, 14 Sep 2018 05:59:48 GMT
< Connection: keep-alive
< ETag: "**************"
< x-webaccel-secret: secretkey        ←設定したシークレットキー
< Accept-Ranges: bytes

STEP4 オリジンガード設定

オリジンサーバ上の対象ファイルに直接アクセスした場合、シークレットキー(X-WebAccel-Secret)がレスポンスヘッダに含まれます。
そのため直接オリジンサーバに接続されないよう、 オリジンガード機能 を設定します。

オリジンガード設定後の確認方法

  • オリジンガードが設定された後、オリジンサーバから、以下のコマンドを実行し、X-Webaccel-Secretが表示されず、「403 forbidden」が返されるか確認します。
  • 以下の例は、ドメインが「cdn.example.com」、対象ファイルが「/images/example.jpg」、シークレットキーの文字列が「secretkey」の場合です。
# curl -v -o /dev/null -H 'Host: cdn.example.com' http://localhost/images/example.jpg
上記で「403 forbidden」が返されるか確認して下さい。

STEP5 ワンタイムURLの生成

対象のファイルのワンタイムURLを生成します。
URLは、「シークレットキー」、「対象ファイルのURL」、有効期限を合わせて生成しますので、オリジンサーバ以外でも作成可能です。
よって、ウェブサイトや、ウェブアプリケーションに生成の機能を入れて利用することも可能です。

ワンタイムURL生成例(コマンド入力)

  • 以下の例は、対象のファイルのURLが「 http://cdn.example.com/images/example.jpg 」、シークレットキーの文字列が「secretkey」、有効期限が(2019 年 08 月 31 日 0 時 0 分まで有効)の場合になります。
  • ワンタイムURL対象をファイルでなくディレクトリにする場合は、「/images/」といった様に、ディレクトリ名を指定して下さい。

1.有効期限をUnixTimeで出力します。

# date -d '2019/08/31 00:00:00' +%s
1567177200

2.有効期限をHEX(16進数)に変換。

# printf "%x\n" 1567177200
5d6939f0

3.対象のファイルのパスと有効期限のHEX値、シークレットキーからハッシュ値(MD5)を生成します。

# echo -n "//images/example.jpg/secretkey/5d6939f0/" | openssl dgst -md5
(stdin)= 93ff0581a8f3a1812942dc8c956058a6
ファイルパス、シークレットキー、有効期限を / で連結し両端に / を付けたものをハッシュ値(MD5)にする。

4.URLと組み合わせれば有効期限まで有効なワンタイムURLが出来上がります。

形式:
http://example.com/images/example.jpg?webaccel_secure_hash="MD5の値"&webaccel_secure_time="HEX値"
URL
http://example.com/images/example.jpg?webaccel_secure_hash=93ff0581a8f3a1812942dc8c956058a6&webaccel_secure_time=5d6939f0

指定した有効期限内に、上記のURLでアクセスを行い、画像が表示されることをご確認下さい。

  • MD5、有効期限のHEXの指定が無い場合、もしくは間違っている場合は、「403 Forbidden」が返されます。
  • 正しいMD5、有効期限のHEXを指定しても、有効期限を過ぎた場合は、「403 Forbidden」が返されます。

ワンタイムURL生成例(スクリプト)

  • 以下の例は、対象のファイルのURLが「 http://cdn.example.com/images/example.jpg 」、シークレットキーの文字列が「secretkey」、有効期限は、下記スクリプト実行の10分後になります。
#!/bin/bash

base_url="http:\/\/cdn\.example\.com"
file_path="/images/example.jpg"
secret="secretkey"
limit_time=$(printf %x $(expr $(date +%s) + 600)) # 10分間(600s)有効

md5=$(echo -n "/$file_path/$secret/$limit_time/" | md5sum)

echo "${base_url}${file_path}?webaccel_secure_time=$limit_time&webaccel_secure_hash=${md5%% *}"

スクリプト実行結果

$ ./create_url.sh ←スクリプトのファイル名は任意です
http:/cdn.example.com/images/example.jpg?webaccel_secure_time=5d2d9453&webaccel_secure_hash=21d498aa696c35431cd2f0240d9eeb3a

指定した有効期限内に、上記のURLでアクセスを行い、画像が表示されることをご確認下さい。

  • MD5、有効期限のHEXの指定が無い場合、もしくは間違っている場合は、「403 Forbidden」が返されます。
  • 正しいMD5、有効期限のHEXを指定しても、有効期限を過ぎた場合は、「403 Forbidden」が返されます。

ワンタイムURL生成例(PHP)

  • 以下の例は、対象のファイルのURLが「 http://cdn.example.com/images/example.jpg 」、シークレットキーの文字列が「secretkey」、有効期限は、下記プログラムの実行の10分後になります。
  • ワンタイムURL対象をファイルでなくディレクトリにする場合は、「/images/」といった様に、ディレクトリ名を指定して下さい。
<?php
$base_url="http://cdn.example.com";
$file_path="/images/example.jpg";
$secret = "secretkey";
$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でアクセスを行い、画像が表示されることをご確認下さい。

  • MD5、有効期限のHEXの指定が無い場合、もしくは間違っている場合は、「403 Forbidden」が返されます。
  • 正しいMD5、有効期限のHEXを指定しても、有効期限を過ぎた場合は、「403 Forbidden」が返されます。

シークレットキーのローテーション手順

  • シークレットキーに2つの値を設定することで、配信を停止することなくシークレットキーを変更可能です。
  • 2つ以上のシークレットキーを指定する場合は、シークレットキー(X-WebAccel-Secret)の値を「, (カンマ)」区切りで設定、もしくは、複数のシークレットキー(X-WebAccel-Secret)のヘッダを付与します。
    「, (カンマ)」が含まれる場合、区切り文字と判定されるため、シークレットキーの文字列としては使用できません。

有効期限切れの前にシークレットをローテーションする手順

STEP1 初期状態

初期状態でシークレット「Key1」を設定しています。

有効期限 有効
オリジンに設定するシークレットキー
(X-WebAccel-Secret)
X-WebAccel-Secret: Key1
アクセスに使用するURL http(s)://example.com/foo?hash=${hash1}&time=${t1}
(Key1より生成したワンタイムURL)

STEP2 新しいシークレットの追加

有効期限(t1)を過ぎる前にオリジンの設定を変更して新しいシークレット「Key2」を追加します。
※ オリジンでの各設定方法については 設定手順 をご確認下さい。

有効期限 有効
オリジンに設定するシークレットキー
(X-WebAccel-Secret)
X-WebAccel-Secret: Key1,Key2 (※)
アクセスに使用するURL http(s)://example.com/foo?hash=${hash1}&time=${t1}
(Key1より生成したワンタイムURL)

※ 「X-WebAccel-Secret: Key1」「X-WebAccel-Secret: Key2」の2つのヘッダを付与する方法でも指定可能です。

STEP3 シークレットキーの反映

ウェブアクセラレータにキャッシュされたシークレットキー(X-WebAccel-Secret)を更新するため、
キャッシュを削除するかキャッシュ期限切れまで待ちます。

有効期限 有効
オリジンに設定するシークレットキー
(X-WebAccel-Secret)
X-WebAccel-Secret: Key1,Key2 (※)
アクセスに使用するURL http(s)://example.com/foo?hash=${hash1}&time=${t1}
(Key1より生成したワンタイムURL)

※ 「X-WebAccel-Secret: Key1」「X-WebAccel-Secret: Key2」の2つのヘッダを付与する方法でも指定可能です。

STEP4 ワンタイムURLの更新

サイト内のワンタイムURLを更新します。
※ オリジンでの各設定方法については 設定手順 をご確認下さい。

有効期限 有効
オリジンに設定するシークレットキー
(X-WebAccel-Secret)
X-WebAccel-Secret: Key1,Key2 (※)
アクセスに使用するURL http(s)://example.com/foo?hash=${hash2}&time=${t2}
(Key2より生成したワンタイムURL)

※ 「X-WebAccel-Secret: Key1」「X-WebAccel-Secret: Key2」の2つのヘッダを付与する方法でも指定可能です。

STEP5 古いシークレットキーの削除

オリジンの設定を変更して古いシークレットキー(X-WebAccel-Secret)を削除します。
ウェブアクセラレータにキャッシュされたシークレットキー(X-WebAccel-Secret)を更新するため、
キャッシュを削除するかキャッシュ期限切れまで待ちます。
※ オリジンでの各設定方法については 設定手順 をご確認下さい。

有効期限 有効
オリジンに設定するシークレットキー
(X-WebAccel-Secret)
X-WebAccel-Secret: Key2
アクセスに使用するURL http(s)://example.com/foo?hash=${hash2}&time=${t2}
(Key2より生成したワンタイムURL)

有効期限が切れてしまった後にシークレットを更新する手順

STEP1 初期状態

初期状態でシークレット「Key1」を設定しています。

有効期限 有効
オリジンに設定するシークレットキー
(X-WebAccel-Secret)
X-WebAccel-Secret: Key1
アクセスに使用するURL http(s)://example.com/foo?hash=${hash1}&time=${t1}
(Key1より生成したワンタイムURL)

STEP2 ワンタイムURLの有効期限切れ

ワンタイムURLの有効期限(t1)を過ぎている状態では、アクセスすると403応答となり配信できません。

有効期限 期限切れ
オリジンに設定するシークレットキー
(X-WebAccel-Secret)
X-WebAccel-Secret: Key1
アクセスに使用するURL http(s)://example.com/foo?hash=${hash1}&time=${t1}
(Key1より生成したワンタイムURL)

STEP3 シークレットキー更新

オリジンの設定を変更してシークレットキー(X-WebAccel-Secret)を更新します。
※ オリジンでの設定方法については 設定手順 をご確認下さい。
ウェブアクセラレータにキャッシュされたシークレットキー(X-WebAccel-Secret)を更新するため、
キャッシュを削除するかキャッシュ期限切れまで待ちます。

有効期限 期限切れ
オリジンに設定するシークレットキー
(X-WebAccel-Secret)
X-WebAccel-Secret: Key2
アクセスに使用するURL http(s)://example.com/foo?hash=${hash1}&time=${t1}
(Key1より生成したワンタイムURL)

STEP4 ワンタイムURL更新

サイト内のワンタイムURLを更新します。
※ オリジンでの設定方法については 設定手順 をご確認下さい。

有効期限 有効
オリジンに設定するシークレットキー
(X-WebAccel-Secret)
X-WebAccel-Secret: Key2
アクセスに使用するURL http(s)://example.com/foo?hash=${hash2}&time=${t2}
(Key2より生成したワンタイムURL)