背景:我们已将 2 台旧 Web 服务器迁移到 2 台新的、更强大的服务器 - Ubuntu 17.04 和 18.04。我们为我们托管的域(约 20 个)购买了 Thawte SSL 证书,以便在 2 台服务器上使用。每台服务器都有自己的单个静态 IP 地址。
证书以 Common Name 的形式配置www.example.org和替代名称www.example.org,示例网站,www2.example.org
17.04 服务器拥有“www2”子域。SSL 证书已设置,一切正常 - 提供 https 且没有证书不匹配
我设置了包含我们“www”的 18.04 服务器,并尝试镜像设置。经过反复尝试(忘记 a2enmod 标头、.conf 文件中的语法 vhost 错误),我获得了第一个提供 https 的域
但是,当我配置下一个域的 .conf vhost 时,启用 SNI 的浏览器会给出错误,提示该网站正在使用第一个域的证书。我在 Google 上搜索并进行了实验,检查了我的语法和路径 - 我卡住了。
有趣的是,当我使用 SSL 验证工具时,它们会报告第二个域通过了,并且似乎报告了证书的正确域所有权。但是所有浏览器(网络内外)都会报告错误。如果我忽略错误并继续,它会带我到第一个域。
每个域在 /etc/apache2/sites-available 中都有自己的 .conf 文件。我读到有人建议将所有虚拟主机放在 1 个 .conf 上 - 我尝试了,结果相同,但第二个域当时没有通过 SSL 测试。
似乎我的第二个域名正在返回第一个域名的证书,从我读到的内容来看,它应该对所有其他域名都这样做。但这些网站是实时的,我不能(也不应该)在测试时关闭它们。我使用访问量最少的网站作为第二个域名的示例。有人建议这可能是缓存问题,问题在几个小时后自行解决。我不禁想到我错过了一些使用 SNI 的服务器设置,但 Apache 2.4 据称开箱即用
来自 ports.conf
Listen 80
<IfModule ssl_module>
Listen 443
</IfModule>
<IfModule mod_gnutls.c>
Listen 443
</IfModule>
来自 example.conf
<VirtualHost *:80>
ServerName www.example.org
ServerAlias example.org www4.example.org
ServerAdmin [email protected]
Redirect 301 "/" "https://www.example.org/"
</VirtualHost>
<IfModule ssl_module>
SetEnvIf HTTPS https HTTPS=on
Header always set Strict-Transport-Security "max-age=63072000" env=HTTPS
Header always set Content-Security-Policy: upgrade-insecure-requests env=HTTPS
Header always set X-XSS-Protection: "1; mode=block"
Header always set X-Frame-Options: sameorigin
Header always set X-Content-Type-Options: nosniff
Header always set X-Permitted-Cross-Domain-Policies: "master-only"
<VirtualHost *:443>
ServerName www.example.org
DocumentRoot /var/www/example/
ServerAdmin [email protected]
SSLEngine on
SSLCertificateFile "/etc/apache2/ssl/crt/www.example.org.crt"
SSLCertificateChainFile "/etc/apache2/ssl/crt/IntermediateCA.example.crt"
SSLCertificateKeyFile "/etc/apache2/ssl/www.example.org.key"
DirectoryIndex index.html index.htm index.php
<FilesMatch "^wp-login\.php$|^wp-admin/.*">
AuthName "Login Login"
AuthType Basic
AuthUserFile /etc/apache2/.htpasswd
Require valid-user
</FilesMatch>
</VirtualHost>
</IfModule>
来自 otherdomain.conf
<VirtualHost *:80>
ServerName www.otherdomain.org
ServerAlias otherdomain.org www4.otherdomain.org
ServerAdmin [email protected]
Redirect 301 "/" "https://www.otherdomain.org/"
</VirtualHost>
<IfModule ssl_module>
SetEnvIf HTTPS https HTTPS=on
Header always set Strict-Transport-Security "max-age=63072000" env=HTTPS
Header always set Content-Security-Policy: upgrade-insecure-requests env=HTTPS
Header always set X-XSS-Protection: "1; mode=block"
Header always set X-Frame-Options: sameorigin
Header always set X-Content-Type-Options: nosniff
Header always set X-Permitted-Cross-Domain-Policies: "master-only"
<VirtualHost *:443>
ServerName www.otherdomain.org
DocumentRoot /var/www/otherdomain/
ServerAdmin [email protected]
SSLEngine on
SSLCertificateFile "/etc/apache2/ssl/crt/www.otherdomain.org.crt"
SSLCertificateChainFile "/etc/apache2/ssl/crt/IntermediateCA.otherdomain.crt"
SSLCertificateKeyFile "/etc/apache2/ssl/www.otherdomain.org.key"
DirectoryIndex index.html index.htm index.php
<FilesMatch "^wp-login\.php$|^wp-admin/.*">
AuthName "Login Login"
AuthType Basic
AuthUserFile /etc/apache2/.htpasswd
Require valid-user
</FilesMatch>
</VirtualHost>
</IfModule>
可能重要的是,“www”网站和服务器是 WordPress 网站。我在将上述 WordPress 网站从 PHP 5.2 环境升级到 7 时使用了“www4”子域名进行测试。网站正确显示后,我将 www 的 DNS(Cloudflare 免费)从旧服务器的静态 IP 地址指向新服务器(Ubuntu18.04)的静态 IP 地址。
我尝试过的事情:
在 ports.conf 中添加 * 通配符
sudo service apache2 restart
sudo service apache2 stop/start
注释我在端口 80 中的重定向 Virtualhost
验证证书路径
等待 6 个多小时
我已经这样做了将近一周,用尽了所有搜索方法,承认失败并寻求帮助。提前致谢。
答案1
不久前,我通过调整顺序终于解决了这个问题。最终适用于我们所有网站的所有 .conf 文件的方法如下:
<VirtualHost *:80>
ServerName www.otherdomain.org
ServerAlias www4.otherdomain.org otherdomain.org
ServerAdmin [email protected]
DocumentRoot /var/www/otherdomain/
Redirect 301 "/" "https://www.otherdomain.org/"
</VirtualHost>
<IfModule ssl_module>
SetEnvIf HTTPS https HTTPS=on
Header always set Strict-Transport-Security "max-age=63072000" env=HTTPS
Header always set Content-Security-Policy: upgrade-insecure-requests env=HTTPS
Header always set X-XSS-Protection: "1; mode=block"
Header always set X-Frame-Options: sameorigin
Header always set X-Content-Type-Options: nosniff
Header always set X-Permitted-Cross-Domain-Policies: "master-only"
<VirtualHost *:443>
ServerName www.otherdomain.org
ServerAlias otherdomain.org
DocumentRoot /var/www/otherdomain/
ServerAdmin [email protected]
SSLEngine on
SSLCertificateFile "/etc/apache2/ssl/crt/www.otherdomain.org.crt"
SSLCertificateChainFile "/etc/apache2/ssl/crt/IntermediateCA.otherdomain.crt"
SSLCertificateKeyFile "/etc/apache2/ssl/www.otherdomain.org.key"
DirectoryIndex index.html index.htm index.php
<FilesMatch "^wp-login\.php$|^wp-admin/.*">
AuthName "Login Login"
AuthType Basic
AuthUserFile /etc/apache2/.htpasswd
Require valid-user
</FilesMatch>
</VirtualHost>
</IfModule>
我不知道在我随后的 conf 文件 vhosts 中使用第一个证书的罪魁祸首具体是什么。
答案2
到 2023 年,仍然存在错误证书的错误,该错误已在https://blog.apnic.net/2020/04/07/the-wrong-certificate-apache-lets-encrypt-and-openssl/原因是 openssl 库的默认行为存在缺陷,不依赖于站点的预期主机名。