Настройка виртуальных хостов для Apache 2 с поддержкой SSL (https) в Linux Debian

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

Когда пользователь соединяется с сервером по обычному протоколу HTTP, все данные между сервером и обозревателем пользователя передаются в открытом виде. Таким образом, злоумышленник может перехватить не только сами данные, но и пароли пользователя, тем самым просто получить доступ к закрытой зоне сайта.

Решением данной проблемы является использование защищенного протокола HTTPS. При работе с этим протоколом данные передаются в зашифрованном виде. Для каждого сайта может быть использован свой сертификат.

В этой статье идет речь о формировании сертификата для виртуального хоста, на котором будет работать phpmyadmin используемый для управления сервером баз данных MySQL. У каждого виртуального хоста может быть свой сертификат, более того Apache позволяет использовать отдельный сертификат для определенного каталога виртуального хоста. В качестве Web сервера мы используем Apache 2.2. Наш сервер функционирует на базе операционной системы Linux Debian 5.0.4. Соответственно, все приводимые команды используют специфику данного дистрибутива. Если у Вас другой дистрибутив, следует учитывать особенности устройства его структуры файловой системы.

В статье мы не будем рассматривать процесс установки phpmyadmin. Процедура установки подробно описана в прилагаемом к phpmyadmin README и не является сложной.

Прежде всего, устанавливаем требуемое программное обеспечение:

$ sudo apt-get install apache2 openssl openssl-blacklist ssl-cert

Определение имени для виртуального хоста

Обычно, для управления именами используется DNS сервер. В Linux чаще всего — это BIND. Если вы настраиваете виртуальный хост не на локальном компьютере, а на Интернет сервере, то имя виртуального хоста необходимо прописать в файле зоны DNS сервера.

Будем рассматривать формирование сертификатов SSL на примере локального виртуального хоста для работы phpmyadmin. Дабы не усложнять себе жизнь с настройкой DNS сервера, просто внесем в файл /etc/hosts строчку:

127.0.0.1 db.deblocal

Таким образом, после всех выполненных действий по настройке, мы сможем обратиться к нашему виртуальному хосту по адресу: https://db.deblocal/.

Создание новых сертификатов SSL

Создаваемые на данном этапе сертификаты будут использованы при настройке нашего виртуального хоста.

Формирование ключа

Выполнять процедуру формирования ключей и сертификатов можно в любом каталоге и с любыми правами. Я предпочитаю это делать изначально в домашнем каталоге, а потом переписывать полученные файлы в соответствующие им каталоги сертификатов.

Сначала формируем private key:

$ openssl genrsa -des3 -out db.deblocal.key 2048
Generating RSA private key, 2048 bit long modulus
..........+++
.................................................................................+++
e is 65537 (0x10001)
Enter pass phrase for db.deblocal.key:
Verifying - Enter pass phrase for db.deblocal.key:

В процессе формирования ключа будет запрошена ключевая фраза. Необходимо ее ввести и запомнить. Эта фраза нам понадобится позже.

Создание подписанного сертификата

После создания закрытого ключа, можно создавать самоподписанный сертификат (CSR):

$ openssl req -new -key db.deblocal.key -out db.deblocal.csr
Enter pass phrase for db.deblocal.key:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:RU
State or Province Name (full name) [Some-State]:Moscow
Locality Name (eg, city) []:Moscow
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Database
Organizational Unit Name (eg, section) []:
Common Name (eg, YOUR name) []:Andrew
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:

В ходе процедуры формирования самоподписанного сертификата будет запрошена ключевая фраза, которую мы задавали вначале процедуры для закрытого ключа.

Удаление пароля из закрытого ключа

У ключа с паролем есть одна очень неприятная особенность: Apache каждый раз при запуске будет спрашивать этот пароль. Большинство серверов работают автономно и мало кому захочется каждый раз вводить этот пароль.

Пароль удалить достаточно просто:

$ cp db.deblocal.key db.deblocal.orig
$ openssl rsa -in db.deblocal.orig -out db.deblocal.key
Enter pass phrase for db.deblocal.orig:
writing RSA key

На втором этапе необходимо задать пароль закрытого ключа.

Генерация сертификата SSL

Наконец выполняем процедуру генерации сертификата SSL:

$ openssl x509 -req -days 365 -in db.deblocal.csr -signkey db.deblocal.key -out db.deblocal.crt
Signature ok
subject=/C=RU/ST=Moscow/L=Moscow/O=Database/CN=Andrew
Getting Private key

В итоге получаем два основных файла: db.deblocal.key и db.deblocal.crt.

Перенос созданных файлов сертификата в системные папки

Полученные файлы необходимо разместить в подходящие для них системные каталоги.

Копируем сам сертификат:

$ sudo cp db.deblocal.crt /etc/ssl/certs/

Копируем ключ сертификата:

$ sudo cp db.deblocal.key /etc/ssl/private/

Удаляем файлы, которые были созданы в процессе формирования сертификата:

$ rm db.deblocal.*

Настройка Apache2 для работы с SSL

Создание каталога для виртуального хоста db.deblocal

Вообще говоря, создание каталога для виртуального хоста в каталоге /var/www, считается неправильным. На рабочем сервере необходимо запускать модуль userdir и размещать все виртуальные каталоги в папках соответствующих пользователей. Но наша машина локальная, работаем по-быстрому, поэтому заморачиваться не будем. Просто выполняем команду:

$ sudo mkdir /var/www/db.deblocal

Теперь создадим индексный файл, который можно будет увидеть, когда все настроим успешно и наберем адрес https://db.deblocal/. Для этого выполняем команду:

echo DB Test is Ok! > /var/www/db.deblocal/index.html

Активируем модуль для работы Apache с сертификатами SSL

Все доступные модули Apache располагаются в каталоге /etc/apache2/mods-available

$ cd /etc/apache2/mods-available
$ sudo ln -s ../mods-available/ssl.load ../mods-enabled/ssl.load
$ sudo ln -s ../mods-available/ssl.conf ../mods-enabled/ssl.conf

Создание конфигурационного файла виртуального хоста для db.deblocal

Конфигурационные файлы виртуальных хостов Apache находятся в каталоге /etc/apache2/sites-available. Создадим в этом каталоге новый конфигурационный файл:

$ cd /etc/apache2/sites-available
$ sudo nano db.deblocal

Откроется редактор с нашим новым файлом. Описываем наш конфигурационный файл как показано ниже:

<IfModule mod_ssl.c>
<VirtualHost *:443>
        ServerAdmin webmaster@localhost
        ServerName db.deblocal
        DocumentRoot /var/www/db.deblocal
        <Directory /var/www/db.deblocal>
                Options Indexes FollowSymLinks MultiViews
                AllowOverride None
                Order allow,deny
                allow from all
        </Directory>

        ErrorLog /var/log/apache2/db.deblocal-error.log
        LogLevel error

        CustomLog /var/log/apache2/db.deblocal-access.log combined

        SSLEngine on
        SSLCertificateFile    /etc/ssl/certs/db.deblocal.crt
        SSLCertificateKeyFile /etc/ssl/private/db.deblocal.key

        <FilesMatch "\.(cgi|shtml|phtml|php)$">
                SSLOptions +StdEnvVars
        </FilesMatch>

        BrowserMatch ".*MSIE.*" \
                nokeepalive ssl-unclean-shutdown \
                downgrade-1.0 force-response-1.0

</VirtualHost>
</IfModule>

Активируем созданную конфигурацию виртуального хоста и перезапускаем наш сервер.

$ sudo ln -s ../sites-available/db.deblocal ../sites-enabled/db.deblocal
$ sudo /etc/init.d/apache2 restart

Если все сделано верно, Apache перезагрузится без ошибок. Максимум — получите предупреждение, что он не может распознать имя по вашему IP, но на это можно пока не обращать внимания.

Финальная проверка

Проверка проста: запускаем обозреватель и в строке адреса пишем:

https://db.deblocal/

Жмем Enter и у вас должны начать появляться запросы на одобрение сертификатов. Если заглянуть в сведения сертификата, увидим те данные, которые мы вводили при генерации нашего файла сертификата. На некоторых обозревателях можете получить предупреждение системы безопасности о поддельном сертификате, но переживать не стоит. Такие предупреждения связаны с тем, что мы сертификат сформировали сами и нигде не регистрировали.

В конечном итоге, если прошло все нормально, на экране должна появится надпись DB Test is Ok!, которую мы вводили во временный index.html.

Если соединение не происходит, значит по мере настройки допущены ошибки. Читайте статью сначала и ищите где допустили ошибку.

11 комментария(ев) для “Настройка виртуальных хостов для Apache 2 с поддержкой SSL (https) в Linux Debian

  1. Приветствую, не знаю когда была написана статья, но задам вопрос.

    Как добавить еще один виртуальный хост, но так, чтобы при заходе по https://сайт2.ру открывался именно SSL сайт2.ру, а не SSL сайт1.ру (а при заходе на первый сайт, открывался первый)?

    А то я пробовал, мучался, но не смог добиться того, чтобы отрывался нужный сайт с SSL, у меня получается что при любом домене через https, открывается первый сайт.. т.е. домен в адресной строке отображается как https://сайт2.ру, а на деле показывает содержимое https://сайт1.ру….

    И еще, можно ли отключить к примеру у третьего вирт.хоста SSL, т.е. чтобы при заходе по https://сайт3.ру, не открывался никакой другой, или еще лучше, был редирект на обычный сайт3.ру (который без SSL)

    з.ы. возможно пригодиться инфа:
    ОС Debian 7.1, Apache2, одна сетевая карта, интернет через роутер, локальный IP 192.168.1.110, роутера 192.168.1.1

    1. Приветствую.

      Вероятнее всего проблема с неправильным указанием имени домена в директиве ServerName или не на тот каталог указывает директива DocumentRoot.

      Строго говоря, у вас должно быть два файла виртуальных хостов:

      первый файл:

      <IfModule mod_ssl.c>
      <VirtualHost *:443>
      ServerName site1.ru
      DocumentRoot /var/www/site1.ru
      </VirtualHost>
      </IfModule>

      второй файл:

      <IfModule mod_ssl.c>
      <VirtualHost *:443>
      ServerName site2.ru
      DocumentRoot /var/www/site2.ru
      </VirtualHost>
      </IfModule>

      Недостающие директивы по аналогии из примера в статье. Полный список не стал приводить.

      Еще вариант — проблема с роутером. Если он настроен на трансляцию трафика, то бывают ситуации, когда он не передает информацию о доменных именах. Тогда при любых запросах будет отображаться первый попавшийся сайт согласно правилам сортировки файловой системы вышей ОС. Чтоб проверить в этом ли дело, нужно подключить еще дефолтный виртуальный хост с отключенным распознаванием имен. Тогда при ошибочной трансляции роутера будет идти запрос именно на дефолтный хост.

  2. Не ожидал получить такой быстрый ответ, респект -)

    Прописал настройки для второго домена для ssl (до этого писал, но чет не прокатывало), и еще дописал в /etc/apache2/port.conf строку «NameVirtualHost *:443» в секцию:

    # If you add NameVirtualHost *:443 here, you will also have to change
    # the VirtualHost statement in /etc/apache2/sites-available/default-ssl
    # to
    # Server Name Indication for SSL named virtual hosts is currently not
    # supported by MSIE on Windows XP.

    NameVirtualHost *:443
    Listen 443

    И в свойства SSL VHOST (/etc/apache2/sites-*/), дописал под ServerName site.ru ниже строку ServerAlias http://www.site.ru (кстати правильно ли это делать в SSL VHOST конфиге (в обычном там тоже есть алиас)?

    Теперь при заходе на второй домен, отображается второй домен со своим сертификатом (как я и хотел, кстати, как это по совместимости с другим ПО? Вроде где-то читал, что какие-то браузеры не смогут зайти если прописать NameVirtualHost *:443)

    Кстати, нужно ли делать «дефолтный хост» к примеру с чистой страницей, если допустим не прописан SSL у VHOST для какого-то сайта и/или поддомена, ведь при заходе на такой адрес по https, будет отрываться «первый». Или лучше как-то прописать редирект со всех неизвестных апачу доменов с которых на него заходят, на тоже самое (т.е. тот домен, который запросили, даже если его нет), но на «без https://» т.е. на «http://запрошенный_домен_или_поддомен.com». Кстати как это сделать?

    1. Не зайдут на твой виртуальный хост только те, у кого 443 порт закрыт. А таких балбесов осталось крайне мало.

      Виртуальные хосты по SSL и обычные отличаются только портом и сертификатом. Во всем остальном — это такие же сайты. У них отличается только протокол.

      Для дефолтного хоста можешь установить стандартный каталог «/var/www» и будет у тебя отображаться заглушка «It works!».

  3. И еще забыл дописать, можно ли отключить для поддомена или другого вирт.хоста SSL, верней, чтобы при заходе на такой вирт.хост, редиректило на http (но при этом другие сайты, которым нужен SSL, работали как работают и по http и https).. Или если можно, чтобы он не открывался по https, надеюсь понятно написал.

    1. Сделай виртуальный хост обычный на 80 порту. Будет работать по протоколу http и не надо ничего редиректить. У тебя два типа виртуальных хостов: 443 порт — https, 80 порт — http. Друг другу они не мешают.

  4. Спасибо за отличную статью, все получилось! Так держать!

  5. Что такое виртуальный хост? Это такая настройка локального веб-сервера, при которой веб-сервер начинает откликаться на заданное имя, а не только на IP

Комментарии запрещены.