![Apache、通配符 SSL 和 mod_rewrite](https://linux22.com/image/517099/Apache%E3%80%81%E9%80%9A%E9%85%8D%E7%AC%A6%20SSL%20%E5%92%8C%20mod_rewrite.png)
我有一个通配符 SSL 证书,它工作正常:
<VirtualHost *:443>
ServerName star.mydomain.com
DocumentRoot /dev/null
SSLEngine On
SSLCertificateFile /etc/httpd/conf.d/star.mydomain.com.crt
SSLCertificateKeyFile /etc/httpd/conf.d/star.mydomain.com.key
SSLCertificateChainFile /etc/httpd/conf.d/star.mydomain.com.gd_bundle.crt
</VirtualHost>
然后我有了在 SSL 端口上监听的各个子域:
<Virtualhost *:80 *:443>
ServerName staging.mydomain.com
DocumentRoot /var/www/staging.mydomain.com/
CustomLog logs/staging.mydomain.com.log combined
AccessFileName .htaccess
DirectoryIndex index.php index.html
</VirtualHost>
<Virtualhost *:80 *:443>
ServerName www.mydomain.com
DocumentRoot /var/www/www.mydomain.com/
CustomLog logs/www.mydomain.com.log combined
AccessFileName .htaccess
DirectoryIndex index.php index.html
</VirtualHost>
这很好。我可以去http://staging.mydomain.com/或者https://staging.mydomain.com/一切都很幸福。
现在的诀窍是,据我所知,在这种配置下没有办法知道请求是否是 SSL。
例如,即使请求是 SSL 请求,所有环境变量都指向非 SSL 请求。我怀疑这是由于 mod_ssl 的实现造成的。
具体来说,我想在虚拟主机中做这样的事情:
RewriteCond %{SERVER_PORT} 80
RewriteCond %{REQUEST_URI} dashboard
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [L]
但是我得到了重定向循环,因为 SERVER_PORT 始终为 80,即使在 SSL 下也是如此。
我也尝试在第一个 star.mydomain.com 虚拟主机中添加 SetEnv IS_SSL 1,但该变量也不能用于 mod_rewrite。
如果不为每个域创建单独的 ssl/非 ssl 虚拟主机,有没有办法实现这一点?
谢谢!
答案1
我建议看看HTTPS
多变的,这应该是当前连接是否使用 HTTPS 的可靠指标。您应该可以执行以下操作:
RewriteCond %{HTTPS} off
RewriteRule ^/dashboard.* https://%{HTTP_HOST}%{REQUEST_URI} [L,R]
我建议使用[R]
标志强制进行外部重定向,因为根据文档,Apache 会检查重定向 URL 中的主机名是否与当前请求中的主机名相同,如果是,它会剥离方案和主机名,并且仅使用 URL 路径进行内部重写(这意味着它会忽略https://
重写规则的一部分)。