Два домена (при SSL) в одном каталоге

Моя конфигурация apache2 проблематична: у меня есть два веб-сайта на сервере:

  • domain1.tdl
  • domain2.tdl

Один из них (domain2.tdl) должен быть и доступен через порт 443 (с SSL). Все домены должны быть доступны для порта 80. Но когда мы пытаемся получить доступ к domain1.tdl через порт 443, отображаются файлы domain2.tdl. Таким образом, на порт 443, domain2.tdl доступен для domain1.tdl и domain2.tdl. Я не хочу этого!

Моя конфигурация:

domain1.tdl:

<VirtualHost *:80>
  DocumentRoot /home/sites/domain1.tdl/www
  ServerName domain1.tdl
  ServerAlias www.domain1.tdl
  ServerAdmin xxx@mail.com
  RewriteEngine on
  <Directory "/home/sites/domain1.tdl/www">
    AllowOverride All
    allow from all
    Options -Indexes
  </Directory>
</VirtualHost>

<VirtualHost *:443>
  DocumentRoot /home/sites/domain1.tdl/www
  ServerName domain1.tdl
  ServerAlias www.domain1.tdl
  ServerAdmin xxx@mail.com
  RewriteEngine on
  <Directory "/home/sites/domain1.tdl/www">
    AllowOverride All
    allow from all
    Options -Indexes
</Directory>

domain2.tdl:

<VirtualHost *:80>
  DocumentRoot "/home/sites/domain2.tdl/web"
  ServerName domain2.tdl
  ErrorLog /var/log/apache2/site/error_domain2.tdl.log              
  CustomLog /var/log/apache2/site/access_domain2.tdl.log combined
  <Directory "/home/sites/domain2.tdl/web">
    allow from all
    Options -Indexes
  </Directory>
  ServerAlias www.domain2.tdl
</VirtualHost>

<VirtualHost domain2.tdl:443>
  DocumentRoot "/home/sites/domain2.tdl/web"
  ServerName domain2.tdl
  ErrorLog /var/log/apache2/site/error_domain2.tdl.log
  CustomLog /var/log/apache2/site/access_domain2.tdl.log combined

  SSLEngine on
  SSLCertificateFile /etc/ssl/private/domain2.tdl/domain2.tdl.crt
  SSLCertificateKeyFile /etc/ssl/private/domain2.tdl/domain2.tdl.key
  SSLCACertificateFile /etc/ssl/private/domain2.tdl/GandiStandardSSLCA.pem
  SSLVerifyClient None

  <Directory "/home/sites/domain2.tdl/web">
    allow from all
    Options -Indexes
  </Directory>
  ServerAlias www.domain2.tdl
</VirtualHost>

1 ответ

Решение

объяснение

Когда вы используете NameVirtualHosts, Apache будет использовать имя хоста, указанное в заголовке Host:, чтобы определить, к какому из ваших виртуальных хостов вы должны получить доступ. Исторически это было проблематично с SSL - поскольку весь сеанс зашифрован, включая заголовок Host:, Apache должен расшифровать сеанс, прежде чем он сможет определить, какой виртуальный хост использовать. Но информация, необходимая для дешифрования, находится внутри секции VirtualHost, создавая ловушку 22 - apache нужен VirtualHost, но он не может знать, какой именно, поэтому он выберет первый, который найдет.

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

Решение

Во-первых, поскольку вы не хотите, чтобы domain1.tdl был доступен через SSL, вы можете просто удалить VirtualHost:443 раздел для домена1. (Это не решит эту текущую проблему, но вы не должны сохранять конфигурацию, если не хотите ее использовать; в какой-то момент это вызовет у вас проблемы!)

Во-вторых, вам нужно будет создать способ проверки правильности имени хоста после согласования SSL и разрешить трафик только на правильное имя хоста. Самый простой способ - использовать mod_rewrite, выполнить проверку заголовка и отклонить весь трафик без правильного имени хоста. Вот пример:

RewriteEngine On # to turn rewriting on

RewriteCond %{HTTP_HOST} ^(www.)?domain2.tdl   # If http_host doesn't match (www.)domain2.tdl
RewriteRule (.*) http://%{HTTP_HOST}/$1    # then redirect to http for the hostname that was used, keeping the path intact

Если вы предпочитаете просто сообщить им, что доступ не разрешен, вы можете выдать сообщение об ошибке:

RewriteEngine On # to turn rewriting on

RewriteCond %{HTTP_HOST} ^(www.)?domain2.tdl   # If http_host doesn't match (www.)domain2.tdl
RewriteRule (.*) - [F]                     # then issue a "403 Forbidden" error page

Эти команды должны быть внутри директивы VirtualHost для domain2.tdl:443.

Другие вопросы по тегам