Два домена (при 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.