Skip to content

非公式本サイトは非公式の日本語ドキュメントであり、Cloudflare 公式サイトではありません。最新情報はdevelopers.cloudflare.comをご確認ください。

証明書をサーバーへ転送する

最終更新 Markdown で表示Agent セットアップ

Client-Cert および Client-Cert-Chain ヘッダーを追加する(RFC 9440)

RFC 9440 は、クライアント証明書の情報をオリジンサーバーへ渡すための HTTP ヘッダーフィールド Client-CertClient-Cert-Chain を定義しています。これらのヘッダーは、リクエストヘッダー変更ルール と次の Ruleset Engine フィールドを使って組み立てできます。

  • cf.tls_client_auth.cert_rfc9440 — RFC 9440 形式でエンコードしたクライアントのリーフ証明書です(リファレンスを参照)。
  • cf.tls_client_auth.cert_chain_rfc9440 — RFC 9440 形式でエンコードした証明書チェーンです(リーフ証明書は含みません。リファレンスを参照)。

フィールド定義のとおり、これらのフィールドは空文字列、または有効な RFC 9440 エンコードのいずれかになります。適切に使うには、以降のセクションで説明するいくつかの点を確認します。

セキュリティ上の考慮事項

cert_rfc9440cert_chain_rfc9440 フィールドは、証明書の検証結果に関係なく 値が入ります。つまり、クライアントが無効、期限切れ、または自己署名の証明書を提示しても、フィールドにはエンコードされた証明書データが入ります。値を信頼する前に、必ず次のフィールドを確認します。

クライアントは、リクエストに独自の Client-Cert または Client-Cert-Chain ヘッダーを付けて、任意の値を注入できます。RFC 9440 のセキュリティ上の考慮事項 にあるとおり、証明書の有効性に関係なく、受信リクエストから既存の Client-Cert および Client-Cert-Chain ヘッダーを無条件に削除する必要があります。これにより、オリジンが信頼してしまう偽造証明書データの注入を防げます。

mTLS と証明書検証の設定方法は、mTLS を有効にする を参照してください。

サイズ制限

エンコード後のリーフ証明書は 10 KiB、エンコード後のチェーンは 16 KiB が上限です。エンコード値が上限を超えると、対応するフィールドは空文字列になります。この状態は、次のフィールドで確認できます。

Transform Rules の例

ここでは、これらのフィールドを安全に使い、信頼できる Client-Cert および Client-Cert-Chain ヘッダーを組み立ててオリジンへ転送する例を示します。 オリジンは、ヘッダーがあることをもって、クライアントが有効な証明書を提示したと判断できます。 注: クライアントが中間証明書を提示せず、リーフ証明書だけを提示した場合、Client-Cert-Chain ヘッダーは省略できます。

次のリクエストヘッダー変更ルールを作成します。 Remove ルールは Set dynamic ルールより前に置く必要があります。 クライアントが注入したヘッダーを、検証済みの値を設定する前に、すべてのリクエストから取り除くためです。

ルール 1 — Client-Cert ヘッダーを削除する

このルールは、クライアントが送った Client-Cert ヘッダーを無条件に削除します。

Expression Editor のテキスト:

true

Modify request header で選ぶ操作: Remove

Header name: Client-Cert

ルール 2 — Client-Cert-Chain ヘッダーを削除する

このルールは、クライアントが送った Client-Cert-Chain ヘッダーを無条件に削除します。

Expression Editor のテキスト:

true

Modify request header で選ぶ操作: Remove

Header name: Client-Cert-Chain

ルール 3 — Client-Cert ヘッダーを設定する

このルールは、クライアントが有効かつ未失効で、サイズ制限内の証明書を提示した場合にだけ、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_large

Modify request header で選ぶ操作: Set dynamic

Header name: Client-Cert

Value: cf.tls_client_auth.cert_rfc9440

ルール 4 — Client-Cert-Chain ヘッダーを設定する

このルールは、クライアントが有効かつ未失効の証明書を提示し、チェーンが空でなくサイズ制限内である場合にだけ、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_large

Modify request header で選ぶ操作: Set dynamic

Header name: Client-Cert-Chain

Value: cf.tls_client_auth.cert_chain_rfc9440

Cloudflare Workers

Cloudflare Worker でも、受信リクエストの tlsClientAuth プロパティを使い、RFC 9440 ヘッダーを組み立てできます。

上記と同じセキュリティ上の考慮事項が適用されます。

クライアント証明書を転送する(レガシー)

ホストに mTLS 認証を適用するだけでなく、クライアント証明書を HTTP ヘッダーとしてオリジンサーバーへ転送できます。この構成は、サーバーログに使うことがよくあります。

すべてのリクエストに証明書を付けないように、証明書は mTLS 接続の最初のリクエストでのみ転送されます。

Cloudflare API

証明書を転送する最も一般的な方法は、Cloudflare API で mTLS 証明書のホスト名設定を更新 することです。

Required API token permissions

At least one of the following token permissions is required:
  • Access: Mutual TLS Certificates Write
Update an mTLS certificate's hostname settingsbash
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_forwardingtrue に設定すると、mTLS 接続内のすべてのリクエストに次のヘッダーが付きます。

  • Cf-Client-Cert-Der-Base64
  • Cf-Client-Cert-Sha256

Managed Transforms

Managed Transforms で HTTP レスポンスヘッダーを変更 し、TLS クライアント認証ヘッダー を渡すこともできます。

Cloudflare Workers

加えて、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,
};

役に立ちましたか?