编辑:我从虚拟主机中取出了两个不起作用的域的重定向线。重新启动 Apache 后,两个站点的 HTTP 和 HTTPS 版本都按预期工作,但它不再自动重定向(显然)。但这些完全相同的重定向规则对于 sidmandesign.com 来说效果很好
我正在使用 Ubuntu 将我的 Web 服务器从 IIS 服务器迁移到 LAMP 堆栈。我使用 certbot 为我的三个域安装了三个 SSL 证书。 Certbot 在 virtualhosts 目录中添加了一个 -le-ssl.conf 文件,因此我现在已经在其中(全部位于 /etc/apache2/sites-enabled/ 目录中,并在 apache.conf 中正确包含):
sidmandesign.conf:
<VirtualHost *:80>
ServerName www.sidmandesign.com
ServerAlias sidmandesign.com
DocumentRoot "/var/www/html/Sidman Designs/"
RewriteEngine on
RewriteCond %{SERVER_NAME} =sidmandesign.com [OR]
RewriteCond %{SERVER_NAME} =www.sidmandesign.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>
sidmandesign-le-ssl.conf:
<VirtualHost *:443>
ServerName www.sidmandesign.com
ServerAlias sidmandesign.com
DocumentRoot "/var/www/html/Sidman Designs"
Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateFile /etc/letsencrypt/live/sidmandesign.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/sidmandesign.com/privkey.pem
</VirtualHost>
augustinebuilders.conf:
<VirtualHost *:80>
ServerName www.augustinebuilders.com
ServerAlias augustinebuilders.com
DocumentRoot "/var/www/html/augustine/"
RewriteEngine on
RewriteCond %{SERVER_NAME} =augustinebuilders.com [OR]
RewriteCond %{SERVER_NAME} =www.augustinebuilders.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>
augustinebuilders-le-ssl.conf:
<VirtualHost *:443>
ServerName www.augustinebuilders.com
ServerAlias augustinebuilders.com
DocumentRoot "/var/www/html/augustine"
Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateFile /etc/letsencrypt/live/augustinebuilders.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/augustinebuilders.com/privkey.pem
</VirtualHost>
salvgedserendipity.conf:
<VirtualHost *:80>
ServerName www.salvagedserendipity.com
ServerAlias salvagedserendipity.com
DocumentRoot "/var/www/html/salvagedserendipity/"
RewriteEngine on
RewriteCond %{SERVER_NAME} =salvagedserendipity.com [OR]
RewriteCond %{SERVER_NAME} =www.salvagedserendipity.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>
salvgedserendipity-le-ssl.conf:
<VirtualHost *:443>
ServerName www.salvagedserendipity.com
ServerAlias salvagedserendipity.com
DocumentRoot "/var/www/html/salvagedserendipity"
Include /etc/letsencrypt/options-ssl-apache.conf
SSLCertificateFile /etc/letsencrypt/live/salvagedserendipity.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/salvagedserendipity.com/privkey.pem
</VirtualHost>
Sidmandesign.com 工作正常,它重定向到 HTTPS,我可以看到一切。然而,当我尝试其他两个网站时,它们重定向到 HTTPS,但我在 Chrome 中收到 ERR_TOO_MANY_REDIRECTS,并且通用无法在 Edge/IE 中显示此页面。
您知道为什么当配置看起来相同时一个域可以工作但其他两个域却不能吗?
您的
RewriteCond
语法
在您的 *:80 VirtualHost 中,删除
RedirectCond
和 RewriteRule
指令并添加(好吧,根据您的域进行调整!):
Redirect permanent / https://www.example.com
无需验证域名是否匹配,如果域名与
ServerName
或 ServerAlias
指令值匹配,Apache 只会使用该 VirtualHost 中的配置。
还有一点,
RewriteCond
不需要=
标志(以备将来参考):
RewriteCond %{SERVER_NAME} ^www.example.com$
删除 VirtualHost 中的
DocumentRoot
*:80
由于您从不为 *:80 VirtualHost 提供任何内容,因此您应该删除
DocumentRoot
指令。
多个 SSL 虚拟主机问题
对于端口 80,定义多个 VirtualHost 没有问题。 Apache 将查看请求的域并使用匹配的配置。
但对于 SSL 来说,这不起作用。在与浏览器完成 SSL 证书协商之前,Apache 无法读取请求的域。那么它有什么作用呢?它使用它找到的第一个 *:443 VirtualHost。 解决这个问题的方法是:
https://www.example.com
发送至
apache:443
,https://www.example2.com
发送至 apache:444
,依此类推。但这需要在流量到达 Apache 之前完成。在 Apache 中使用 SNI (
端口 80 上的请求
http://<SOMEDOMAIN>
此 VH 将其重定向到端口 443 上的
https://<SOMEDOMAIN>
始终使用第一个 VH,因此证书
/etc/letsencrypt/live/sidmandesign.com/fullchain.pem
浏览器因此会看到一个域的证书,该证书与所请求的域不匹配(除了第一个域之外)。
对于“Chrome 中的 ERR_TOO_MANY_REDIRECTS”,请查看控制台(F12,“网络”选项卡,选中“保留日志”)。您将看到 Chrome 获得的每个重定向。这样你就会看到什么是循环的。我的猜测是“=”符号把事情搞砸了。
这个答案可能不适合 OP 问题,但我的 WordPress 网站有一个非常相似的问题。所以将此视为对 Nic3500 答案的补充。 在尝试修复它一段时间后,我意识到在 WordPress 中可以设置站点 URL。
问题是,wordpress 将重定向回 example.com,因此创建了一个重定向循环。 将站点 URL 更改为 www.example.com 后,它会按预期工作。