カスタム Lua スクリプトを記述して Web リクエスト処理をインターセプトおよび変更し、Web Application Firewall (WAF) の組み込みルールを超えるセキュリティロジックを実装できます。設定可能なスクリプトとパラメーターにより、複雑なビジネス固有の要件にも、より柔軟に対応できます。
拡張機能の有効化
拡張機能を使用するには、次の手順で有効化します。
適用可能なエディション:この機能は、WAF Enterprise Edition、Ultimate Edition、および Pay-As-You-Go Edition でのみ利用できます。
課金:これは有料サービスです。課金方法は次のとおりです:
-
Pay-As-You-Go Edition:事前購入なしで直接使用できます。実際の使用量に基づいて追加料金が発生します。
-
Subscription Edition:使用する前に機能を購入する必要があります。
WAF 3.0コンソールにログインします。 上部のナビゲーションバーで、WAFインスタンスがデプロイされているリソースグループとリージョンを選択します。 中国本土または中国本土以外を選択します。
-
左側のナビゲーションペインで、 の順に選択します。
-
[今すぐ購入] をクリックし、画面の指示に従って機能を有効化します。
拡張の作成
拡張プラグイン ページで 拡張プラグインの新規作成 をクリックし、次のパラメーターを設定します。
-
[基本情報]:識別しやすい プラグイン名 と プラグインの説明 を入力します。
-
[プラグインコード]:ここにカスタムセキュリティロジックを実装するための Lua スクリプトを記述します。 例:API の詳細については、「付録:カスタム Lua スクリプト API リファレンス」をご参照ください。
-- カスタム Lua スクリプトの例:クエリパラメーターを抽出し、カスタムパラメーターと比較します。一致しない場合はブロックします。 -- 手順 1:リクエストパラメーターを抽出 local token = aliwaf.req.get_arg('token') -- 手順 2:カスタムパラメーターと比較 if token ~= params.token then aliwaf.func.punish() end重要-
WAF システムの安定性を確保するため、1 つの Lua スクリプトのリクエストあたりの実行時間は 2 ms に制限されています。デバッグテスト フェーズで実行時間がこの制限を超えると、スクリプトはテストに失敗し、作成は失敗します。実際のランタイムでは、リクエストに対するスクリプトの実行時間が 2 ms を超えると、その実行はスキップされます。
-
コードに機密情報 (キーなど) をハードコードしないでください。代わりに、以下の パラメーター定義 機能を使用してください。
-
-
パラメーター定義:スクリプト内のハードコードされた値を設定可能なパラメーターとして抽出し、ロジックとデータを分離します。これにより、コードを変更せずにポリシーを動的に調整でき、キーを安全に管理できます。パラメーターの追加 をクリックし、以下の設定を行います:
-
パラメーター名:スクリプトで参照される変数名です (例:
secret_key)。 -
パラメータータイプ:サポートされるタイプは、文字列、数値、ブール値、JSON オブジェクト、JSON 配列です。タイプがスクリプト内の処理ロジックと一致していることを確認してください。
-
パラメーターの説明:パラメーターの目的を記述します。
-
パラメーター値:以下の 2 つのモードをサポートします:
-
手動入力:値を直接入力します。
-
KMS シークレットを使用:Key Management Service (KMS) ですでに作成された認証情報を参照し、機密データを安全に保存します。WAF が認証情報を正常に参照するには、認証情報に以下のタグを付与する必要があります:
-
タグキー:
waf:access:enable -
タグ値:
true
-
-
-
-
デバッグテスト:
-
プラグイン処理パラメーター:現在は ブロック モードのみをサポートしています。このモードはリクエストをブロックします。
-
トラフィック パラメーター:実際の HTTP リクエストトラフィックをシミュレートします。パラメーターの追加 をクリックし、パラメーター名 (
method、uri、argsなど) と、対応する パラメーター値 を入力します。例:
methodをPOSTに、uriを/loginに設定して、ログインエンドポイントの保護ロジックをテストします。
-
-
実行結果:デバッグ実行 をクリックすると、システムはシミュレートされたトラフィックに対してスクリプトを実行し、結果を右側の 実行結果 パネルで確認できます。結果が失敗と表示された場合は、具体的なエラーメッセージに基づいてコードを修正してください。
次のステップ
拡張を作成した後、[カスタムルール]の保護テンプレートで参照してください。詳細については、「カスタムルール」をご参照ください。
日々の運用
拡張プラグイン ページでは、次の操作を実行できます。
-
プラグインリストの表示:すべての拡張機能を表示します。検索ボックスにプラグイン名を入力し、すばやく検索できます。
-
関連付けられた保護ルールの表示:目的のプラグインを見つけ、関連ルール 列の
アイコンをクリックすると、関連付けられた保護ルール ID が表示されます。ID をコピーして、Web コア保護 または セキュリティレポート ページで検索できます。 -
拡張機能の編集:目的のプラグインを見つけ、操作 列の編集 をクリックして、その設定を変更します。
-
拡張機能の削除:目的のプラグインを見つけ、操作 列の削除 をクリックして、拡張機能を削除します。
付録:カスタム Lua スクリプト API リファレンス
カスタム Lua スクリプト用のコアインターフェイスで、リクエストデータの読み取り、暗号化と復号、リクエストのフロー制御を扱います。
HTTP リクエストの例
POST /api/v1/orders?source=web&campaign=spring2024 HTTP/1.1
Host: shop.example.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)
Cookie: session_id=abc123xyz; user_prefs=lang%3Den%26theme%3Ddark
Content-Type: application/json
Content-Length: 51
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.xxxxx
Accept: application/json
{"product_id": 789, "quantity": 2, "urgent": true}
リクエストデータの読み取り
すべてのインターフェイスは文字列を返します。フィールドが存在しない場合は、空の文字列が返されます。
メソッドの読み取り
|
項目 |
タイプ |
説明 |
|
パラメーター |
- |
- |
|
戻り値 |
文字列 |
「GET」や「POST」などの HTTP リクエストメソッド。 |
-- POST --
local method = aliwaf.req.get_method()
URIの読み取り
|
項目 |
タイプ |
説明 |
|
パラメーター |
- |
- |
|
戻り値 |
文字列 |
リクエストの URI パス。 |
-- /api/v1/orders --
local uri = aliwaf.req.get_uri()
ドメインの読み取り
|
項目 |
タイプ |
説明 |
|
パラメーター |
- |
- |
|
戻り値 |
文字列 |
リクエストのホストドメイン名。 |
-- shop.example.com --
local domain = aliwaf.req.get_domain()
クエリの読み取り
|
項目 |
タイプ |
説明 |
|
パラメーター |
- |
- |
|
戻り値 |
文字列 |
リクエストの完全なクエリ文字列。 |
-- source=web&campaign=spring2024 --
local query = aliwaf.req.get_query()
クエリパラメーターの読み取り
|
項目 |
タイプ |
説明 |
|
パラメーター |
文字列 |
クエリパラメーター名。 |
|
戻り値 |
文字列 |
対応するパラメーター値。パラメーターが存在しない場合は、空の文字列 "" が返されます。 |
-- web --
local source = aliwaf.req.get_arg('source')
Cookieの読み取り
|
項目 |
タイプ |
説明 |
|
パラメーター |
文字列 |
Cookie 名。 |
|
戻り値 |
文字列 |
対応する Cookie 値。Cookie が存在しない場合は、空の文字列 "" が返されます。 |
-- abc123xyz --
local session_id = aliwaf.req.get_cookie('session_id')
ヘッダーの読み取り
|
項目 |
タイプ |
説明 |
|
パラメーター |
文字列 |
HTTP リクエストヘッダー名。 |
|
戻り値 |
文字列 |
対応するヘッダー値。ヘッダーが存在しない場合は、空の文字列 "" が返されます。 |
-- Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.xxxxx --
local auth = aliwaf.req.get_header('Authorization')
ボディの読み取り
リクエストボディのステータスの確認
-
ボディが完全に受信されたかどうか
項目
タイプ
説明
パラメーター
-
-
戻り値
ブール値
true はリクエストボディが完全に受信されたこと、false はまだ受信すべきデータがあることを示します。
local last = aliwaf.func.is_last_fragment_arrived() -
ボディが切り捨てられたかどうか
項目
タイプ
説明
パラメーター
-
-
戻り値
ブール値
true はリクエストボディが制限を超えて切り捨てられたこと、false はリクエストボディが完全であることを示します。
デフォルトでは、WAF はリクエストボディを最大 128 KB まで保存します。この制限を超えるリクエストは切り捨てられます (超過部分は破棄されます)。
local discard = aliwaf.func.is_request_body_discarded()
ボディの待機
リクエストボディは WAF にストリーミング方式で到着するため、スクリプトの実行時にボディがまだ完全に受信されていない可能性があります。完全なボディを処理するには、フレームワークに完全なボディを待機してからスクリプトを再実行するよう明示的に指示する必要があります。
|
項目 |
タイプ |
説明 |
|
パラメーター |
- |
- |
|
戻り値 |
- |
- |
aliwaf.func.wait_request_body()
例:リクエストボディの読み取り
-- ボディが完全に受信されていない場合、待機します --
if not aliwaf.func.is_last_fragment_arrived() then
aliwaf.func.wait_request_body()
return
end
-- ボディが完全に受信されたので、切り捨てられたかどうかを確認します --
if aliwaf.func.is_request_body_discarded() then
return
end
-- eyJwcm9kdWN0X2lkIjogNzg5LCAicXVhbnRpdHkiOiAyLCAidXJnZW50IjogdHJ1ZX0= --
local body = aliwaf.req.get_body()
-- TODO: 完全なボディに対してビジネスロジックを適用します --
一般的なユーティリティ関数
基本的なエンコーディングとデコーディング
URL、Hex、Base64 のエンコーディング/デコーディングインターフェイスは、文字列パラメーターを受け取り、処理された文字列を返します。失敗した場合は、空の文字列を返します。
URL エンコーディングとデコーディング
-
escape_uri
項目
タイプ
説明
パラメーター
文字列
エンコードする生の文字列。
戻り値
文字列
エンコードされた文字列。
-
unescape_uri
項目
タイプ
説明
パラメーター
文字列
デコードする URL エンコードされた文字列。
戻り値
文字列
デコードされた生の文字列。
-- a%20b を返します --
local data1 = aliwaf.util.escape_uri('a b')
-- a b を返します --
local data2 = aliwaf.util.unescape_uri('a%20b')
Hex エンコーディングとデコーディング
-
hex_encode
項目
タイプ
説明
パラメーター
文字列
エンコードするバイナリ文字列。
戻り値
文字列
大文字の Hex エンコードされた文字列。
-
hex_decode
項目
タイプ
説明
パラメーター
文字列
デコードする Hex 文字列。
戻り値
文字列
デコードされた生の文字列。入力が無効な場合は、空の文字列 "" を返します。
-- DEADBEEF を返します --
local data1 = aliwaf.util.hex_encode(string.char(0xDE, 0xAD, 0xBE, 0xEF))
-- \xDE\xAD\xBE\xEF を返します --
local data2 = aliwaf.util.hex_decode('DEADBEEF')
Base64 エンコーディングとデコーディング
-
base64_encode
項目
タイプ
説明
パラメーター
文字列
エンコードする生の文字列。
戻り値
文字列
Base64 エンコードされた文字列。
-
base64_decode
項目
タイプ
説明
パラメーター
文字列
デコードする Base64 文字列。
戻り値
文字列
デコードされた生の文字列。入力が無効な場合は、空の文字列 "" を返します。
-- aGVsbG8= を返します --
local data1 = aliwaf.util.base64_encode('hello')
-- hello を返します --
local data2 = aliwaf.util.base64_decode('aGVsbG8=')
MD5/CRC/SHA
-
md5
項目
タイプ
説明
パラメーター
文字列
ハッシュ化する生の文字列。
戻り値
文字列
32 文字の小文字 Hex 形式の MD5 ダイジェスト。
-
sha256
項目
タイプ
説明
パラメーター
文字列
ハッシュ化する生の文字列。
戻り値
文字列
64 文字の小文字 Hex 形式の SHA-256 ダイジェスト。
-
crc32
項目
タイプ
説明
パラメーター
文字列
計算する生の文字列。
戻り値
整数
CRC32 チェックサム (符号なし 32 ビット整数)。
-- 5d41402abc4b2a76b9719d911017c592 を返します --
local md5 = aliwaf.util.md5('hello')
-- 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824 を返します --
local sha = aliwaf.util.sha256('hello')
-- 3287646509 を返します --
local crc = aliwaf.util.crc32('hello')
暗号化と復号 (AES/DES)
-
evp_encrypt
項目
タイプ
説明
パラメーター 1
文字列
暗号化アルゴリズムのタイプ (例:「aes-128-cbc」)。
パラメーター 2
文字列
暗号化キー (バイナリセーフな文字列)。
パラメーター 3
文字列
初期化ベクトル。IV を使用しない場合は、空の文字列 "" を指定できます。
パラメーター 4
文字列
暗号化するプレーンテキスト。
戻り値
文字列
暗号化された暗号文。パラメーターが無効な場合や暗号化に失敗した場合は、空の文字列 "" を返します。
-
evp_decrypt
項目
タイプ
説明
パラメーター 1
文字列
復号アルゴリズムのタイプ。暗号化に使用したアルゴリズムと一致させる必要があります (例:「aes-128-cbc」)。
パラメーター 2
文字列
復号キー (バイナリセーフな文字列)。暗号化に使用したキーと一致させる必要があります。
パラメーター 3
文字列
初期化ベクトル。暗号化に使用した IV と一致させる必要があります。空の文字列 "" を指定できます。
パラメーター 4
文字列
復号する暗号文。
戻り値
文字列
復号されたプレーンテキスト。パラメーターが無効な場合や復号に失敗した場合は、空の文字列 "" を返します。
local data1 = aliwaf.util.evp_encrypt('aes-128-cbc', 'key-12345678-key', 'iv-1234567890-iv', 'hello')
local data2 = aliwaf.util.evp_decrypt('aes-128-cbc', 'key-12345678-key', 'iv-1234567890-iv', data1)
署名と検証 (ES256)
-
es256_sign
項目
タイプ
説明
パラメーター 1
文字列
PEM 形式の ES256 秘密キー。
パラメーター 2
文字列
署名する生のデータ。
戻り値
文字列
署名結果 (バイナリ文字列)。パラメーターが無効な場合や署名に失敗した場合は、空の文字列 "" を返します。
-
es256_verify
項目
タイプ
説明
パラメーター 1
文字列
PEM 形式の ES256 公開キー。
パラメーター 2
文字列
署名に使用した生のデータ (署名時に使用したデータと一致させる必要があります)。
パラメーター 3
文字列
検証する署名値 (es256_sign によって生成されたバイナリ文字列)。
戻り値
ブール値
true は署名検証が成功したことを示します。false は検証の失敗、またはパラメーターが無効であることを示します。
local sign = aliwaf.util.es256_sign('private_key-1234', 'hello')
local result = aliwaf.util.es256_verify('public_key-12345', 'hello', sign)
時刻
|
項目 |
タイプ |
説明 |
|
パラメーター |
- |
- |
|
戻り値 |
整数 |
現在のミリ秒単位の UNIX タイムスタンプ。 |
-- 現在のミリ秒単位のタイムスタンプ (整数) --
local timestamp = aliwaf.util.get_current_ms()
ビジネスヘルパー関数
ビジネスヘルパー関数は、Lua スクリプトと WAF フレームワーク間の連携を行います。
アクション
|
項目 |
タイプ |
説明 |
|
パラメーター |
- |
- |
|
戻り値 |
- |
- |
-- 事前に選択されたアクションに基づいて、現在のリクエストにアクションを実行します
aliwaf.func.punish()