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

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

Теория


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

Практика


Поддержка расширения SNI согласно Wikipedia появилась в Apache HTTP Server начиная с версии 2.2.12.
Подробности есть в Apache Wiki.
Для работы расширения нужна библиотека 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
  2. С домашней страницы проекта (mod_gnutls) взял актуальную версию исходных кодов модуля.
  3. Установил пакеты исходных кодов (ключ --nomd5 нужен, если cpio ругается на несовпадение md5, т.к. srpm собран в более новой версии)
    rpm -ivh --nomd5 libtasn1-2.7-2.fc15.src.rpm
    rpm -ivh --nomd5 gnutls-2.10.5-1.fc15.src.rpm
  4. Архив исходных кодов (mod_gnutls-0.5.9.tar.bz2) cкопировал в /usr/src/redhat/SOURCES.
  5. В /usr/src/redhat/SPECS создал файл mod_gnutls.spec. За основу взят mod_gnutls.spec из http://dev.centos.org/centos/5/testing/SRPMS/mod_gnutls-0.2.0-1.el5.centos.src.rpm.
    Содержимое файла в конце поста (mod_gnutls.spec).
  6. Удалил старые пакеты вместе с зависимостями:
    yum erase gnutls libtasn1
  7. Собрал libtasn1:
    rpmbuild -bb --clean /usr/src/redhat/SPECS/libtasn1.spec
  8. Установил пакеты libtasn1:
    yum localinstall --nogpgcheck /usr/src/redhat/RPMS/x86_64/libtasn1-*.rpm
  9. Собрал gnutls:
    rpmbuild -bb --clean /usr/src/redhat/SPECS/gnutls.spec
  10. Установил пакеты gnutls:
    yum localinstall --nogpgcheck /usr/src/redhat/RPMS/x86_64/gnutls-*.rpm
  11. Из файла /usr/lib64/pkgconfig/gnutls.pc из строки Requires.private удалил zlib, т.к. установленный zlib-devel не содержит определения для pkg-config.
  12. Собрал mod_gnutls:
    rpmbuild -bb --clean /usr/src/redhat/SPECS/mod_gnutls.spec
  13. Установил пакеты mod_gnutls:
    yum localinstall --nogpgcheck /usr/src/redhat/RPMS/x86_64/mod_gnutls-*.rpm

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


Модулю нужен доступ к файлу, в котором ведется его собственный кеш, путь к файлу задается ключем GnuTLSCache в файле конфигурации.
Если включен selinux, нужно выполнить настройку политики:
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
Файл конфигурации по умолчанию лежит в /etc/httpd/conf.d/mod_gnutls.conf.

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

## Documentation Link:
## http://www.outoforder.cc/projects/apache/mod_gnutls/docs/

## 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/server1_test_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
    UseCanonicalName On
    ServerAdmin webmaster@www.home.net
    DocumentRoot /srv/www.home.net

    #Конфигурация хоста

</VirtualHost>

<VirtualHost *:443>

    ServerName www.home.net:443
    UseCanonicalName On
    ServerAdmin webmaster@www.home.net
    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 *:80>

    ServerName test.home.net:80
    UseCanonicalName On
    ServerAdmin webmaster@test.home.net
    DocumentRoot /srv/test.home.net

    #Конфигурация хоста

</VirtualHost>

<VirtualHost *:443>

    ServerName test.home.net:443
    UseCanonicalName On
    ServerAdmin webmaster@test.home.net
    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>


Спек-файл (mod_gnutls.spec)

Summary:        mod_gnutls is a DSO module for the apache Web server.
Name:           mod_gnutls
Version:        0.5.9
Release:        1%{?dist}
Group:          System Environment/Daemons
URL:            http://www.outoforder.cc/projects/apache/mod_gnutls/
Source:         http://www.outoforder.cc/downloads/mod_gnutls/%{name}-%{version}.tar.bz2
Source1:        mod_gnutls.conf
License:        Apache Software License
BuildRoot:      %{_tmppath}/%{name}-root
BuildRequires:  httpd-devel > 2.0.42
BuildRequires:  gnutls >= 1.2.0, gnutls-devel >= 1.2.0, gnutls-utils >= 1.2.0, apr-devel
Requires:       httpd-mmn = %(cat %{_includedir}/httpd/.mmn || echo missing httpd-devel)
Requires:       gnutls >= 1.2.0, httpd >= 2.0.42

%description
mod_gnutls uses the GnuTLS library to provide SSL v3, TLS 1.0 and TLS 1.1
encryption for Apache HTTPD.  It is similar to mod_ssl in purpose, but does
not use OpenSSL.

%prep
%setup -q

%build
%configure --disable-srp

make

%install
[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT
mkdir -p $RPM_BUILD_ROOT%{_libdir}/httpd/modules
install -m755 src/.libs/lib%{name}.so $RPM_BUILD_ROOT%{_libdir}/httpd/modules

# Install the config file
mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/httpd/conf.d
install -m 644 %{SOURCE1} \
   $RPM_BUILD_ROOT%{_sysconfdir}/httpd/conf.d/
mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/httpd/conf

#Create a cache directory
mkdir -p -m 0700 $RPM_BUILD_ROOT%{_var}/cache/mod_gnutls_cache

%clean
[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT
%files
%defattr(-,root,root)
%doc LICENSE NOTICE README
%{_libdir}/httpd/modules/*.so
%config(noreplace) %{_sysconfdir}/httpd/conf.d/*.conf
%attr(0700, apache, apache) %{_var}/cache/mod_gnutls_cache
Метки:
Поделиться публикацией
Похожие публикации
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама
Комментарии 32
  • –4
    Хммм, не об этом ли статья?
    • 0
      Чувствуете разницу между nginx и apache?
      • 0
        Да куда нам, болезным, мы ж не заем ничего.
        Теперь еще раз ознакомьтесь с содержимым ссылки, на этот раз не торопитесь.
        • 0
          В этой статье рассказывается о настройке нескольких https-доменов на одном IP на примере apache, в Вашей — на примере nginx. Это разные статьи. Нет?
          • –4
            Где я утверждал, что статьи одинаковые?
            • 0
              Ок, значит я неправильно понял смысл Вашего комментария
    • 0
      Там отдается один и тот же сертификат. Браузер ругаться будет.
      • 0
        там ниже написано что есть еще 2 решения
        wildcard cert и SNI
        а эта статья всетаки не об этом.
        • 0
          wildcard это не решение проблемы множественных сайтов на одном IP, т.к. работает только в контексте одного домена. Захочется повесить еще один — проблема появится снова.
          • 0
            Ага, вот еще эксперты набежали. Неужели так сложно прочитать пару строк текста, перед тем, как выставлять себя невеждой?
        • –2
          А если набраться мужества и дочитать до конца?
      • +1
        Offtopic. Я не понимаю зачем ставить CentOS или RHEL, подключать к нему кучу неофициальных репозиториев и пересобирать руками то, чего в этих репозиториях не оказалось.
        • 0
          ставящие Enterprise знают зачем,
          остальным можно и федору)
          • 0
            Так зачем, если все критичные компоненты системы из левых репозиториев или самосбор?
            • 0
              mod_gnutls этож не все…
              • +4
                На Хабре чуть ли не в каждой статье «на примере CentOS» предложение что-нибудь пересобрать.
            • +1
              Enterprise, такой Enterprise :)
            • +1
              К сожалению, очень много ПО поставляется в сборе только под Enterprise Linux: Oracle Linux, RHEL, SLES. Гришат этим, например, производители всяких стораджей, Oracle, IBM, VMWare. А по стабильности с ними сравним debian stable, но никак не фидора. Хотя в SLES11 попадаются иногда очень неприятные баги.
              • +4
                Во-первых потому что у них долгий цикл поддержки (очень долгий). Обновлять федору или убунту каждые пол года — не вариант. На одном из проектов мы только относительно недавно избавились от старого сервера с RHEL3 — и то только потому что железо уж очень устарело.
                Во-вторых потому что их хорошо тестируют и в часто можно спокойно делать `yum update -y`, особенно если ничего стороннего нету.
                В-третьих (в случае RHEL) — это поддержка, всякие вкусности типа RHN, безпроблемная поддержка всяким коммерческим и не очень софтом.

                Естественно есть и свои минусы.
                • 0
                  Долгий цикл поддержки — несомненно плюс. Но заметьте, я говорил о случаях подключения левых репозиториев и пересборки софта руками. Не проще ли использовать, например, Debian stable? Цикл обновления — примерно раз в три года.

                  > особенно если ничего стороннего нету
                  В репозиториях CentOS очень часто нет довольно нужных инструментов, поэтому без стороннего обойтись бывает довольно сложно. Например? rrdtool.

                  • 0
                    Debian stable — тоже хорош, со своими достоинствами и недостатками. Почему не использовать — в некоторых случаях 3-х лет мало, поддержки коммерческой насколько я знаю нету или она не так хороша, да и всякий закрытый софт в нем может работать с глюками.

                    При этом собрать для rhel/centos тот же rrdtool и добавить его в свой репозиторий — как правило не проблема, для debian скорее всего тоже придется что-то добавлять, и аналогично делать репозиторий — а тут уже не так важно — один там пакет или десять.
                  • +2
                    Обнимемся, брат. Отчего-то никто вокруг этого не понимает, я устал уже объяснять. «Нах платить за линукс, он же бесплатный. Свобода, равенство, упячка!» Подобные красноглазые вопли уже поднадоели. Ценится не ОС, ценятся решения.
                    Конечно, тихий ужас в виде компиляции из тарболов в бинарном дистрибутиве тоже наотмашь серпом по яйцам.
                    • 0
                      Вообще тут надо включать голову и искать компромис.
                      Если проект завязан на вашем ПО (например на java) то имеет смысл ставить RHEL/SLES and etc.
                      Если надо все же какой то боевый сервер со свежими решениями, то смотрим в сторону более свежего.
                      Вот мне нравится ubuntu LTS (конечно и там хватает косяков) но в целом все хорошо и софт оптимальный между старым и новым.
                      • +1
                        Про компромисс-то очевидно. Но вот все же фраза «боевый сервер со свежими решениями» мне не вполне понятна.
                        Standart support у canonical стоит более 700 долларов за один сервер, кстати. Ну, как всегда, оптом дешевле, естественно.
                        • +1
                          новый софт — не значит глючный.

                          ubuntu lts — в этом плане меня полностью устроила. Софт — морально не устарел, и нормальная стабильность.

                          Те — там где — это можно, я отдаюсь на растерзания мантейнерам.
                          Там где платят, можно и руками собрать и репозиторий свой сделать :)
                          • 0
                            Согласен.
                            Только вот что значит «морально устарел»? Это же не модный аксессуар. Если софт решает задачу и получает фиксы безопасности (пусть и из бекпортов), то нет никакого смысла в этой фразе.
                            • +1
                              ну вот мы и раставили все точки. Да конечно, я имел ввиду, что старый софт — который не позволяет сделать то, что тебе надо. Обычно надо как раз новые плюшки, которые в более новым софте.
                      • 0
                        :)

                        Но покраснаглазить я тоже люблю — на личных машинах и для всяких экспериментов у меня gentoo. :)
                        • +1
                          Это, кстати, еще одна жирная точка. Gentoo (и ей подобные «сделай сам») отличная, но именно для таких целей.
                  • 0
                    Забавно, но XP+IE и с другой стороны NSS в пролете.
                    • 0
                      А зачем столько мороки со сборкой? Как правило обычный `rpmbuild --rebuild whatever.src.rpm` отлично работает.
                      (хотя я обычно тоже немного модифицирую спеки, но в основном для того чтобы они хорошо смотрелись в моем репозитории)

                      Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.