Skip to content

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

相互 TLS

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

相互 TLS(mTLS)認証 では、TLS ハンドシェイク中にクライアントとサーバーの両方が証明書を提示します。Cloudflare Access の実装では、アップロードした CA でクライアント証明書を検証します(サーバー証明書の検証は通常の TLS が担当します)。Access の mTLS には次の 2 つの用途があります。

  • ID プロバイダーを使わないデバイスを認証する — 自動化システムや IoT デバイスは、IdP でログインする代わりにクライアント証明書を提示して身元を証明できます。
  • 2 つ目の認証要素を追加する — IdP でログインするチームメンバーにも、有効なクライアント証明書の提示を求め、セキュリティを一段厚くできます。

ルート認証局(CA)を Access にアップロードすると、一致するクライアント証明書を持つデバイスからのリクエストだけが通過します。リクエストがアプリケーションに届くと、Access はクライアントに証明書の提示を求めます。有効な証明書を提示できない場合、リクエストはブロックされます。有効な証明書を提示した場合、Access は鍵交換を完了して検証します。

mTLS ハンドシェイクの図

mTLS 認証を適用する

前提条件

  • mTLS で保護したいホスト名の Access アプリケーション
  • デバイス向けのクライアント証明書を発行する CA
    • CA 証明書は、公開信頼されている CA のもの、または自己署名のものを使用できます。

    • 証明書の Basic Constraints では、属性 CATRUE に設定する必要があります。

    • 証明書は、次のいずれかの署名アルゴリズムを使用する必要があります。

      使用できる署名アルゴリズム

      x509.SHA1WithRSA

      x509.SHA256WithRSA

      x509.SHA384WithRSA

      x509.SHA512WithRSA

      x509.ECDSAWithSHA1

      x509.ECDSAWithSHA256

      x509.ECDSAWithSHA384

      x509.ECDSAWithSHA512

Access アプリケーションに mTLS を追加する

  1. Cloudflare ダッシュボードZero Trust > Access controls > Service credentials > Mutual TLS を開きます。

  2. Add mTLS Certificate を選択します。

  3. ルート CA の名前を任意で入力します。

  4. Certificate content にルート CA の内容を貼り付けます。

    クライアント証明書がルート CA で直接署名されている場合は、ルートだけをアップロードします。クライアント証明書が中間証明書で署名されている場合は、CA チェーン全体(中間とルート)をアップロードする必要があります。例:

    -----BEGIN CERTIFICATE-----
    <intermediate.pem>
    -----END CERTIFICATE-----
    -----BEGIN CERTIFICATE-----
    <rootCA.pem>
    -----END CERTIFICATE-----

    SSL/TLS のサーバー証明書は含めないでください。Access はユーザーのデバイスと Cloudflare 間の接続を検証するために、CA チェーンだけを使います。

  5. Associated hostnames に、この証明書を使う完全修飾ドメイン名(FQDN)を入力します。

    これらの FQDN は、Access ポリシー で保護するリソースのホスト名になります。ルート CA は、保護対象アプリケーションが使う FQDN に関連付ける必要があります。

  6. ポリシーを保存します。

  7. Access controls > Policies を開きます。

  8. 次のいずれかの セレクター を使って Access ポリシーを作成 します。

    • Valid Certificate: ルート CA で認証できるクライアント証明書なら、どれでも続行を許可します。
    • Common Name: 特定のコモンネームを持つクライアント証明書だけを続行許可します。
  9. IdP でログインする必要がないクライアント向けの場合は、ポリシーの ActionService Auth に設定します。

    mTLS ポリシーの例

    アクション ルールタイプ セレクター
    Service Auth Include Common Name John Doe
  10. ポリシーを保存し、Access controls > Applications を開きます。

  11. mTLS を適用したいアプリケーションを選び、Configure を選択します。アプリケーションは、手順 5 の Associated hostnames 一覧に含まれている必要があります。

  12. Policies タブで、mTLS ポリシーを追加します。

  13. アプリケーションを保存します。

これで、クライアント証明書を使ってアプリケーションに認証できます。クライアント証明書の提示方法は、mTLS をテストする を参照してください。

mTLS をテストする

cURL でテストする

mTLS ポリシーで保護したアプリケーションをテストするには、次の手順を行います。

  1. まず、クライアント証明書なしでサイトに curl します。 この curl の例は、https://auth.example.comAccess アプリケーションとポリシー を設定したサイト example.com 向けです。

    curl -sv https://auth.example.com

    リクエストにクライアント証明書がないと、403 forbidden が返り、サイトにアクセスできません。

  2. 次に、クライアント証明書と鍵をリクエストに追加します。

    curl -sv https://auth.example.com --cert example.pem --key key.pem

認証が成功すると、応答に CF_Authorization Set-Cookie ヘッダーが返ります。

ブラウザーでテストする

ブラウザーで mTLS 保護のアプリケーションにアクセスするには、クライアント証明書をブラウザーの証明書マネージャーにインポートする必要があります。手順はブラウザーによって異なります。ブラウザーは、OS のルートストアを使う場合と、独自の内部トラストストアを使う場合があります。

次の例では、クライアント証明書を macOS のシステムキーチェーンに追加する方法を示します。

  1. クライアント証明書と鍵があるディレクトリに移動します。
    1. Keychain Access で client.pem ファイルを開きます。求められた場合は、ローカルのパスワードを入力します。
    2. Keychain で、用途に合うアクセスオプションを選び、Add を選択します。
    3. 証明書の一覧で、いまインストールした証明書を探します。Keychain Access は、この証明書を信頼されていない状態として表示します。証明書を右クリックし、Get Info を選択します。
    4. Trust を選択します。When using this certificateAlways Trust を選びます。

ブラウザーが macOS のシステムストアを使う場合は、これでブラウザーから mTLS アプリケーションに接続できます。

mTLS 証明書を生成する

オープンソースの公開鍵基盤(PKI)ツールを使って、Cloudflare Access の mTLS 機能をテストするための証明書を生成できます。

OpenSSL

このセクションでは、OpenSSL でルート証明書と中間証明書を生成し、CA チェーンで認証できるクライアント証明書を発行する方法を説明します。

ルート CA を生成する

  1. ルート CA の秘密鍵を生成します。

     openssl genrsa -aes256 -out rootCA.key 4096

    求められたら、rootCA.key に使うパスワードを入力します。

  2. rootCA.pem という自己署名ルート証明書を作成します。

    openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 3650 -out rootCA.pem

    秘密鍵のパスワードと、任意のフィールドの入力を求められます。テスト目的なら、任意フィールドは空のままで構いません。

中間証明書を生成する

  1. 中間 CA の秘密鍵を生成します。

     openssl genrsa -aes256 -out intermediate.key 4096

    求められたら、intermediate.key に使うパスワードを入力します。

  2. 中間証明書の証明書署名要求(CSR)を作成します。

    openssl req -new -sha256 -key intermediate.key -out intermediate.csr

    秘密鍵のパスワードと、任意のフィールドの入力を求められます。テスト目的なら、任意フィールドは空のままで構いません。

  3. v3_intermediate_ca.ext という CA 拡張ファイルを作成します。例:

    subjectKeyIdentifier = hash
    authorityKeyIdentifier = keyid:always,issuer
    basicConstraints = critical, CA:true
    keyUsage = critical, cRLSign, keyCertSign

    basicConstraintsCA:true プロパティが含まれていることを確認してください。このプロパティがあると、中間証明書が CA として動作し、クライアント証明書に署名できます。

  4. ルート CA で中間証明書に署名します。

     openssl x509 -req -in intermediate.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out intermediate.pem -days 1825 -sha256 -extfile v3_intermediate_ca.ext

CA チェーンファイルを作成する

  1. 中間証明書とルート証明書を 1 つのファイルにまとめます。

    cat intermediate.pem rootCA.pem > ca-chain.pem

    ファイルの先頭に中間証明書を置き、そのあとに署名した証明書を続けます。

  2. ca-chain.pem の内容を Cloudflare Access にアップロードします。手順は Access アプリケーションに mTLS を追加する を参照してください。

クライアント証明書を生成する

  1. クライアント用の秘密鍵を生成します。

     openssl genrsa -out client.key 2048
  2. クライアント証明書の CSR を作成します。

    openssl req -new -key client.key -out client.csr

    任意のフィールドの入力を求められます。テスト目的なら、Common NameJohn Doe などに設定できます。

  3. 中間証明書でクライアント証明書に署名します。

     openssl x509 -req -in client.csr -CA intermediate.pem -CAkey intermediate.key -CAcreateserial -out client.pem -days 365 -sha256
  4. 証明書チェーンに対してクライアント証明書を検証します。

    openssl verify -CAfile ca-chain.pem client.pem
    client.pem: OK

これで、クライアント証明書(client.pem)とその鍵(client.key)を使って mTLS をテスト できます。

Cloudflare PKI

このガイドでは、Cloudflare の PKI ツールキット を使い、JSON ファイルからルート CA とクライアント証明書を生成します。

1. 依存関係をインストールする

この手順では、Cloudflare の PKI ツールキットから次の 2 つのパッケージが必要です。

  • cf-ssl
  • cfssljson

これらのパッケージは Cloudflare SSL の GitHub リポジトリ からインストールできます。Go 1.12 以降の動作する環境が必要です。または、パッケージを直接ダウンロード することもできます。 Installation の手順に従ってツールキットをインストールし、ツールキット内のユーティリティプログラムをすべてインストールしてください。

2. ルート CA を生成する

  1. ルート CA を保存する新しいディレクトリを作成します。

  2. そのディレクトリ内に、次の 2 つのファイルを作成します。

    • CSRca-csr.json というファイルを作成し、次の JSON を追加して保存します。

      {
      	"CN": "Access Testing CA",
      	"key": {
      		"algo": "rsa",
      		"size": 4096
      	},
      	"names": [
      		{
      			"C": "US",
      			"L": "Austin",
      			"O": "Access Testing",
      			"OU": "TX",
      			"ST": "Texas"
      		}
      	]
      }
    • configca-config.json というファイルを作成し、次の JSON を追加して保存します。

      {
      	"signing": {
      		"default": {
      			"expiry": "8760h"
      		},
      		"profiles": {
      			"server": {
      				"usages": ["signing", "key encipherment", "server auth"],
      				"expiry": "8760h"
      			},
      			"client": {
      				"usages": ["signing", "key encipherment", "client auth"],
      				"expiry": "8760h"
      			}
      		}
      	}
      }
  3. 次のコマンドを実行し、それらのファイルでルート CA を生成します。

    cfssl gencert -initca ca-csr.json | cfssljson -bare ca
  4. コマンドはルート証明書(ca.pem)とその鍵(ca-key.pem)を出力します。

    ls
    ca-config.json ca-csr.json ca-key.pem ca.csr  ca.pem
  5. ca.pem の内容を Cloudflare Access にアップロードします。手順は Access アプリケーションに mTLS を追加する を参照してください。

3. クライアント証明書を生成する

アップロードしたルート CA で認証できるクライアント証明書を生成するには、次の手順を行います。

  1. client-csr.json というファイルを作成し、次の JSON を追加します。

    {
    	"CN": "James Royal",
    	"hosts": [""],
    	"key": {
    		"algo": "rsa",
    		"size": 4096
    	},
    	"names": [
    		{
    			"C": "US",
    			"L": "Austin",
    			"O": "Access",
    			"OU": "Access Admins",
    			"ST": "Texas"
    		}
    	]
    }
  2. 次のコマンドで、Cloudflare PKI ツールキットを使ってクライアント証明書を生成します。

    cfssl gencert -ca=ca.pem -ca-key=ca-key.pem  -config=ca-config.json -profile=client client-csr.json | cfssljson -bare client

コマンドはクライアント証明書ファイル(client.pem)とその鍵(client-key.pem)を出力します。これらのファイルで mTLS をテスト できます。

証明書失効リストを作成する

Cloudflare PKI ツールキットで、証明書失効リスト(CRL)も生成できます。このリストには失効したクライアント証明書が入ります。

  1. 先に生成したクライアント証明書からシリアル番号を取得します。そのシリアル番号、または失効させたいほかの番号を、16 進形式でテキストファイルに追加します。この例では serials.txt というファイルを使います。

  2. 次のコマンドで CRL を作成します。

    cfssl gencrl serials.txt ../mtls-test/ca.pem ../mtls-test/ca-key.pem | base64 -D > ca.crl

CRL はサーバーに追加するか、Cloudflare Worker で失効を強制する必要があります。Worker スクリプトの例は Cloudflare の GitHub リポジトリ にあります。

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,
};

既知の制限

mTLS は現在、次の構成では動作しません。

相互 TLS 証明書の通知

相互 TLS 証明書の期限切れ前に、Cloudflare は次の 通知 を送ります。

Access mTLS Certificate Expiration Alert

対象

相互 TLS 認証にクライアント証明書を使う Access のお客様向けです。証明書の有効期限の 30 日前と 14 日前に通知します。

その他のオプション / フィルタ

なし。

含まれるプラン

Access および / または Cloudflare for SaaS の購入。

受け取ったときの対応

更新した証明書 をアップロードします。

役に立ちましたか?