Пример политики mTLS
| Действие | Тип правила | Селектор | Значение |
|---|---|---|---|
| Service Auth | Включить | Общее имя | John Doe |
← Cloudflare One / cloudflare-one / access-controls / service-credentials
Аутентификация с использованием взаимного TLS (mTLS) ↗ требует, чтобы и клиент, и сервер предъявили сертификаты во время TLS handshake. В реализации Cloudflare Access загруженный вами CA используется для проверки сертификата клиента (проверка сертификата сервера выполняется стандартными средствами TLS). Access mTLS служит двум целям:
После загрузки корневого удостоверяющего центра (CA) в Access через него пропускаются только запросы с устройств, у которых есть соответствующий клиентский сертификат. Когда запрос достигает приложения, Access запрашивает у клиента сертификат. Если клиент не может предъявить действительный сертификат, запрос блокируется. Если клиент предъявляет действительный сертификат, Access выполняет обмен ключами для проверки.
Сертификат CA может быть выдан общедоступным доверенным удостоверяющим центром или быть самоподписанным.
В сертификате Basic Constraints, атрибут CA должен быть установлен на TRUE.
Сертификат должен использовать один из перечисленных ниже алгоритмов подписи:
Разрешённые алгоритмы подписи
x509.SHA1WithRSA
x509.SHA256WithRSA
x509.SHA384WithRSA
x509.SHA512WithRSA
x509.ECDSAWithSHA1
x509.ECDSAWithSHA256
x509.ECDSAWithSHA384
x509.ECDSAWithSHA512
В Панель управления Cloudflare ↗, перейдите в Zero Trust > Контроль доступа > Учетные данные службы > Mutual TLS.
Выберите Add mTLS Certificate.
Введите любое имя для корневого CA.
В Содержимое сертификата, вставьте содержимое корневого CA.
Если клиентский сертификат подписан непосредственно корневым CA, достаточно загрузить только корневой сертификат. Если клиентский сертификат подписан промежуточным сертификатом, нужно загрузить всю цепочку CA (промежуточный и корневой сертификаты). Например:
-----BEGIN CERTIFICATE-----
<intermediate.pem>
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
<rootCA.pem>
-----END CERTIFICATE-----Не включайте сертификаты сервера SSL/TLS: Access использует только цепочку CA для проверки соединения между устройством пользователя и Cloudflare.
В Связанные имена хостов, введите полные доменные имена (FQDN), которые будут использовать этот сертификат.
Эти FQDN будут именами хостов, используемыми для ресурсов, защищаемых в Политика Access. Необходимо связать корневой CA с FQDN, который использует защищаемое приложение.
Сохраните политику.
Перейдите в Контроль доступа > Политики.
Создать политику Access одним из следующих селекторы:
Если это предназначено для клиента, которому не требуется вход через IdP, задайте политику Действие к Service Auth.
Пример политики mTLS
| Действие | Тип правила | Селектор | Значение |
|---|---|---|---|
| Service Auth | Включить | Общее имя | John Doe |
Сохраните политику, затем перейдите в Контроль доступа > Приложения.
Выберите приложение, для которого нужно принудительно включить mTLS, и нажмите Настройте. Приложение должно быть включено в Связанные имена хостов список из шага 5.
В Политики вкладке добавьте свою политику mTLS.
Сохраните приложение.
Теперь для аутентификации в приложении можно использовать клиентский сертификат. Инструкции о том, как предъявить клиентский сертификат, см. в Протестировать mTLS.
Чтобы протестировать приложение, защищенное политикой mTLS:
Сначала попробуйте выполнить curl-запрос к сайту без клиентского сертификата.
Пример этой команды curl приведён для сайта example.com у которой есть Приложение и политика Access задан для https://auth.example.com:
curl -sv https://auth.example.comБез клиентского сертификата в запросе 403 forbidden отображается ответ, и доступ к сайту становится невозможен.
Теперь добавьте клиентский сертификат и ключ к запросу:
curl -sv https://auth.example.com --cert example.pem --key key.pemПосле успешного завершения процесса аутентификации CF_Authorization Set-Cookie заголовок возвращается в ответе.
Чтобы получить доступ к приложению, защищённому с помощью mTLS, в браузере, клиентский сертификат необходимо импортировать в диспетчер сертификатов вашего браузера. Инструкции зависят от конкретного браузера. Ваш браузер может использовать корневое хранилище сертификатов операционной системы либо собственное внутреннее хранилище доверенных сертификатов.
Следующий пример показывает, как добавить клиентский сертификат в системный keychain macOS:
client.pem файл в Keychain Access. При появлении запроса введите локальный пароль.Если ваш браузер использует системное хранилище macOS, теперь вы можете подключиться к приложению mTLS через браузер.
Для тестирования функции mTLS в Cloudflare Access можно генерировать сертификаты с помощью инструментов инфраструктуры открытых ключей (PKI) с открытым исходным кодом.
В этом разделе описано, как использовать OpenSSL ↗ чтобы создать корневой и промежуточный сертификаты, а затем выпустить клиентские сертификаты, которые могут проходить аутентификацию по цепочке CA.
Создайте закрытый ключ корневого CA:
openssl genrsa -aes256 -out rootCA.key 4096Когда появится запрос, введите пароль для использования с rootCA.key.
Создайте самоподписанный корневой сертификат с именем rootCA.pem:
openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 3650 -out rootCA.pemВам будет предложено ввести пароль от закрытого ключа и заполнить несколько необязательных полей. Для тестирования эти поля можно оставить пустыми.
Создайте закрытый ключ промежуточного CA:
openssl genrsa -aes256 -out intermediate.key 4096Когда появится запрос, введите пароль для использования с intermediate.key.
Создайте запрос на подпись сертификата (CSR) для промежуточного сертификата:
openssl req -new -sha256 -key intermediate.key -out intermediate.csrВам будет предложено ввести пароль от закрытого ключа и заполнить несколько необязательных полей. Для тестирования эти поля можно оставить пустыми.
Создайте файл расширения CA с именем v3_intermediate_ca.ext. Например,
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer
basicConstraints = critical, CA:true
keyUsage = critical, cRLSign, keyCertSignУбедитесь, что basicConstraints включает в себя CA:true свойство. Это свойство позволяет промежуточному сертификату выступать в роли CA и подписывать клиентские сертификаты.
Подпишите промежуточный сертификат с помощью корневого 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Объедините промежуточный и корневой сертификаты в один файл:
cat intermediate.pem rootCA.pem > ca-chain.pemПромежуточный сертификат должен находиться в начале файла, а за ним должен следовать сертификат, которым он подписан.
Загрузите содержимое ca-chain.pem к Cloudflare Access. Инструкции см. в Добавить mTLS в приложение Access.
Создайте закрытый ключ для клиента:
openssl genrsa -out client.key 2048Создайте CSR для клиентского сертификата:
openssl req -new -key client.key -out client.csrВам будет предложено заполнить несколько необязательных полей. Для тестирования можно задать Общее имя на что-то вроде John Doe.
Подпишите клиентский сертификат промежуточным сертификатом:
openssl x509 -req -in client.csr -CA intermediate.pem -CAkey intermediate.key -CAcreateserial -out client.pem -days 365 -sha256Проверьте клиентский сертификат по цепочке сертификатов:
openssl verify -CAfile ca-chain.pem client.pemclient.pem: OKТеперь можно использовать клиентский сертификат (client.pem) и его ключ (client.key) в Протестировать mTLS.
В этом руководстве используется Набор инструментов PKI от Cloudflare ↗ чтобы создать корневой CA и клиентские сертификаты из файлов JSON.
Для этого процесса требуются два пакета из набора инструментов PKI от Cloudflare:
cf-sslcfssljsonЭти пакеты можно установить из GitHub-репозиторий Cloudflare SSL ↗. Вам потребуется рабочая установка Go версии 1.12 или новее. Либо вы можете скачайте пакеты ↗ напрямую. Используйте инструкции в разделе Installation, чтобы установить набор инструментов, и убедитесь, что установлены все утилиты из набора.
Создайте новый каталог для хранения корневого CA.
В этом каталоге создайте два новых файла:
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"
}
}
}
}Теперь выполните следующую команду, чтобы сгенерировать корневой CA с использованием этих файлов.
cfssl gencert -initca ca-csr.json | cfssljson -bare caКоманда выведет корневой сертификат (ca.pem) и его ключ (ca-key.pem).
lsca-config.json ca-csr.json ca-key.pem ca.csr ca.pemЗагрузите содержимое ca.pem к Cloudflare Access. Инструкции см. в Добавить mTLS в приложение Access.
Чтобы создать клиентский сертификат, который будет проходить проверку подлинности по загруженному корневому CA:
Создайте файл с именем 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"
}
]
}Теперь сгенерируйте клиентский сертификат с помощью следующей команды, используя 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). Этот список будет содержать отозванные клиентские сертификаты.
Получите серийный номер из ранее созданного клиентского сертификата. Добавьте этот серийный номер, а также любые другие номера, которые вы намерены отозвать, в шестнадцатеричном формате в текстовый файл. В этом примере используется файл с именем serials.txt.
Создайте 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 ↗.
RFC 9440 ↗ определяет Client-Cert и Client-Cert-Chain Поля HTTP-заголовков для передачи информации о клиентском сертификате на исходный сервер. Эти заголовки можно сформировать с помощью правила изменения заголовков запроса со следующими полями 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 : возвращает true когда закодированный сертификат превышает 10 KiB.cf.tls_client_auth.cert_chain_rfc9440_too_large : возвращает true когда закодированная цепочка превышает 16 KiB.Здесь мы приводим пример того, как безопасно использовать эти поля для формирования доверенного Client-Cert и Client-Cert-Chain заголовки для пересылки на ваш источник.
После этого источник может полагаться на наличие заголовков, чтобы убедиться, что клиент предоставил действительный сертификат.
Примечание: Client-Cert-Chain заголовок может отсутствовать, если клиент не предоставил промежуточные сертификаты (только конечный сертификат).
Вам нужно создать следующие правила изменения заголовков запроса. Заголовок Удалить правила должны быть размещены перед Включить динамический режим правила, чтобы заголовки, добавленные клиентом, удалялись при каждом запросе до установки проверенных значений.
Это правило безусловно удаляет любой Client-Cert заголовок, отправленный клиентом.
Текст в Expression Editor:
trueВыбранная операция в разделе Изменить заголовок запроса: Удалить
Имя заголовка: Client-Cert
Это правило безусловно удаляет любой Client-Cert-Chain заголовок, отправленный клиентом.
Текст в Expression Editor:
trueВыбранная операция в разделе Изменить заголовок запроса: Удалить
Имя заголовка: 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_largeВыбранная операция в разделе Изменить заголовок запроса: Включить динамический режим
Имя заголовка: Client-Cert
Значение: 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_largeВыбранная операция в разделе Изменить заголовок запроса: Включить динамический режим
Имя заголовка: Client-Cert-Chain
Значение: cf.tls_client_auth.cert_chain_rfc9440
Вы также можете сформировать заголовки RFC 9440 в Cloudflare Worker
с использованием tlsClientAuth
свойства во входящем запросе.
Действуют те же соображения безопасности, что указаны выше.
Помимо принудительной mTLS-аутентификации для вашего хоста, вы также можете передавать клиентский сертификат на исходный сервер в виде HTTP-заголовка. Это часто полезно для журналирования на сервере.
Чтобы не добавлять сертификат к каждому запросу, он передаётся только с первым запросом mTLS-соединения.
Наиболее распространённый способ переслать сертификат: использовать API Cloudflare, чтобы обновить настройки имени узла сертификата mTLS.
Необходимые разрешения API-токена
Access: Mutual TLS Certificates Writecurl "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-соединения будет включать следующие заголовки:
Cf-Client-Cert-Der-Base64Cf-Client-Cert-Sha256Вы также можете изменять заголовки HTTP-ответов с помощью Managed Transforms, чтобы передать Заголовки клиентской аутентификации 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,
};mTLS в настоящее время не работает для:
Cloudflare отправит следующие уведомления до истечения срока действия ваших сертификатов mutual TLS:
Оповещение Access об истечении срока действия сертификата mTLS
Доступ клиентов, использующих клиентские сертификаты для взаимной аутентификации TLS. Это уведомление будет отправлено за 30 и 14 дней до истечения срока действия сертификата.
Другие параметры / фильтрыНет.
Входит вПокупка Доступ и/или Cloudflare for SaaS.
Что делать при получении такого уведомления?Загрузите обновлённый сертификат.