Как стать автором
Обновить

Apache HTTP Server: Обслуживание нескольких HTTPS-хостов на одном IP-адресе

При миграции сервера в облако возникла необходимость разместить несколько веб-сайтов, работающих по HTTPS на одном физическом IP-адресе.
При этом нужно было остаться на той же операционной системе CentOS 5.6 и штатном apache-2.2.19.
Готового решения для CentOS не нашел, поэтому предлагаю свой вариант решения.

Согласно RFC 4366, раздел «3.1. Server Name Indication» это возможно.
Для полноценной работы это расширение должен поддерживать и сервер и клиент (браузер).

Поддержка расширения SNI появилась в Apache HTP Server начиная с версии 2.2.12.
Подробности: Apache Wiki: NameBasedSSLVHostsWithSNI и Changes with Apache 2.2.12.
Для работы расширения нужна библиотека OpenSSL версии 0.9.8f или выше.
Проблема в том, что в CentOS 5.6 встроен OpenSSL версии 0.9.8e, и «поднять» ему версию не так то просто, т.к. именно на эту версию завязано много других компонент.
Собирать отдельный OpenSSL и Apache вне дерева пакетов — неспортивно.
В процессе поиска решения наткнулся на альтернативу: библиотеку gnutls и модуль mod_gnutls.
Библиотека gnutls в системе тоже присутствует и тоже очень старая, правда достаточно безболезненно удаляется вместе с зависимостями.

В результате были собраны и установлены «свежие» пакеты gnutls и mod_gnutls, которые дали нужный функционал с минимальным влиянием на остальную систему.
Под катом подробности по процессу сборки и примеры файлов конфигурации.

Сборка пакетов


Для сборки понадобятся *-devel пакеты из штатных репозитариев, список нужных пакетов приводить не буду.
  1. Из комплекта Fedora Core 15 (Fedora Mirror List) установил пакеты libtasn1-2.7-2.fc15.src.rpm и gnutls-2.10.5-1.fc15.src.rpm. Для установки нужен ключ "--nomd5", если cpio ругается на несовпадение md5, т.к. srpm собран в более новой версии.
  2. С домашней страницы проекта (mod_gnutls) взял актуальную версию исходных кодов модуля.
  3. В качестве спек-файла взят mod_gnutls.spec из http://dev.centos.org/centos/5/testing/SRPMS/mod_gnutls-0.2.0-1.el5.centos.src.rpm.
    К команде "%configure" добавил ключ "--disable-srp", т.к. SRP выключен в сборке gnutls.
  4. Удалил старые версии пакетов (gnutls libtasn1).
  5. Собрал и установил libtasn1 и gnutls (rpmbuild & yum localinstall).
  6. Из файла /usr/lib64/pkgconfig/gnutls.pc из строки «Requires.private» удалил zlib, т.к. установленный zlib-devel не содержит определения для pkg-config.
  7. Собрал и установил mod_gnutls (rpmbuild & yum localinstall).

Конфигурирование плагина


Файл конфигурации по умолчанию лежит в /etc/httpd/conf.d/mod_gnutls.conf.
Модулю нужен доступ к файлу, в котором ведется его собственный кеш, путь к файлу задается ключем GnuTLSCache.
Нужно выполнить настройку политики безопасности и создать каталог для файла кеша:
semanage fcontext -a -f "" -t httpd_cache_t "/var/cache/mod_gnutls_cache(/.*)?"
mkdir /var/cache/mod_gnutls_cache
chown apache:apache /var/cache/mod_gnutls_cache
chmod 700 /var/cache/mod_gnutls_cache

Пример файла конфигурации модуля mod_gnutls.conf

## Load the module into Apache.
LoadModule gnutls_module modules/libmod_gnutls.so

## Set Certificate MIME-types, may instead be in ssl.conf
AddType application/x-x509-ca-cert .crt
AddType application/x-pkcs7-crl    .crl

## Set TLS Cache info
GnuTLSCache dbm "/var/cache/mod_gnutls_cache/defsrv_home_net.dbm"
GnuTLSCacheTimeout 300

Конфигурирование виртуальных хостов


При конфигурировании нужно учесть несколько моментов:
  • Желательно полностью отключить mod_ssl.
  • Каждый VirtualHost должен быть или полностью HTTP или полностью HTTPS, при «смешанном» варианте по протоколу HTTP все равно приходят SSL-шифрованные данные.
  • Виртуальный HTTPS-хост «по-умолчанию» обязательно должен иметь сертификат и ключ, т.к. первоначальное соединение происходит именно с ним.

Пример конфигурации VirtualHost

Listen 80
Listen 443

NameVirtualHost *:80
NameVirtualHost *:443

ServerName defsrv.home.net

# По умолчанию все запросы перенаправляются на основной сайт (http://www.home.net)
<VirtualHost _default_:80>
    Redirect permanent / http://www.home.net/
</VirtualHost>

# SSL-сертификат у дефолтного сервера должен присутсвовать обязательно!
<VirtualHost _default_:443>
    GnuTLSEnable          on
    GnuTLSPriorities      NORMAL
    GnuTLSCertificateFile /etc/httpd/certs/defsrv_home_net.crt
    GnuTLSKeyFile         /etc/httpd/certs/defsrv_home_net.key
    Redirect permanent / https://www.home.net/
</VirtualHost>

<VirtualHost *:80>
    ServerName www.home.net:80
    DocumentRoot /srv/www.home.net
    #Конфигурация хоста
</VirtualHost>

<VirtualHost *:443>
    ServerName www.home.net:443
    DocumentRoot /srv/www.home.net
    GnuTLSEnable          on
    GnuTLSPriorities      NORMAL
    GnuTLSCertificateFile /etc/httpd/certs/www_home_net.crt
    GnuTLSKeyFile         /etc/httpd/certs/www_home_net.key
    #Конфигурация хоста
</VirtualHost>

<VirtualHost *:443>
    ServerName test.home.net:443
    DocumentRoot /srv/test.home.net
    GnuTLSEnable          on
    GnuTLSPriorities      NORMAL
    GnuTLSCertificateFile /etc/httpd/certs/test_home_net.crt
    GnuTLSKeyFile         /etc/httpd/certs/test_home_net.key
    #Конфигурация хоста
</VirtualHost>
Теги:
Хабы:
Данная статья не подлежит комментированию, поскольку её автор ещё не является полноправным участником сообщества. Вы сможете связаться с автором только после того, как он получит приглашение от кого-либо из участников сообщества. До этого момента его username будет скрыт псевдонимом.