RFC 9440 ↗ は、クライアント証明書の情報をオリジンサーバーへ渡すための HTTP ヘッダーフィールド Client-Cert と Client-Cert-Chain を定義しています。これらのヘッダーは、リクエストヘッダー変更ルール と次の Ruleset Engine フィールドを使って組み立てできます。
cf.tls_client_auth.cert_rfc9440— RFC 9440 形式でエンコードしたクライアントのリーフ証明書です(リファレンスを参照)。cf.tls_client_auth.cert_chain_rfc9440— RFC 9440 形式でエンコードした証明書チェーンです(リーフ証明書は含みません。リファレンスを参照)。
フィールド定義のとおり、これらのフィールドは空文字列、または有効な RFC 9440 エンコードのいずれかになります。適切に使うには、以降のセクションで説明するいくつかの点を確認します。
cert_rfc9440 と cert_chain_rfc9440 フィールドは、証明書の検証結果に関係なく 値が入ります。つまり、クライアントが無効、期限切れ、または自己署名の証明書を提示しても、フィールドにはエンコードされた証明書データが入ります。値を信頼する前に、必ず次のフィールドを確認します。
cf.tls_client_auth.cert_verified— クライアント証明書が有効なときにtrueを返します。cf.tls_client_auth.cert_revoked— クライアント証明書が失効しているときにtrueを返します。
クライアントは、リクエストに独自の Client-Cert または Client-Cert-Chain ヘッダーを付けて、任意の値を注入できます。RFC 9440 のセキュリティ上の考慮事項 ↗ にあるとおり、証明書の有効性に関係なく、受信リクエストから既存の Client-Cert および Client-Cert-Chain ヘッダーを無条件に削除する必要があります。これにより、オリジンが信頼してしまう偽造証明書データの注入を防げます。
mTLS と証明書検証の設定方法は、mTLS を有効にする を参照してください。
エンコード後のリーフ証明書は 10 KiB、エンコード後のチェーンは 16 KiB が上限です。エンコード値が上限を超えると、対応するフィールドは空文字列になります。この状態は、次のフィールドで確認できます。
cf.tls_client_auth.cert_rfc9440_too_large— エンコードした証明書が 10 KiB を超えるときにtrueを返します。cf.tls_client_auth.cert_chain_rfc9440_too_large— エンコードしたチェーンが 16 KiB を超えるときにtrueを返します。
ここでは、これらのフィールドを安全に使い、信頼できる Client-Cert および Client-Cert-Chain ヘッダーを組み立ててオリジンへ転送する例を示します。
オリジンは、ヘッダーがあることをもって、クライアントが有効な証明書を提示したと判断できます。
注: クライアントが中間証明書を提示せず、リーフ証明書だけを提示した場合、Client-Cert-Chain ヘッダーは省略できます。
次のリクエストヘッダー変更ルールを作成します。 Remove ルールは Set dynamic ルールより前に置く必要があります。 クライアントが注入したヘッダーを、検証済みの値を設定する前に、すべてのリクエストから取り除くためです。
このルールは、クライアントが送った Client-Cert ヘッダーを無条件に削除します。
Expression Editor のテキスト:
trueModify request header で選ぶ操作: Remove
Header name: Client-Cert
このルールは、クライアントが送った Client-Cert-Chain ヘッダーを無条件に削除します。
Expression Editor のテキスト:
trueModify request header で選ぶ操作: Remove
Header name: Client-Cert-Chain
このルールは、クライアントが有効かつ未失効で、サイズ制限内の証明書を提示した場合にだけ、Client-Cert ヘッダーを設定します。
Expression Editor のテキスト:
cf.tls_client_auth.cert_verified
and not cf.tls_client_auth.cert_revoked
and not cf.tls_client_auth.cert_rfc9440_too_largeModify request header で選ぶ操作: Set dynamic
Header name: Client-Cert
Value: cf.tls_client_auth.cert_rfc9440
このルールは、クライアントが有効かつ未失効の証明書を提示し、チェーンが空でなくサイズ制限内である場合にだけ、Client-Cert-Chain ヘッダーを設定します。
Expression Editor のテキスト:
cf.tls_client_auth.cert_verified
and not cf.tls_client_auth.cert_revoked
and cf.tls_client_auth.cert_chain_rfc9440 ne ""
and not cf.tls_client_auth.cert_chain_rfc9440_too_largeModify request header で選ぶ操作: Set dynamic
Header name: Client-Cert-Chain
Value: cf.tls_client_auth.cert_chain_rfc9440
Cloudflare Worker でも、受信リクエストの tlsClientAuth プロパティを使い、RFC 9440 ヘッダーを組み立てできます。
上記と同じセキュリティ上の考慮事項が適用されます。
ホストに mTLS 認証を適用するだけでなく、クライアント証明書を HTTP ヘッダーとしてオリジンサーバーへ転送できます。この構成は、サーバーログに使うことがよくあります。
すべてのリクエストに証明書を付けないように、証明書は mTLS 接続の最初のリクエストでのみ転送されます。
証明書を転送する最も一般的な方法は、Cloudflare API で mTLS 証明書のホスト名設定を更新 することです。
Required API token permissions
At least one of the following token permissions is required:Access: Mutual TLS Certificates Write
curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/access/certificates/settings" \
--request PUT \
--header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
--json '{
"settings": [
{
"hostname": "<HOSTNAME>",
"china_network": false,
"client_certificate_forwarding": true
}
]
}'client_certificate_forwarding を true に設定すると、mTLS 接続内のすべてのリクエストに次のヘッダーが付きます。
Cf-Client-Cert-Der-Base64Cf-Client-Cert-Sha256
Managed Transforms で HTTP レスポンスヘッダーを変更 し、TLS クライアント認証ヘッダー を渡すこともできます。
加えて、Workers では クライアント証明書 に関する詳細を取得できます。
const tlsHeaders = {
"X-CERT-ISSUER-DN": request.cf.tlsClientAuth.certIssuerDN,
"X-CERT-SUBJECT-DN": request.cf.tlsClientAuth.certSubjectDN,
"X-CERT-ISSUER-DN-L": request.cf.tlsClientAuth.certIssuerDNLegacy,
"X-CERT-SUBJECT-DN-L": request.cf.tlsClientAuth.certSubjectDNLegacy,
"X-CERT-SERIAL": request.cf.tlsClientAuth.certSerial,
"X-CERT-FINGER": request.cf.tlsClientAuth.certFingerprintSHA1,
"X-CERT-VERIFY": request.cf.tlsClientAuth.certVerify,
"X-CERT-NOTBE": request.cf.tlsClientAuth.certNotBefore,
"X-CERT-NOTAF": request.cf.tlsClientAuth.certNotAfter,
};