HMAC 署名ヘッダーの設定ガイド
Miterl からの監視リクエストに署名ヘッダーを付与し、お客様の WAF / CDN 側で正規のリクエストとして除外する方法を説明します。
動作の仕組み
監視を「HMAC 署名」を有効にした状態で発行すると、Miterl のプローブはすべての HTTP リクエストに署名ヘッダーを付与します。形式は以下のとおりです(Stripe Webhook 流儀)。
X-Miterl-Signature: t=1714112000,v1=a3b1...d9ヘッダー名はデフォルトで X-Miterl-Signature ですが、変更可能です。
- t は Unix タイムスタンプ(リプレイ攻撃を防ぐ目的で使えます)
- v1 は HMAC-SHA256(secret, "<t>.<METHOD>.<PATH>") の hex 文字列
- クエリ文字列は署名対象に含まれません
設定手順
- Miterl の監視編集画面で「HMAC 署名」を有効にし、「自動生成」でシークレットを発行してください(または任意の文字列を入力)。
- 発行されたシークレットを安全な場所に保管します(再表示はできません)。
- 下記の WAF / CDN 設定例を参考に、お客様の環境にルールを追加してください。
Cloudflare WAF の設定例
Pro プラン以上で WAF Custom Rules が利用できます。Free プランでは Bot Fight Mode の完全なバイパスはできません。
# Cloudflare WAF Custom Rule (Pro plan or above)
# Field: HTTP Header → "X-Miterl-Signature"
# Operator: matches regex
# Value: ^t=\d+,v1=[a-f0-9]{64}$
# Action: Skip → All remaining custom rules + Bot Fight ModeAWS WAF の設定例
WebACL に Allow ルールを優先度 0 で追加すると、署名付きリクエストを最優先で許可できます。
# AWS WAF Rule (JSON snippet)
{
"Name": "AllowMiterlProbes",
"Priority": 0,
"Action": { "Allow": {} },
"Statement": {
"ByteMatchStatement": {
"FieldToMatch": { "SingleHeader": { "Name": "x-miterl-signature" } },
"PositionalConstraint": "STARTS_WITH",
"SearchString": "t=",
"TextTransformations": [{ "Priority": 0, "Type": "NONE" }]
}
}
}Nginx の設定例
# nginx (skip rate limiting / ModSecurity for signed requests)
map $http_x_miterl_signature $is_miterl_probe {
~^t=\d+,v1=[a-f0-9]{64}$ 1;
default 0;
}
server {
location / {
if ($is_miterl_probe) {
# bypass rules — set whatever flag your stack reads
set $skip_modsec 1;
}
# ...
}
}オリジン側で署名を検証する(任意)
ヘッダーの存在チェックだけでも実用上は十分ですが、より確実にするためにオリジン側で HMAC を検証することもできます。PHP のサンプルです。
<?php
// On your origin: verify the signature is genuinely from Miterl.
// Use this if you want stronger assurance than "header exists".
\$header = \$_SERVER['HTTP_X_MITERL_SIGNATURE'] ?? '';
if (! preg_match('/^t=(\d+),v1=([a-f0-9]{64})\$/', \$header, \$m)) {
http_response_code(401); exit;
}
[\$_, \$ts, \$sig] = \$m;
if (abs(time() - (int) \$ts) > 300) {
http_response_code(401); exit; // replay protection: 5min window
}
\$secret = getenv('MITERL_HMAC_SECRET');
\$expected = hash_hmac('sha256', "{\$ts}.{\$_SERVER['REQUEST_METHOD']}.{\$_SERVER['REQUEST_URI']}", \$secret);
if (! hash_equals(\$expected, \$sig)) {
http_response_code(401); exit;
}よくある質問
シークレットをローテーションするには?
監視編集画面で「自動生成」を再度クリックして上書き保存してください。すぐに新しいシークレットで署名するようになります。
シークレットが漏洩した場合は?
上記と同様に再生成してください。漏洩したシークレットは無効になります。WAF 側のルールはヘッダーの存在チェックだけなら変更不要です。
URL のクエリ文字列を含めて署名できますか?
現状は署名対象が <METHOD>.<PATH> のみです。WAF キャッシュキーで揺れる可能性を避けるためです。