INTEGRITY Документация

Mutual TLS

Аутентификация с использованием взаимного TLS (mTLS) требует, чтобы и клиент, и сервер предъявили сертификаты во время TLS handshake. В реализации Cloudflare Access загруженный вами CA используется для проверки сертификата клиента (проверка сертификата сервера выполняется стандартными средствами TLS). Access mTLS служит двум целям:

После загрузки корневого удостоверяющего центра (CA) в Access через него пропускаются только запросы с устройств, у которых есть соответствующий клиентский сертификат. Когда запрос достигает приложения, Access запрашивает у клиента сертификат. Если клиент не может предъявить действительный сертификат, запрос блокируется. Если клиент предъявляет действительный сертификат, Access выполняет обмен ключами для проверки.

диаграмма рукопожатия mTLS

Требовать аутентификацию mTLS

Предварительные требования

Добавить mTLS в приложение Access

  1. В Панель управления Cloudflare, перейдите в Zero Trust > Контроль доступа > Учетные данные службы > Mutual TLS.

  2. Выберите Add mTLS Certificate.

  3. Введите любое имя для корневого CA.

  4. В Содержимое сертификата, вставьте содержимое корневого CA.

    Если клиентский сертификат подписан непосредственно корневым CA, достаточно загрузить только корневой сертификат. Если клиентский сертификат подписан промежуточным сертификатом, нужно загрузить всю цепочку CA (промежуточный и корневой сертификаты). Например:

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

    Не включайте сертификаты сервера SSL/TLS: Access использует только цепочку CA для проверки соединения между устройством пользователя и Cloudflare.

  5. В Связанные имена хостов, введите полные доменные имена (FQDN), которые будут использовать этот сертификат.

    Эти FQDN будут именами хостов, используемыми для ресурсов, защищаемых в Политика Access. Необходимо связать корневой CA с FQDN, который использует защищаемое приложение.

  6. Сохраните политику.

  7. Перейдите в Контроль доступа > Политики.

  8. Создать политику Access одним из следующих селекторы:

    • Valid Certificate: Любой клиентский сертификат, который может пройти проверку подлинности в корневом удостоверяющем центре (Root CA), будет допущен к работе.
    • Общее имя: Только клиентские сертификаты с определённым common name будут допущены к продолжению.
  9. Если это предназначено для клиента, которому не требуется вход через IdP, задайте политику Действие к Service Auth.

    Пример политики mTLS

    Действие Тип правила Селектор Значение
    Service Auth Включить Общее имя John Doe
  10. Сохраните политику, затем перейдите в Контроль доступа > Приложения.

  11. Выберите приложение, для которого нужно принудительно включить mTLS, и нажмите Настройте. Приложение должно быть включено в Связанные имена хостов список из шага 5.

  12. В Политики вкладке добавьте свою политику mTLS.

  13. Сохраните приложение.

Теперь для аутентификации в приложении можно использовать клиентский сертификат. Инструкции о том, как предъявить клиентский сертификат, см. в Протестировать mTLS.

Протестировать mTLS

Тестирование с помощью cURL

Чтобы протестировать приложение, защищенное политикой mTLS:

  1. Сначала попробуйте выполнить curl-запрос к сайту без клиентского сертификата. Пример этой команды curl приведён для сайта example.com у которой есть Приложение и политика Access задан для https://auth.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, в браузере, клиентский сертификат необходимо импортировать в диспетчер сертификатов вашего браузера. Инструкции зависят от конкретного браузера. Ваш браузер может использовать корневое хранилище сертификатов операционной системы либо собственное внутреннее хранилище доверенных сертификатов.

Следующий пример показывает, как добавить клиентский сертификат в системный keychain macOS:

  1. Перейдите в каталог, содержащий клиентский сертификат и ключ.
    1. Откройте client.pem файл в Keychain Access. При появлении запроса введите локальный пароль.
    2. В Связка ключей, выберите вариант доступа, который соответствует вашим потребностям, и выберите Add.
    3. В списке сертификатов найдите только что установленный сертификат. Keychain Access пометит его как ненадёжный. Щёлкните сертификат правой кнопкой мыши и выберите Получить сведения.
    4. Выберите Доверие. В разделе При использовании этого сертификата, выберите Always Trust.

Если ваш браузер использует системное хранилище macOS, теперь вы можете подключиться к приложению mTLS через браузер.

Создать сертификаты mTLS

Для тестирования функции mTLS в Cloudflare Access можно генерировать сертификаты с помощью инструментов инфраструктуры открытых ключей (PKI) с открытым исходным кодом.

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. Создайте файл расширения CA с именем v3_intermediate_ca.ext. Например,

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

    Убедитесь, что basicConstraints включает в себя CA: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. Объедините промежуточный и корневой сертификаты в один файл:

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

    Промежуточный сертификат должен находиться в начале файла, а за ним должен следовать сертификат, которым он подписан.

  2. Загрузите содержимое ca-chain.pem к Cloudflare Access. Инструкции см. в Добавить mTLS в приложение Access.

Создайте клиентский сертификат

  1. Создайте закрытый ключ для клиента:

     openssl genrsa -out client.key 2048
  2. Создайте CSR для клиентского сертификата:

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

    Вам будет предложено заполнить несколько необязательных полей. Для тестирования можно задать Общее имя на что-то вроде John 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

В этом руководстве используется Набор инструментов PKI от Cloudflare чтобы создать корневой CA и клиентские сертификаты из файлов JSON.

1. Установите зависимости

Для этого процесса требуются два пакета из набора инструментов PKI от Cloudflare:

Эти пакеты можно установить из GitHub-репозиторий Cloudflare SSL. Вам потребуется рабочая установка Go версии 1.12 или новее. Либо вы можете скачайте пакеты напрямую. Используйте инструкции в разделе Installation, чтобы установить набор инструментов, и убедитесь, что установлены все утилиты из набора.

2. Сгенерируйте корневой CA

  1. Создайте новый каталог для хранения корневого CA.

  2. В этом каталоге создайте два новых файла:

    • CSR. Создайте файл с именем ca-csr.json и добавьте следующий JSON блок, затем сохраните файл.

      {
      	"CN": "Access Testing CA",
      	"key": {
      		"algo": "rsa",
      		"size": 4096
      	},
      	"names": [
      		{
      			"C": "US",
      			"L": "Austin",
      			"O": "Access Testing",
      			"OU": "TX",
      			"ST": "Texas"
      		}
      	]
      }
    • конфигурация. Создайте файл с именем ca-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. Инструкции см. в Добавить mTLS в приложение Access.

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 toolkit:

    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. Получите серийный номер из ранее созданного клиентского сертификата. Добавьте этот серийный номер, а также любые другие номера, которые вы намерены отозвать, в шестнадцатеричном формате в текстовый файл. В этом примере используется файл с именем 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 Script можно найти на репозиторий Cloudflare на GitHub.

Добавление заголовков Client-Cert и Client-Cert-Chain (RFC 9440)

RFC 9440 определяет Client-Cert и Client-Cert-Chain Поля HTTP-заголовков для передачи информации о клиентском сертификате на исходный сервер. Эти заголовки можно сформировать с помощью правила изменения заголовков запроса со следующими полями Ruleset Engine:

Как указано в определениях полей, поля могут быть заданы либо как пустая строка, либо как корректная кодировка RFC 9440. Правильное использование зависит от нескольких факторов, которые рассматриваются в следующих разделах.

Соображения по безопасности

cert_rfc9440 и cert_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 заголовок может отсутствовать, если клиент не предоставил промежуточные сертификаты (только конечный сертификат).

Вам нужно создать следующие правила изменения заголовков запроса. Заголовок Удалить правила должны быть размещены перед Включить динамический режим правила, чтобы заголовки, добавленные клиентом, удалялись при каждом запросе до установки проверенных значений.

Правило 1. Удаление заголовка Client-Cert

Это правило безусловно удаляет любой Client-Cert заголовок, отправленный клиентом.

Текст в Expression Editor:

true

Выбранная операция в разделе Изменить заголовок запроса: Удалить

Имя заголовка: Client-Cert

Правило 2. Удаление заголовка Client-Cert-Chain

Это правило безусловно удаляет любой Client-Cert-Chain заголовок, отправленный клиентом.

Текст в Expression Editor:

true

Выбранная операция в разделе Изменить заголовок запроса: Удалить

Имя заголовка: 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

Выбранная операция в разделе Изменить заголовок запроса: Включить динамический режим

Имя заголовка: Client-Cert

Значение: 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

Выбранная операция в разделе Изменить заголовок запроса: Включить динамический режим

Имя заголовка: Client-Cert-Chain

Значение: cf.tls_client_auth.cert_chain_rfc9440

Cloudflare Workers

Вы также можете сформировать заголовки RFC 9440 в Cloudflare Worker с использованием tlsClientAuth свойства во входящем запросе.

Действуют те же соображения безопасности, что указаны выше.

Передача клиентского сертификата (устаревший способ)

Помимо принудительной mTLS-аутентификации для вашего хоста, вы также можете передавать клиентский сертификат на исходный сервер в виде HTTP-заголовка. Это часто полезно для журналирования на сервере.

Чтобы не добавлять сертификат к каждому запросу, он передаётся только с первым запросом mTLS-соединения.

Cloudflare API

Наиболее распространённый способ переслать сертификат: использовать API Cloudflare, чтобы обновить настройки имени узла сертификата mTLS.

Необходимые разрешения API-токена

Хотя бы одно из следующих права доступа токена требуется:
Изменение настроек имени хоста сертификата mTLS
curl "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/access/certificates/settings" \
	--request PUT \
	--header "X-Auth-Email: $CLOUDFLARE_EMAIL" \
	--header "X-Auth-Key: $CLOUDFLARE_API_KEY" \
	--json '{
		"settings": [
				{
						"hostname": "<HOSTNAME>",
						"china_network": false,
						"client_certificate_forwarding": true
				}
		]
	}'

Как только client_certificate_forwarding имеет значение true, теперь каждый запрос в рамках mTLS-соединения будет включать следующие заголовки:

Managed Transforms

Вы также можете изменять заголовки HTTP-ответов с помощью Managed Transforms, чтобы передать Заголовки клиентской аутентификации 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 в настоящее время не работает для:

Уведомления о сертификатах mTLS

Cloudflare отправит следующие уведомления до истечения срока действия ваших сертификатов mutual TLS:

Оповещение Access об истечении срока действия сертификата mTLS

Для кого это предназначено?

Доступ клиентов, использующих клиентские сертификаты для взаимной аутентификации TLS. Это уведомление будет отправлено за 30 и 14 дней до истечения срока действия сертификата.

Другие параметры / фильтры

Нет.

Входит в

Покупка Доступ и/или Cloudflare for SaaS.

Что делать при получении такого уведомления?

Загрузите обновлённый сертификат.