apache2 虚拟主机用于 # 个子域名,并重写为 SSL

apache2 虚拟主机用于 # 个子域名,并重写为 SSL

我在设置 Apache Web 服务器以仅通过 https 提供页面时遇到了一些问题。我想我本周早些时候解决了这个问题,但经过一番调整后,似乎我又把它搞砸了,我不知道具体是什么时候搞砸的。

我的设置产生了这个输出,因此我的配置语法应该没问题:

# apache2ctl -t -D DUMP_VHOSTS
VirtualHost configuration:
192.168.0.1:80         is a NameVirtualHost
default server cal.example.com (/etc/apache2/sites-enabled/99-davical:2)
port 80 namevhost cal.example.com (/etc/apache2/sites-enabled/99-davical:2)
port 80 namevhost proius.example.com (/etc/apache2/sites-enabled/proius:1)
port 80 namevhost slnew.example.com (/etc/apache2/sites-enabled/slnew:1)
port 80 namevhost webmail.example.com (/etc/apache2/sites-enabled/webmail:1)
192.168.0.1:443        is a NameVirtualHost
default server proius.example.com (/etc/apache2/sites-enabled/proius:10)
port 443 namevhost proius.example.com (/etc/apache2/sites-enabled/proius:10)
port 443 namevhost slnew.example.com (/etc/apache2/sites-enabled/slnew:10)
port 443 namevhost webmail.example.com (/etc/apache2/sites-enabled/webmail:10)
192.168.0.1:8443       is a NameVirtualHost
default server cal.example.com (/etc/apache2/sites-enabled/99-davical:11)
port 8443 namevhost cal.example.com (/etc/apache2/sites-enabled/99-davical:11)
Syntax OK

所有我的虚拟主机的定义如下:

<VirtualHost slnew.example.com:80>
 ServerName      slnew.example.com
 ServerAdmin     [email protected]
 DocumentRoot    /var/www/slnew
 RewriteEngine   On
 RewriteLogLevel 0
 RewriteRule     ^/(.*) https://slnew.example.com:443/$1 [L,R]
</VirtualHost>
<VirtualHost slnew.example.com:443>
 ServerName      slnew.example.com
 ServerAdmin     [email protected]
 DocumentRoot /var/www/slnew
 <Directory /var/www/slnew>
  Options Indexes FollowSymLinks MultiViews
  AllowOverride All
  Order allow,deny
  allow from all
 </Directory>
 LogLevel info
 ErrorLog ${APACHE_LOG_DIR}/slnew_error.log
 CustomLog ${APACHE_LOG_DIR}/slnew_access.log combined
 SSLEngine               on
 SSLCertificateFile      /etc/ssl/certs/ssl-cert-snakeoil.pem
 SSLCertificateKeyFile   /etc/ssl/private/ssl-cert-snakeoil.key
 SSLProtocol             -all +SSLv3 +TLSv1
 SSLCipherSuite          SSLv3:+HIGH:+MEDIUM
 <FilesMatch "\.(cgi|shtml|phtml|php)$">
  SSLOptions +StdEnvVars
 </FilesMatch>
 <Directory /usr/lib/cgi-bin>
  SSLOptions +StdEnvVars
 </Directory>
 BrowserMatch "MSIE [2-6]" \
 nokeepalive ssl-unclean-shutdown \
 downgrade-1.0 force-response-1.0
 BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown
</VirtualHost>

当我访问我的网站时,我在 Google Chrome 中收到此错误:

Error 107 (net::ERR_SSL_PROTOCOL_ERROR): SSL protocol error.

答案1

您不能在同一个 IP:端口组合上运行多个基于 SSL 名称的虚拟主机。

Apache 无法知道您想要哪一个,因为 Host: 标头直到安全通道建立后才会发送,而要建立安全通道,Apache 必须选择要使用的证书。这是一个先有鸡还是先有蛋的问题。

但除此之外,您尝试通过 SSL 连接访问 HTTP 内容,这会产生您报告的错误。这与证书问题不同。

规则 #0:永远不要在虚拟主机定义中使用主机名。永远不要。

规则 1:当可以使用其他方法时,请勿使用重写。

在将 HTTP 重定向到 HTTPS 的情况下,您可以创建与 SSL 虚拟主机一样多的 HTTP(端口 80)虚拟主机,然后为每个虚拟主机重定向到 SSL 版本。

您似乎已经实现了 80%,然后放弃了,并认为使用重写是一个合适的解决方案:)

相反,将以上所有内容替换为:

<VirtualHost *:80>
  ServerName slnew.example.com
  Redirect Permanent / https://slnew.example.com/
</Virtualhost>

现在 SSL 部分至少不会再导致错误,但对于每个不是所选证书的规范 CN 的 SSL 虚拟主机,您都会收到证书警告(apache 将始终选择在第一的SSL 虚拟主机。

如果您确实希望它正常工作,每个 vhost 都需要有自己的 IP,您可以在 Virtualhost 定义中使用该 IP:

<Virtualhost 55.66.77.88:443>
  ServerName slnew.example.com

ETC。

相关内容