AScript を使用すると、Application Load Balancer (ALB) 上でカスタム転送ルールを直接記述できます。このページでは、ホットリンク保護、IP ブラックリスト、リクエストヘッダーおよびレスポンスヘッダーの操作、URI の書き換え、リダイレクト、リクエストトラッキングなど、一般的なシナリオに対応したすぐに使用できるスクリプトを提供します。
AScript 機能はホワイトリスト登録制で提供しています。スクリプトを追加または変更するには、アカウントマネージャーまでお問い合わせください。
ホットリンク保護
.ts ファイルのカスタム認証
要件: 時刻ベースのダイジェスト方式を使用して .ts リクエストを検証します。リクエスト URL の形式は /path/digest/?.tskey=&t= です。
検証には次の 3 つのルールが適用されます。
-
ルール1: リクエストに
tまたはkeyパラメーターが欠落している場合、HTTP 403 を返し、失敗理由を記載したX-AUTH-MSGレスポンスヘッダーを追加します。 -
ルール2:
tパラメーターは絶対有効期限時刻です。tが現在時刻より前の場合、HTTP 403 を返し、X-AUTH-MSGを追加します。 -
ルール3: 計算された MD5 ダイジェストと URL 内の
digest値を比較します。一致しない場合、HTTP 403 を返します。
MD5 値の形式: プライベートキー + パス + ファイル名.拡張子
サンプルスクリプト:
if eq(substr($uri, -3, -1), '.ts') {
if or(not($arg_t), not($arg_key)) {
add_rsp_header('X-AUTH-MSG', 'auth failed - missing necessary arg')
exit(403)
}
t = tonumber($arg_t)
if not(t) {
add_rsp_header('X-AUTH-MSG', 'auth failed - invalid time')
exit(403)
}
if gt(now(), t) {
add_rsp_header('X-AUTH-MSG', 'auth failed - expired url')
exit(403)
}
pcs = capture_re($request_uri,'^/([^/]+)/([^/]+)/([^?]+)%?(.*)')
sec1 = get(pcs, 1)
sec2 = get(pcs, 2)
sec3 = get(pcs, 3)
if or(not(sec1), not(sec2), not(sec3)) {
add_rsp_header('X-AUTH-MSG', 'auth failed - malformed url')
exit(403)
}
key = 'b98d643a-9170-4937-8524-6c33514bbc23'
signstr = concat(key, sec1, sec3)
digest = md5(signstr)
if ne(digest, sec2) {
add_rsp_header('X-AUTH-DEBUG', concat('signstr: ', signstr))
add_rsp_header('X-AUTH-MSG', 'auth failed - invalid digest')
exit(403)
}
}
key の値 ('b98d643a-9170-4937-8524-6c33514bbc23') はプレースホルダーです。本番環境にデプロイする前に、実際のプライベートキーに置き換えてください。本番環境でサンプルキーを使用することはセキュリティリスクとなります。
User-Agent ブラックリスト
要件: User-Agent ヘッダーが ijkplayer または Ysten で始まるリクエストには、HTTP 403 を返します。
サンプルスクリプト:
if and($http_user_agent, match_re($http_user_agent, '^(ijkplayer|Ysten).*$')) {
add_rsp_header('X-BLOCKLIST-DEBUG', 'deny')
exit(403)
}
Referer ホワイトリスト
要件: Referer ヘッダーが http[s]://*alibaba.com* と一致しないリクエストには、HTTP 403 を返します。
サンプルスクリプト:
if and($http_referer, match_re($http_referer, '^(http|https)://(.)+\.alibaba\.com.*$')) {
return true
}
add_rsp_header('X-WHITELIST-DEBUG', 'missing')
exit(403)
IP ブラックリスト
要件: 127.0.0.1 または 10.0.0.1 からのリクエストには、HTTP 403 を返します。
サンプルスクリプト:
if match_re($remote_addr, '127.0.0.1|10.0.0.1') {
add_rsp_header('X-IPBLOCK-DEBUG', 'hit')
exit(403)
}
カスタムリクエストヘッダーおよびレスポンスヘッダー
ファイルダウンロード用の Content-Disposition 設定
要件: filename クエリパラメーターが存在する場合、ブラウザがその名前でファイルをダウンロードするように Content-Disposition を設定します。filename が存在しない場合は、デフォルトのファイル名が使用されます。
サンプルスクリプト:
if $arg_filename {
hn = 'Content-Disposition'
hv = concat('attachment;filename=', $arg_filename)
add_rsp_header(hn, hv)
}
ファイル名を引用符で囲む例:
add_rsp_header('Content-Disposition', concat('attachment;filename=', tochar(34), filename, tochar(34)))
レスポンスにContent-Disposition: attachmentを追加すると、ブラウザはメッセージ本文を自動的にダウンロードします。tochar(34)関数は、ASCII コードが 34 である二重引用符 (") を生成します。
出力:
Content-Disposition: attachment;filename="monitor.apk"
レスポンスヘッダーの上書き
要件: Content-Type レスポンスヘッダーの上書き。
サンプルスクリプト:
add_rsp_header('Content-Type', 'audio/mpeg')
URI の書き換え
このセクションのすべての書き換え例では 'break' モードを使用しており、オリジンサーバーへのリクエストとキャッシュキーで使われる URI を書き換えますが、クライアントに新しい HTTP リダイレクトは発行しません。
URI パスの書き換え
要件: /hello を /index.html に書き換えます。オリジンサーバーへのリクエストの URI とキャッシュ URI は /index.html に変更され、その他のパラメーターは変更されません。
サンプルスクリプト:
if match_re($uri, '^/hello$') {
rewrite('/index.html', 'break')
}
拡張子の書き換え
要件: /1.txt を /1.<type> に書き換えます。ここで、type は URL パラメーター type の値です。例えば、/1.txt?type=mp4 は /1.mp4?type=mp4 になります。
サンプルスクリプト:
if and(match_re($uri, '^/1.txt$'), $arg_type) {
rewrite(concat('/1.', $arg_type), 'break')
}
拡張子を小文字に正規化
要件: URI 文字列内の拡張子を小文字に変換します。
サンプルスクリプト:
pcs = capture_re($uri, '^(.+\.)([^.]+)')
section = get(pcs, 1)
postfix = get(pcs, 2)
if and(section, postfix) {
rewrite(concat(section, lower(postfix)), 'break')
}
URI プレフィックスの追加
要件: ^/nn_live/(.*) と一致するパスに /3rd を先頭に追加して書き換えます。例えば、/nn_live/foo は /3rd/nn_live/foo になります。
サンプルスクリプト:
pcs = capture_re($uri, '^/nn_live/(.*)')
sec = get(pcs, 1)
if sec {
dst = concat('/3rd/nn_live/', sec)
rewrite(dst, 'break')
}
リダイレクト
このセクションのすべてのリダイレクト例では、クライアントに HTTP 302 レスポンスを発行します。
ルートパスを特定ページへリダイレクト
要件: / へのリクエストを /app/movie/pages/index/index.html にリダイレクトします。
サンプルスクリプト:
if eq($uri, '/') {
rewrite('/app/movie/pages/index/index.html', 'redirect')
}
ルートパスを HTTPS URL へリダイレクト
要件: ルートパス ^/$ に一致するリクエストを https://aliyun.com にリダイレクトします。これは http://rtmp.cdnpe.com と https://rtmp.cdnpe.com の両方に適用されます。ターゲット URL は、必要に応じてご自身の URL に置き換えてください。
サンプルスクリプト:
if eq($uri, '/') {
rewrite('https://aliyun.com', 'redirect')
}
クエリパラメーターを削除してドメインをリダイレクト
要件: www.test.com へのリクエストを www.example.com にリダイレクトし、すべてのクエリパラメーターを削除します。
サンプルスクリプト:
if and(eq(req_header('Host'), 'www.test.com')) {
rewrite('www.example.com', 'redirect')
}
結果: 元のクエリパラメーターは削除されます。ただし、リダイレクト先の URL の末尾には ? が残ります。
| 元のリクエスト | リダイレクト先 |
|---|---|
http://www.test.com/path?a=1 |
http://www.example.com/path? |
末尾の ? を削除するには、代わりに enhance_redirect を使用します。
if and(eq(req_header('Host'), 'www.test.com')) {
rewrite('www.example.com', 'enhance_redirect')
}
| 元のリクエスト | リダイレクト先 |
|---|---|
http://www.test.com/path?a=1 |
http://www.example.com/path |
クエリパラメーターを保持してドメインをリダイレクト
要件: www.test.com へのリクエストを www.example.com にリダイレクトし、元のクエリパラメーターを保持します。
サンプルスクリプト:
if and(eq(req_header('Host'), 'www.test.com')) {
rewrite(concat('www.example.com', $uri), 'enhance_redirect')
}
| 元のリクエスト | リダイレクト先 |
|---|---|
http://www.test.com/path?a=1 |
http://www.example.com/path?a=1 |
URI サフィックスを使用したワイルドカードドメインマッチング
要件: test.com の任意のサブドメインへのリクエストのうち、URI に index.php がまだ含まれていないものに一致した場合、ホストに /index.php?s=<uri> を追加します。
サンプルスクリプト:
host_re = match_re(req_header('Host'), '.*.test.com')
url_match = null(find($uri, 'index.php'))
if and(host_re, url_match) {
rewrite(concat($host, '/index.php?s=', $uri), 'enhance_redirect')
}
HTTP から HTTPS へのリダイレクト、クエリパラメーターの削除
要件: http://www.test.com/tmp/?a=b を https://www.test.com にリダイレクトし、すべてのクエリパラメーターを削除します。
サンプルスクリプト:
host_re = match_re(req_header('Host'), 'www.test.com')
if and(req_scheme('http'), host_re) {
rewrite('https://www.test.com', 'enhance_redirect') # ステータスコード 302
}
url_match条件は、リクエスト URI に?が含まれているかを確認することで、リダイレクトループを防止します。 すでに HTTPS にリダイレクトされたリクエストはreq_scheme('http')に一致せず、パススルーされます。
| 元のリクエスト | リダイレクト先 |
|---|---|
http://www.test.com/tmp/?a=b |
https://www.test.com |
https://www.test.com/tmp/?a=b |
(リダイレクトされません) |
トラブルシューティング
リクエストトラッキング用の x-request-id の追加
要件: 一意の x-request-id ヘッダーを生成し、リクエストとレスポンスの両方に付加して、リクエストトラッキングとエラーの特定を簡素化します。
サンプルスクリプト:
requestid=md5(concat(rand(1, 10000), now()))
add_req_header('x-request-id', requestid)
add_rsp_header('x-request-id', requestid)
x-request-id の値は、乱数と現在のタイムスタンプを組み合わせた md5(concat(rand(1, 10000), now())) から導出されます。