セキュアな「x-ch-no-bypass」トークンを使用して、DNSバイパス攻撃を防御する。

はじめに

このガイドでは、DNSバイパス攻撃からオリジンを保護する方法について説明します。以下の対策を実施することで、 x-ch-no-bypass CrowdHandlerとの統合において、ヘッダーは必須ではありませんが、オリジン側で検証の層を追加することになるため、使用することをお勧めします。

この記事は、どのような統合タイプに関連していますか?

「DNSバイパス攻撃」とは、具体的にどのようなものを指すのでしょうか?

CDNにCrowdHandlerを統合すると、CrowdHandlerによるチェックを回避することは困難になります。しかし、インフラに関するネットワーク情報を突き止めた執念深いユーザーであれば、CDNエンドポイントを迂回してトラフィックを送信し、CrowdHandlerの統合を含め、CDNが提供するすべての保護機能を回避できる可能性があります。

仕組み

設定が完了すると、CrowdHandler 統合により、 x-ch-no-bypass アプリケーションに転送されるすべてのリクエストに対して。その値は、バイパス防止トークンとなります。わずかなコードを記述するだけで、アプリケーションはリクエストに期待される値を持つヘッダーが含まれているかを確認し、含まれていないリクエストを拒否します。CrowdHandlerを通過したリクエストのみが、アプリケーションに到達します。

Appcelerator (DNS) の前に Cloudflare または Imperva を配置

DNSがCloudflareまたはImpervaを指しており、そのサービスがトラフィックをCrowdHandlerに転送している場合は、ドメインの セットアップの種類 CrowdHandlerのコントロールパネルでCloudflareまたはImpervaに設定します。このモードでは、CrowdHandlerは独自の x-ch-no-bypass ヘッダー。その代わりに、Cloudflare や Imperva で設定したヘッダーは、変更されることなくオリジンにそのまま渡されます。

オリジン側でその値を検証することで、リクエストがアップストリームサービスとCrowdHandlerの両方を通過したことが確認できます。CloudflareやImpervaを経由せずにCrowdHandlerに直接到達したリクエストは、ヘッダーがない状態でオリジンに到達するため、拒否されます。

「Setup Type」を「Direct DNS」のままにしておくと、CrowdHandler は独自のトークンを追加し、受信した同名のヘッダーを上書きします。

トークンはどこで確認できますか?

Appcelerator (DNS): CrowdHandler コントロールパネルでドメインの設定ページを開き、「オプション」を展開します。トークンは「No-Bypass Token」フィールドに記載されています。

セットアップタイプが「Cloudflare」または「Imperva」の場合、そのフィールドには「Relayed from Cloudflare」または「Relayed from Imperva」と表示されます。この場合、CrowdHandlerトークンは存在しません。検証すべき値は、アップストリームで設定した内容となります。

「No-Bypass Token」フィールドが表示されたオプションパネル

その他のCDNとの連携(Akamai、Cloudflare、CloudFront):それぞれのインストールガイドに、トークンの設定場所が記載されています。値は任意で設定してください。

統合の例

の有無と値を x-ch-no-bypass リクエストヘッダーは、ほとんどのプログラミング言語やWebサーバーにおいて、比較的単純です。以下を置き換えてください。 YOURTOKENVALUE トークンを使用して。

Apache

RewriteEngine On

# Block if the x-ch-no-bypass request header does not match
RewriteCond %{HTTP:x-ch-no-bypass} !^(YOURTOKENVALUE)$
RewriteRule ^ - [F]

Nginx

location / {

    if ($http_x_ch_no_bypass != "YOURTOKENVALUE") {
        return 403;
    }

    proxy_pass http://app:3000/;
}

Express.js

app.get('/', (req, res) => {
    if (req.header('x-ch-no-bypass') !== "YOURTOKENVALUE") {
        return res.status(403).send("Sorry! You can't see that.");
    }
    res.sendFile(__dirname + "/views/index.html");
});

PHP

function getRequestHeaders() {
    $headers = array();
    foreach ($_SERVER as $key => $value) {
        if (substr($key, 0, 5) <> 'HTTP_') {
            continue;
        }

        $header = str_replace(' ', '-', ucwords(str_replace('_', ' ', strtolower(substr($key, 5)))));
        $headers[$header] = $value;
    }
    return $headers;
}

$headers = getRequestHeaders();

if (($headers['X-Ch-No-Bypass'] ?? '') != "YOURTOKENVALUE") {
    header("HTTP/1.1 403 Forbidden");
    exit;
}

Python (Django)

from django.http import HttpResponseForbidden
from django.http import HttpResponse

def index(request):
    ch_bypass_key = request.META.get('HTTP_X_CH_NO_BYPASS')
    if ch_bypass_key != "YOURTOKENVALUE":
        return HttpResponseForbidden()
    return HttpResponse("Hello world!")

ヘッダーが保護するものと保護しないもの

その x-ch-no-bypass チェックはオリジン側で実行されるため、オリジンに到達したリクエストにのみ適用されます。このことから、次の2つのことが言えます。

待機室は常に厳格に適用されます。CrowdHandler は、キャッシュされたコンテンツへのリクエストを含め、他の処理が行われる前に、すべてのリクエストをエッジ側でチェックします。訪問者は、キャッシュされたコピーを見つけたとしても、キューをスキップすることはできません。

キャッシュされたコンテンツはオリジンチェックをスキップします。パスがキャッシュ対象に設定されている場合、最初のリクエストではオリジンからコンテンツが取得され、そこでヘッダーの検証が行われますが、それ以降のリクエストではオリジンに戻ることなく、CDNキャッシュからコンテンツが提供されます。 したがって、CDNを経由しなかったリクエストでは、そのパスのキャッシュ済みコピーが返される可能性があります。これはすべてのCDNキャッシュに共通する仕組みであり、CrowdHandler固有の仕様ではありません。リクエストごとにページの検証が必要な場合は、そのページに対してキャッシュを無効にしてください。Appceleratorの場合、これは「Advanced Behaviour Rules」内の「Cache Policy」列で設定します。新しいドメインはデフォルトで何もキャッシュされません。