Apache、通配符 SSL 和 mod_rewrite

Apache、通配符 SSL 和 mod_rewrite

我有一个通配符 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://重写规则的一部分)。

相关内容