Apache 2 с SSL/TLS: Шаг за Шагом, Часть 1

Apache 2 с SSL/TLS: Шаг за Шагом, Часть 1

Можно только догадываться, сколько миллиардов долларов переводится каждый день в транзакциях с использованием SSL. К сожалению, сам факт использования SSL не говорит о том, что передаваемая через этот протокол информация действительно безопасна.

Автор Artur Maj

Более десяти лет SSL протокол используется для шифрования соединений в Интернет. Можно только догадываться, сколько миллиардов долларов переводится каждый день в транзакциях с использованием SSL. К сожалению, сам факт использования SSL не говорит о том, что передаваемая через этот протокол информация действительно безопасна. Использование слабого алгоритма шифрования, невозможность удостоверения сертификатов серверов, бреши в безопасности веб-серверов или библиотек SSL, также как и другие атаки, позволяют злоумышленнику получить доступ к чувствительной информации.

Это первая статья в цикле статей, посвященных настройке Apache 2.0 с поддержкой SSL/TLS в целях достижения максимальной безопасности и оптимальной производительности SSL-соединений. В первой части этой статьи будут описаны ключевые аспекты SSL/TLS, а затем показано - как настроить Apache 2.0 с поддержкой этих протоколов. Во второй части будет описан процесс настройки mod_ssl, далее – вопросы адресов с аутентификацией веб-сервера. Кроме того, во второй части мы разберемся, как создать SSL-сертификат веб-сервера. Третья и последняя часть этой серии расскажет об аутентификации клиента, а также о некоторых типичных ошибках настройки, которые допускают системные администраторы, что резко снижает уровень безопасности любого SSL-соединения.

Введение в SSL

Secure Sockets Layer (SSL-протокол защищенных сокетов - прим. пер.) самое известное и достаточно надежное средство соединения по модели клиент-сервер с использованием Интернет. SSL сам по себе довольно простой в плане понимания: он устанавливает алгоритмы шифрования и ключи на обоих сторонах и прокидывает шифрованный туннель, по которому могут передаваться другие протоколы (например HTTP). Опционально в SSL имеется возможность аутентификации обоих сторон через использование сертификатов.

SSL - это многоуровневый протокол и состоит из четырех под-протоколов:

  • SSL Handshake Protocol
  • SSL Change Cipher Spec Protocol
  • SSL Alert Protocol
  • SSL Record Layer

Места вышеуказанных протоколов, в соответствии с моделью стека протоколов TCP/IP показаны на Рисунке 1.

Figure 1.

Figure 1. Подпротоколы SSL в модели TCP/IP

Как видно на диаграмме, SSL находится на уровне приложений модели TCP/IP. Благодаря этому, SSL может быть развернут почти на любой ОС, поддерживающей TCP/IP, без какой либо правки ядра системы или TCP/IP стека. В результате SSL имеет преимущества перед другими протоколами, такими как IPSec (IP Security Protocol), который требует поддержки модифицированного TCP/IP стека ядром системы. Кроме того, SSL легко пропускают брандмауэры, прокси и NAT (Network Address Translation - Преобразование Сетевых Адресов – прим.пер.) без проблем.

Как работает SSL? На блок-схеме на Рисунке 2 показан упрощенный пошаговый процесс установки SSL соединения между клиентом (обычно веб-браузер) и сервером (чаще всего SSL веб-сервер).

Figure 2.

Рисунок 2. Установка SSL соединений, шаг за шагом.

Итак, процесс установки соединения каждого нового SSL соединения начинается с обмена параметрами шифрования, а затем (опционально) происходит аутентификация серверов (через SSL Handshake Protocol). Если «рукопожатие» удалось, и обе стороны согласились на один и тот же алгоритм шифрования и ключи шифрования, данные приложения (обычно HTTP, но может быть и другой) могут быть переданы по зашифрованному каналу (используется SSL Record Layer).

Если рассматривать реальную ситуацию, то процесс, описанный выше, выглядит намного сложнее. Чтобы избежать ненужных «рукопожатий» некоторые параметры шифрования кэшируются. При этом могут быть посланы предупреждающие сообщения. Также могут быть изменены блоки шифра. Как бы то ни было, не зависимо от тонкостей спецификации SSL, в общем виде этот процесс работает примерно так, как показано на Рисунке 2.

SSL, PCT, TLS и WTLS (но не SSH)

Хотя SSL - самый известный и популярный, но не единственный протокол, используемый для защиты веб транзакций. Важно знать, что со времени изобретения SSL v1.0 (релиза которого, кстати говоря, не было) появилось, как минимум, пять протоколов, сыгравших более-менее важную роль в защите доступа к World Wide Web:

SSL v2.0

Релиз выпущен фирмой Netscape Communications в 1994. Основной целью этого протокола было повысить безопасность транзакций через World Wide Web. К несчастью, очень быстро нашлось несколько критических брешей в безопасности этой версии, что сделало его ненадежным для коммерческого использования:

  • Слабая конструкция MAC
  • Возможность принудительных партий для использования слабого алгоритма шифрования
  • Отсутствие защиты «рукопожатий»
  • Возможность злоумышленника осуществить атаки принудительного завершения

PCT v1.0

Разработан в 1995 году корпорацией Microsoft. В Privacy Communication Technology (PCT - Технология Конфиденциальной Связи – прим.пер.) v1.0 были усилены некоторые слабые места SSL v2.0, корпорация планировала заменить тем самым SSL. Однако, этот протокол так никогда и не получил популярности из-за появления SSL v3.0.

SSL v3.0

Релиз выпущен в 1996 году компанией Netscape Communications. В SSL v3.0 были решены большинство проблем SSL v2.0 и заимствовано множество возможностей нового для того времени протокола PCT, вследствие чего он быстро стал самым популярным протоколом для защиты соединений через WWW.

TLS v1.0 (также известный как SSL v3.1)

Опубликован IETF (Internet Engineering Task Force - Проблемная Группа Проектирования Интернет – прим.пер.) в 1999 году (RFC 2246). Протокол базируется на SSL v3.0 и PCT и согласован как с методами Netscape, так и с корпорацией Microsoft. Стоит заметить, что если TLS базируется на SSL, он не 100% совместим со своим предшественником. IETF сделала некоторые поправки в безопасности, например использование HMAC вместо MAC, использование другого пересчета основного шифра и ключевого материала, добавлены коды предупреждения, отсутствует поддержка алгоритмов шифрования Fortezza и т.д. В конце концов множество противоречивых изменений привели к тому, что эти протоколы толком не могли взаимодействовать. К счастью, появился мод TLS с откатом до SSL v3.0.

WTLS

«Мобильная и беспроводная» версия протокола TLS, которая использует в качестве носителя UDP протокол. Он разработан и оптимизирован под нижнюю полосу частот и меньшую пропускную способность мобильных устройств с поддержкой WAP (Wireless Application Protocol – Протокол Беспроводных Приложений – прим.пер.). WTLS был представлен с протоколом WAP 1.1 и был опубликован на форуме WAР. Однако, после релиза WAP 2.0, WTLS заменили профилированной версией TLS, которая оказалась намного безопаснее – в основном из-за того, что в этой версии нет необходимости расшифровки и перешифровки трафика на WAP шлюзе.

Почему протокол SSH (Secure Shell) не используется для обеспечения безопасного доступа к World Wide Web? Вот несколько причин: во-первых, с самого начала TLS и SSL были разработаны для защиты веб (HTTP) сессий, тогда как SSH задумывался как альтернатива Telnet и FTP. SSL не выполняет ничего, кроме «рукопожатия» и установки зашифрованного туннеля, а в SSH имеется возможность консольной авторизации, защищенной передачи файлов и поддержка сложной схемы аутентификации (включая пароли, публичные ключи, Kerberos и др.). С другой стороны, SSL/TLS базирован на сертификатах X.509v3 и PKI, что делает распространение и управление аутентификационными мандатами намного проще. Следовательно, эти и другие причины делают SSL/TLS более удобным для защиты WWW доступа и подобных форм соединений, включая SMTP, LDAP и другие – тогда как SSH больше удобен для удаленного управления системой.

В итоге, несмотря на существование нескольких «безопасных» протоколов, только два следует использовать для защиты веб-транзакций (по крайней мере сейчас): TLS v1.0 и SSL v3.0. Оба протокола будут дальше рассмотрены в этих статьях как SSL/TLS. Из-за известных слабостей SSL v2.0, и знаменитой «WAP дыры» в случае с WTLS, использования таких протоколов следует избегать или максимально уменьшать.

Установка Apache с поддержкой SSL/TLS

Первым шагом в установке Apache с поддержкой SSL/TLS будет настройка и установка Apache 2 веб-сервера и создание пользователя и группы с именем "apache". Безопасный способ установки Apache 2.0 уже был рассмотрен на Securing Apache 2.0: Step-by-Step. Единственное отличие в том, что нужно включить mod_ssl и mod_setenvif, которые требуются для совместимости с некоторыми версиями MS Internet Explorer, как описано ниже (изменения выделены жирным):

./configure \ 
--prefix=/usr/local/apache2 \ 
--with-mpm=prefork \ 
--enable-ssl \  
--disable-charset-lite \ 
--disable-include \ 
--disable-env \ 
--enable-setenvif \ 
--disable-status \ 
--disable-autoindex \ 
--disable-asis \ 
--disable-cgi \ 
--disable-negotiation \ 
--disable-imap \ 
--disable-actions \ 
--disable-userdir \ 
--disable-alias \ 
--disable-so
После настройки мы можем установить Apache в конечную директорию:

make
su
umask 022
make install
chown -R root:sys /usr/local/apache2

Настройка SSL/TLS

Перед запуском Apache в первый раз, нам нужно подготовить некоторую начальную конфигурацию и образец веб-контента. Как минимум, мы должны сделать следующее (под root):

  1. Создание некоторого веб-контента, который будет обслуживаться через TLS/SSL:
umask 022
mkdir /www
echo "<html><head><title>Test</title></head><body> \  
Test works.</body></html>" > /www/index.html
chown -R root:sys /www
  1. Удаление конфигурационного файла Apache, созданного по умолчанию (обычно находится в /usr/local/apache2/conf/httpd.conf) и замена его новым, с использованием следующего контента (оптимизировано для обеспечения безопасности и производительности).
# =================================================
# Basic settings
# =================================================
User apache
Group apache
ServerAdmin webmaster@www.seccure.lab     
ServerName www.seccure.lab
UseCanonicalName Off
ServerSignature Off
HostnameLookups Off
ServerTokens Prod
ServerRoot "/usr/local/apache2"
DocumentRoot "/www"
PidFile /usr/local/apache2/logs/httpd.pid
ScoreBoardFile /usr/local/apache2/logs/httpd.scoreboard
<IfModule mod_dir.c>
    DirectoryIndex index.html
</IfModule>
# =================================================
# HTTP and performance settings
# =================================================
Timeout 300
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 30
<IfModule prefork.c>
    MinSpareServers 5
    MaxSpareServers 10
    StartServers 5
    MaxClients 150
    MaxRequestsPerChild 0
</IfModule>
# =================================================
# Access control
# =================================================
<Directory />
    Options None
    AllowOverride None
    Order deny,allow
    Deny from all
</Directory>
<Directory "/www">
    Order allow,deny
    Allow from all
</Directory>
# =================================================
# MIME encoding
# =================================================
<IfModule mod_mime.c>
    TypesConfig /usr/local/apache2/conf/mime.types
</IfModule>
DefaultType text/plain
<IfModule mod_mime.c>
    AddEncoding x-compress              .Z
    AddEncoding x-gzip                  .gz .tgz
    AddType application/x-compress      .Z
    AddType application/x-gzip          .gz .tgz
    AddType application/x-tar           .tgz
    AddType application/x-x509-ca-cert  .crt
    AddType application/x-pkcs7-crl     .crl
</IfModule>
# =================================================
# Logs
# =================================================
LogLevel warn
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %b" common
LogFormat "%{Referer}i -> %U" referer
LogFormat "%{User-agent}i" agent
ErrorLog /usr/local/apache2/logs/error_log
CustomLog /usr/local/apache2/logs/access_log combined
CustomLog logs/ssl_request_log \  
"%t %h %{HTTPS}x %{SSL_PROTOCOL}x %{SSL_CIPHER}x \  
%{SSL_CIPHER_USEKEYSIZE}x %{SSL_CLIENT_VERIFY}x \"%r\" %b"
# =================================================
# SSL/TLS settings
# =================================================
Listen 0.0.0.0:443
SSLEngine on
SSLOptions +StrictRequire
<Directory />
    SSLRequireSSL
</Directory>
SSLProtocol -all +TLSv1 +SSLv3
SSLCipherSuite HIGH:MEDIUM:!aNULL:+SHA1:+MD5:+HIGH:+MEDIUM
SSLMutex file:/usr/local/apache2/logs/ssl_mutex
SSLRandomSeed startup file:/dev/urandom 1024
SSLRandomSeed connect file:/dev/urandom 1024
SSLSessionCache shm:/usr/local/apache2/logs/ssl_cache_shm
SSLSessionCacheTimeout 600
SSLPassPhraseDialog builtin
SSLCertificateFile /usr/local/apache2/conf/ssl.crt/server.crt
SSLCertificateKeyFile /usr/local/apache2/conf/ssl.key/server.key
SSLVerifyClient none
SSLProxyEngine off
<IfModule mime.c>
    AddType application/x-x509-ca-cert      .crt
    AddType application/x-pkcs7-crl         .crl
</IfModule>
SetEnvIf User-Agent ".*MSIE.*" \  
  nokeepalive ssl-unclean-shutdown \  
  downgrade-1.0 force-response-1.0

Заметьте: читатели должны изменить некоторые значения этого конфигурационного файла, таких как имя веб-сервера, e-mail администратора и т.д.

  1. Подготовим структуры директории для приватных ключей веб-сервера, сертификатов и списков аннулированных сертификаций (CRLs - certification revocation lists)
umask 022
mkdir /usr/local/apache2/conf/ssl.key
mkdir /usr/local/apache2/conf/ssl.crt
mkdir /usr/local/apache2/conf/ssl.crl
  1. Создаем самоподписанный серверный сертификат (следует использовать только для тестов – ваш настоящий сертификат должен быть от достоверного СА – такого как Verisign):
openssl req \ 
-new \ 
-x509 \ 
-days 30 \ 
-keyout /usr/local/apache2/conf/ssl.key/server.key \ 
-out /usr/local/apache2/conf/ssl.crt/server.crt \ 
-subj '/CN=Test-Only Certificate'

Проверяем установку

Теперь можно запустить Apache с поддержкой SSL/TLS:

/usr/local/apache2/bin/apachectl startssl
Apache/2.0.52 mod_ssl/2.0.52 (Pass Phrase Dialog)
Some of your private key files are encrypted for security reasons.
In order to read them you have to provide us with the pass phrases.
Server 127.0.0.1:443 (RSA)
Enter pass phrase:*************
Ok: Pass Phrase Dialog successful.

После запуска сервера мы можем попробовать соединиться к нему, направив веб-браузер на URL: https://имя сервера (в нашем случае, https://www.seccure.lab)

Через некоторое время мы должны увидеть предупреждающее сообщение о том, что в ходе проверки аутентифифкации веб-сервера возникла проблема. На Рисунке 3 показан пример такого сообщения в MS Internet Explorer 6.0.

Figure 3.

Рисунок 3. Примерное сообщение о сертификате в IE 6.

Все работает правильно. Следует принять это сообщение из-за двух причин:

  • Веб-браузер не знает Certificate Authority, использовавшийся при создании данного сертификата (и не может знать, ведь мы используем самоподписанный сертификат)
  • Атрибут CN (Common Name – Общее Имя) сертификата не совпадает с именем веб-сайта – на данный момент «Test-Only Certificate» (Только для Тестирования), а должен быть полностью определенное доменное имя веб сервера (например www.seccure.lab)

После нажатия кнопки «Yes», мы увидим следующее веб содержимое:

Figure 4.

Рисунок 4. Пример работы SSL веб страницы.

Внизу окна браузера появился желтый замок, означающий что SSL соединение было успешно установлено. Значение "128-bit" говорит о том, что симметричный ключ, используемый для шифрования равен 128 бит, что довольно таки неплохо (по крайней мере сейчас) для защиты трафика от неавторизованного доступа.

Выполнив двойной щелчок по значку замка, мы увидим свойства сертификата:

Figure 5.

Рисунок 5. Подробнее о нашем самоподписанном сертификате.

Диагностика неисправностей

Если по каким-то причинам мы не можем получить доступ к веб-сайту, можно воспользоваться очень полезной утилитой "s_client" от библиотеки OpenSSL. Пример использования этой утилиты:

/usr/bin/openssl s_client -connect localhost:443
CONNECTED(00000003)
depth=0 /CN=Test-Only Certificate
verify error:num=18:self signed certificate
verify return:1
depth=0 /CN=Test-Only Certificate
verify return:1
---
Certificate chain
0 s:/CN=Test-Only Certificate
i:/CN=Test-Only Certificate
---
Server certificate
-----BEGIN CERTIFICATE-----
MIICLzCCAZigAwIBAgIBADANBgkqhkiG9w0BAQQFADAgMR4wHAYDVQQDExVUZXN0
LU9ubHkgQ2VydGlmaWNhdGUwHhcNMDQxMTIyMTg0ODUxWhcNMDQxMjIyMTg0ODUx
WjAgMR4wHAYDVQQDExVUZXN0LU9ubHkgQ2VydGlmaWNhdGUwgZ8wDQYJKoZIhvcN
AQEBBQADgY0AMIGJAoGBAMEttnihJ7JpksdToPi5ZVGcssUbHn/G+4G43OiLhP0i
KvYuqNxBkSqqM1AanR0BFVEtVCSuq8KS9LLRdQLJ/B1UTMOGz1Pb14WGsVJS+38D
LdLEFaCyfkjNKnUgeKMyzsdhZ52pF9febB+d8cLmvXFve28sTIxLCUK7l4rjT3Xl
AgMBAAGjeTB3MB0GA1UdDgQWBBQ50isUEV6uFPZ0L4RbRm41+i1CpTBIBgNVHSME
QTA/gBQ50isUEV6uFPZ0L4RbRm41+i1CpaEkpCIwIDEeMBwGA1UEAxMVVGVzdC1P
bmx5IENlcnRpZmljYXRlggEAMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQAD
gYEAThyofbK3hg8AJXbAUD6w6+mz6dwsBmcTWLvYtLQUh86B0zWnVxzSLDmwgdUB
NxfJ7yfo0PkqNnjHfvnb5W07GcfGgLx5/U3iUROObYlwKlr6tQzMoysNQ/YtN3pp
52sGsqaOOWpYlAGOaM8j57Nv/eXogQnDRT0txXqoVEbunmM=
-----END CERTIFICATE-----
subject=/CN=Test-Only Certificate
issuer=/CN=Test-Only Certificate
---
No client certificate CA names sent
---
SSL handshake has read 1143 bytes and written 362 bytes
---
New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA
Server public key is 1024 bit
SSL-Session:
Protocol : SSLv3
Cipher : DHE-RSA-AES256-SHA
Session-ID: 56EA68A5750511917CC42A1B134A8F218C27C9C0241C35C53977A2A8BBB9986A
Session-ID-ctx:
Master-Key: 303B60D625B020280F5F346AB00F8A61A7C4BEA707DFA0ED8D2F52371F8C4F087FB6EFFC02CE3B48F912D2C8929DB5BE
Key-Arg : None
Start Time: 1101164382
Timeout : 300 (sec)
Verify return code: 18 (self signed certificate)
---
GET / HTTP/1.0
HTTP/1.1 200 OK
Date: Mon, 22 Nov 2004 22:59:56 GMT
Server: Apache
Last-Modified: Mon, 22 Nov 2004 17:24:56 GMT
ETag: "5c911-46-229c0a00"
Accept-Ranges: bytes
Content-Length: 70
Connection: close
Content-Type: text/html
<html><head><title>Test</title></head><body>Test works.</body></html>
closed

Утилита s_client имеет много полезных опций, например включение/выключение отдельного протокола (-ssl2, -ssl3, -tls1), выбор отдельного алгоритма шифрования (-cipher), запуск режима отладки (-debug), просмотр статистик и сообщений SSL/TLS (-state, -msg), и некоторые другие, которые смогут помочь найти причину неполадки.

Если s_client ничем не помог, следует сменить значение LogLevel (в httpd.conf) на "debug" и перезапустить Apache и проверить его логи (/usr/local/apache2/logs/) для дополнительной информации.

Еще можно попробовать Ethereal или ssldump. Благодаря этим утилитам, мы можем пассивно наблюдать SSL сообщения «рукопожатий» и пытаться найти причину неисправности. Вот скриншот использования Ethereal:

Figure 6.

Figure 6. Просмотр SSL «рукопожатия» в Ethereal.

Заключение к первой части

Итак, мы имеем безопасный Apache 2 сервер в состоянии онлайн и пример SSL-сертификата, на чем и заканчивается первая часть. В следующей части вы познакомитесь с рекомендуемыми настройками безопасности и функций для mod_ssl и процессом создания нормального сертификата.

Приватность — это право, а не роскошь.

Подпишитесь на наш канал и защитите свои права