Надёжное шифрование SSL/TLS: практическое руководство
Этот документ поможет вам начать работу и настроить несколько основных функций. Настоятельно рекомендуем прочитать остальную документацию по SSL и глубже разобраться в материале, прежде чем переходить к более сложным методам.
Пример базовой конфигурации
Ваша конфигурация SSL должна содержать как минимум следующие директивы.
LoadModule ssl_module modules/mod_ssl.so
Listen 443
<VirtualHost *:443>
ServerName www.example.com
SSLEngine on
SSLCertificateFile "/path/to/www.example.com.cert"
SSLCertificateKeyFile "/path/to/www.example.com.key"
</VirtualHost> Наборы шифров и обеспечение надёжной защиты
- Как создать SSL-сервер, который принимает только надёжные алгоритмы шифрования?
- Как создать SSL-сервер, который в целом принимает все типы шифров, но требует надёжный шифр для доступа к определённому URL?
Как создать SSL-сервер, который принимает только надёжные алгоритмы шифрования?
Следующая конфигурация включает только самые надёжные шифры:
SSLCipherSuite HIGH:!aNULL:!MD5
В следующей конфигурации вы указываете предпочтение определённым шифрам, оптимизированным по скорости (mod_ssl выберет их, если они поддерживаются клиентом):
SSLCipherSuite RC4-SHA:AES128-SHA:HIGH:!aNULL:!MD5 SSLHonorCipherOrder on
Как создать SSL-сервер, который в целом принимает все типы шифров, но требует надёжный шифр для доступа к определённому URL?
Очевидно, что здесь не подойдёт директива SSLCipherSuite на уровне всего сервера, ограничивающая набор шифров только надёжными вариантами. Однако mod_ssl можно перенастроить в блоках Location, чтобы задать параметры для отдельных каталогов и автоматически принудительно выполнить повторное согласование параметров SSL в соответствии с новой конфигурацией. Это можно сделать следующим образом:
# be liberal in general SSLCipherSuite ALL:!aNULL:RC4+RSA:+HIGH:+MEDIUM:+LOW:+EXP:+eNULL <Location "/strong/area"> # but https://hostname/strong/area/ and below # requires strong ciphers SSLCipherSuite HIGH:!aNULL:!MD5 </Location>
Степлинг OCSP
Протокол проверки статуса сертификата в сети (OCSP) позволяет определить, был ли отозван сертификат сервера. Степлинг OCSP — это особый вариант его использования, при котором сервер, например httpd с mod_ssl, хранит актуальные ответы OCSP для своих сертификатов и отправляет их клиентам, подключающимся к серверу. Большинство сертификатов содержат адрес службы OCSP, которую обслуживает выдавший сертификат центр сертификации, а mod_ssl может связаться с этой службой, получить подписанный ответ и отправить его клиентам, подключающимся к серверу.
Поскольку клиент может получить статус отзыва сертификата от сервера, не устанавливая дополнительное соединение с центром сертификации, степлинг OCSP является предпочтительным способом получения статуса отзыва. Отсутствие обмена данными между клиентами и центром сертификации также помогает сохранить историю посещений клиента в тайне от центра сертификации и повышает надёжность получения статуса, поскольку оно не зависит от потенциально сильно загруженных серверов центра сертификации.
Поскольку полученный сервером ответ можно использовать для всех клиентов с одним и тем же сертификатом, пока этот ответ действителен, нагрузка на сервер минимальна.
После правильной настройки общей поддержки SSL для включения степлинга OCSP обычно достаточно внести совсем небольшие изменения в конфигурацию httpd — добавить две следующие директивы:
SSLUseStapling On SSLStaplingCache "shmcb:logs/ssl_stapling(32768)"
Эти директивы размещаются в глобальной области (то есть вне определения виртуального хоста) там же, где и другие глобальные директивы конфигурации SSL: например, в conf/extra/httpd-ssl.conf для обычных сборок httpd с открытым исходным кодом, в /etc/apache2/mods-enabled/ssl.conf для httpd из пакетов Ubuntu или Debian и т. д.
Путь в директиве SSLStaplingCache (например, logs/) должен совпадать с путём в директиве SSLSessionCache. Этот путь задаётся относительно ServerRoot.
Для этой директивы SSLStaplingCache требуется mod_socache_shmcb (это следует из префикса shmcb в аргументе директивы). Этот модуль обычно уже включён для SSLSessionCache или используется другим модулем, а не mod_ssl. Если вы включили кэш сеансов SSL с помощью механизма, отличного от mod_socache_shmcb, используйте этот альтернативный механизм и для SSLStaplingCache. Например:
SSLSessionCache "dbm:logs/ssl_scache" SSLStaplingCache "dbm:logs/ssl_stapling"
Чтобы проверить, отправляет ли ваш сервер ответ OCSP, можно использовать программу командной строки openssl:
$ openssl s_client -connect www.example.com:443 -status -servername www.example.com
...
OCSP response:
======================================
OCSP Response Data:
OCSP Response Status: successful (0x0)
Response Type: Basic OCSP Response
...
Cert Status: Good
... В следующих разделах описаны наиболее распространённые ситуации, требующие дополнительной настройки конфигурации. См. также справочное руководство mod_ssl.
Если для сервера используется больше нескольких SSL-сертификатов
Ответы OCSP хранятся в кэше степлинга SSL. Обычно размер ответов составляет от нескольких сотен до нескольких тысяч байт, но mod_ssl поддерживает ответы OCSP размером примерно до 10 КБ. Если сертификатов больше нескольких, может потребоваться увеличить размер кэша степлинга (в приведённом выше примере он составляет 32768 байт). При ошибке сохранения ответа будет записано сообщение об ошибке AH01929.
Если в сертификате не указан адрес службы OCSP или требуется использовать другой адрес
См. директиву SSLStaplingForceURL.
Проверить, указан ли в сертификате сервера адрес службы OCSP, можно с помощью программы командной строки openssl:
$ openssl x509 -in ./www.example.com.crt -text | grep 'OCSP.*http' OCSP - URI:http://ocsp.example.com
Если URI OCSP указан и веб-сервер может напрямую подключиться к нему без использования прокси-сервера, дополнительная настройка не требуется. Учтите, что может понадобиться скорректировать правила брандмауэра, регулирующие исходящие подключения с веб-сервера.
Если URI OCSP не указан, обратитесь в свой центр сертификации и узнайте, доступен ли такой адрес. Если да, задайте его с помощью SSLStaplingForceURL в виртуальном хосте, использующем этот сертификат.
Если настроено несколько виртуальных хостов с поддержкой SSL и для некоторых из них нужно отключить степлинг OCSP
Добавьте SSLUseStapling Off в виртуальные хосты, для которых нужно отключить степлинг OCSP.
Если служба OCSP работает медленно или нестабильно
Для обработки тайм-аутов и ошибок доступны несколько директив. См. документацию по директивам SSLStaplingFakeTryLater, SSLStaplingResponderTimeout и SSLStaplingReturnResponderErrors.
Если mod_ssl записывает ошибку AH02217
AH02217: ssl_stapling_init_cert: Can't retrieve issuer certificate!
Чтобы поддерживать степлинг OCSP при использовании определённого сертификата сервера, необходимо настроить цепочку сертификатов для этого сертификата. Если цепочка не была настроена при включении SSL, после включения степлинга OCSP будет выдана ошибка AH02217, а клиенты, использующие этот сертификат, не получат ответ OCSP.
Инструкции по настройке цепочки сертификатов см. в разделах SSLCertificateChainFile и SSLCertificateFile.
Аутентификация клиентов и контроль доступа
- Как заставить клиентов проходить аутентификацию с помощью сертификатов?
- Как заставить клиентов проходить аутентификацию с помощью сертификатов для определённого URL, но при этом разрешить любым клиентам доступ к остальной части сервера?
- Как разрешить доступ к определённому URL только клиентам с сертификатами, но при этом разрешить всем клиентам доступ к остальной части сервера?
- Как потребовать HTTPS с надёжными шифрами и базовую аутентификацию либо сертификаты клиентов для доступа к части сайта интрасети клиентам из Интернета?
Как заставить клиентов проходить аутентификацию с помощью сертификатов?
Если вам известны все ваши пользователи (например, как это часто бывает во внутренней корпоративной сети), можно потребовать аутентификацию по обычным сертификатам. Для этого достаточно создать сертификаты клиентов, подписанные вашим собственным сертификатом CA (ca.crt), а затем проверять сертификаты клиентов с его помощью.
# require a client certificate which has to be directly # signed by our CA certificate in ca.crt SSLVerifyClient require SSLVerifyDepth 1 SSLCACertificateFile "conf/ssl.crt/ca.crt"
Как заставить клиентов проходить аутентификацию с помощью сертификатов для определённого URL, но при этом разрешить любым клиентам доступ к остальной части сервера?
Чтобы заставить клиентов проходить аутентификацию с помощью сертификатов для определённого URL, можно использовать возможности перенастройки mod_ssl на уровне каталогов:
SSLVerifyClient none SSLCACertificateFile "conf/ssl.crt/ca.crt" <Location "/secure/area"> SSLVerifyClient require SSLVerifyDepth 1 </Location>
Как разрешить доступ к определённому URL только клиентам с сертификатами, но при этом разрешить всем клиентам доступ к остальной части сервера?
Ключ к решению этой задачи — проверить, соответствует ли часть сертификата клиента ожидаемому значению. Обычно для этого проверяют всё различительное имя (DN) или его часть, чтобы убедиться, что оно содержит известную строку. Это можно сделать двумя способами: с помощью mod_auth_basic или SSLRequire.
Метод mod_auth_basic обычно требуется, если сертификаты совершенно разные или в их различительных именах нет общих полей (например, названия организации и т. д.). В таком случае следует создать базу паролей, содержащую всех разрешённых клиентов, например:
SSLVerifyClient none
SSLCACertificateFile "conf/ssl.crt/ca.crt"
SSLCACertificatePath "conf/ssl.crt"
<Directory "/usr/local/apache2/htdocs/secure/area">
SSLVerifyClient require
SSLVerifyDepth 5
SSLOptions +FakeBasicAuth
SSLRequireSSL
AuthName "Snake Oil Authentication"
AuthType Basic
AuthBasicProvider file
AuthUserFile "/usr/local/apache2/conf/httpd.passwd"
Require valid-user
</Directory> В этом примере используется пароль в виде строки, зашифрованной с помощью DES: "password". Дополнительные сведения см. в документации SSLOptions.
httpd.passwd
/C=DE/L=Munich/O=Snake Oil, Ltd./OU=Staff/CN=Foo:xxj31ZMTZzkVA /C=US/L=S.F./O=Snake Oil, Ltd./OU=CA/CN=Bar:xxj31ZMTZzkVA /C=US/L=L.A./O=Snake Oil, Ltd./OU=Dev/CN=Quux:xxj31ZMTZzkVA
Если все ваши клиенты относятся к одной иерархии, закодированной в различительном имени, их проще сопоставить с помощью SSLRequire, например:
SSLVerifyClient none
SSLCACertificateFile "conf/ssl.crt/ca.crt"
SSLCACertificatePath "conf/ssl.crt"
<Directory "/usr/local/apache2/htdocs/secure/area">
SSLVerifyClient require
SSLVerifyDepth 5
SSLOptions +FakeBasicAuth
SSLRequireSSL
SSLRequire %{SSL_CLIENT_S_DN_O} eq "Snake Oil, Ltd." \
and %{SSL_CLIENT_S_DN_OU} in {"Staff", "CA", "Dev"}
</Directory> Как потребовать HTTPS с надёжными шифрами и базовую аутентификацию либо сертификаты клиентов для доступа к части сайта интрасети клиентам из Интернета? При этом я хочу разрешить клиентам во внутренней сети использовать обычный HTTP.
В этих примерах предполагается, что IP-адреса клиентов во внутренней сети находятся в диапазоне 192.168.1.0/24, а часть сайта интрасети, к которой нужно разрешить доступ из Интернета, — это /usr/local/apache2/htdocs/subarea. Эта конфигурация должна находиться вне виртуального хоста HTTPS, чтобы применяться и к HTTPS, и к HTTP.
SSLCACertificateFile "conf/ssl.crt/company-ca.crt"
<Directory "/usr/local/apache2/htdocs">
# Outside the subarea only Intranet access is granted
Require ip 192.168.1.0/24
</Directory>
<Directory "/usr/local/apache2/htdocs/subarea">
# Inside the subarea any Intranet access is allowed
# but from the Internet only HTTPS + Strong-Cipher + Password
# or the alternative HTTPS + Strong-Cipher + Client-Certificate
# If HTTPS is used, make sure a strong cipher is used.
# Additionally allow client certs as alternative to basic auth.
SSLVerifyClient optional
SSLVerifyDepth 1
SSLOptions +FakeBasicAuth +StrictRequire
SSLRequire %{SSL_CIPHER_USEKEYSIZE} >= 128
# Force clients from the Internet to use HTTPS
RewriteEngine on
RewriteCond "%{REMOTE_ADDR}" "!^192\.168\.1\.[0-9]+$"
RewriteCond "%{HTTPS}" "!=on"
RewriteRule "." "-" [F]
# Allow Network Access and/or Basic Auth
Satisfy any
# Network Access Control
Require ip 192.168.1.0/24
# HTTP Basic Authentication
AuthType basic
AuthName "Protected Intranet Area"
AuthBasicProvider file
AuthUserFile "conf/protected.passwd"
Require valid-user
</Directory> Ведение журналов
mod_ssl может записывать в журнал ошибок чрезвычайно подробную отладочную информацию, если для параметра LogLevel заданы более высокие уровни трассировки. С другой стороны, на очень загруженном сервере даже уровень info может оказаться избыточным. Помните, что параметр LogLevel можно настроить отдельно для каждого модуля в соответствии с вашими потребностями.
© 2018 The Apache Software Foundation
Licensed under the Apache License, Version 2.0.
https://httpd.apache.org/docs/2.4/en/ssl/ssl_howto.html