Apache多域名多子域名虚拟主机配置问题求助
看起来你遇到的是Apache虚拟主机匹配逻辑+SSL证书结合的典型问题,我帮你拆解下根源和解决方案:
首先解决最头疼的SSL证书警告问题
你现在访问http://blupp.example.org跳转到HTTPS后出现证书错误,核心原因是:你之前申请的Let's Encrypt证书只包含example.org和指定的几个子域(比如cloud.example.org),不覆盖所有*.example.org泛子域。浏览器会认为证书和当前访问的域名不匹配,所以弹出警告。
解决办法是给每个主域名申请泛域名证书:
用certbot执行以下命令(确保你已经安装了certbot的Apache插件):
# 给example.org申请泛域名证书,包含主域名和所有子域 certbot certonly --apache -d example.org -d *.example.org # 给beispiel.de同理申请泛域名证书 certbot certonly --apache -d beispiel.de -d *.beispiel.de
申请过程中会引导你完成域名所有权验证,跟着提示操作就行。
调整虚拟主机配置,解决重定向和域名混淆问题
Apache虚拟主机是按配置文件加载顺序匹配的,先匹配到符合ServerName/ServerAlias的规则就会停止,所以我们要把「具体子域的配置」放在「泛域名配置」前面,避免泛规则覆盖正常子域。
1. 调整配置文件命名顺序
你已经用数字前缀命名了,比如1_cloud-le-ssl.conf,那把泛域名的配置文件命名成更大的数字,比如20_example-org-wildcard.conf、21_beispiel-de-wildcard.conf,这样Apache会先加载具体子域的配置。
2. 配置example.org的泛域名HTTPS虚拟主机
创建20_example-org-wildcard.conf,内容如下:
<IfModule mod_ssl.c> <VirtualHost *:443> ServerName example.org ServerAlias *.example.org # 排除已经有独立配置的子域,防止被错误重定向 RewriteCond %{HTTP_HOST} !^cloud\.example\.org$ RewriteCond %{HTTP_HOST} !^wiki\.example\.org$ # 强制重定向到主域名,保留请求路径(不需要的话可以去掉$1) RewriteRule ^(.*)$ https://example.org$1 [R=301,L] # 替换成你刚申请的泛域名证书路径 SSLCertificateFile /etc/letsencrypt/live/example.org/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/example.org/privkey.pem Include /etc/letsencrypt/options-ssl-apache.conf </VirtualHost> </IfModule>
3. 配置beispiel.de的泛域名HTTPS虚拟主机
创建21_beispiel-de-wildcard.conf,内容如下:
<IfModule mod_ssl.c> <VirtualHost *:443> ServerName beispiel.de ServerAlias *.beispiel.de # 排除已经有独立配置的blog子域 RewriteCond %{HTTP_HOST} !^blog\.beispiel\.de$ # 强制重定向到beispiel.de主域名 RewriteRule ^(.*)$ https://beispiel.de$1 [R=301,L] # 替换成beispiel.de的泛域名证书路径 SSLCertificateFile /etc/letsencrypt/live/beispiel.de/fullchain.pem SSLCertificateKeyFile /etc/letsencrypt/live/beispiel.de/privkey.pem Include /etc/letsencrypt/options-ssl-apache.conf </VirtualHost> </IfModule>
4. 优化全局HTTP转HTTPS的配置
你的0_redirects.conf可以调整得更严谨一点,确保所有HTTP请求都正确跳转到对应HTTPS地址:
<VirtualHost *:80> RewriteEngine On # 重定向到当前域名的HTTPS版本,保留请求路径 RewriteRule ^(.*)$ https://%{HTTP_HOST}$1 [R=301,L] </VirtualHost>
最后验证配置并重启服务
- 先检查Apache配置是否有语法错误:
# Ubuntu/Debian系统 apache2ctl configtest # CentOS/RHEL系统 httpd -t - 如果输出
Syntax OK,就重启Apache:systemctl restart apache2 # 或者 systemctl restart httpd
问题根源复盘
- 证书警告:普通证书不覆盖泛子域,泛域名证书才能解决这个问题;
- 域名混淆:当Apache找不到匹配
beispiel.de子域的虚拟主机时,会默认使用第一个加载的虚拟主机(也就是example.org的),现在给beispiel.de配置独立的泛域名虚拟主机后,就会优先匹配它; - 重定向URL异常:之前用
Redirect permanent指令没有明确指定目标域名的HTTPS,且会保留原主机头,用RewriteRule可以精准控制重定向后的URL。
备注:内容来源于stack exchange,提问作者edwarddeath

