如何停止重写以强制 https 影响所有子域

How do I stop the rewrite to force https from affecting all the subdomains

我有这条规则可以将所有 http 连接切换到 https。编辑以显示整个文件

RewriteEngine on
RewriteCond %{HTTP_HOST} ^www\.example\.kiwi$ [OR]
RewriteCond %{HTTP_HOST} ^example\.nz$ [OR]
RewriteCond %{HTTP_HOST} ^www\.example\.nz$
RewriteRule ^/?$ "https\:\/\/example\.kiwi\/" [R=301,L]
RewriteCond %{HTTP_HOST} ^example\.app$ [OR]
RewriteCond %{HTTP_HOST} ^www\.example\.app$
RewriteRule ^/?$ "https\:\/\/example\.kiwi\/" [R=301,L]
RewriteCond %{HTTP_HOST} ^example\.online$ [OR]
RewriteCond %{HTTP_HOST} ^www\.example\.online$
RewriteRule ^/?$ "https\:\/\/example\.kiwi\/" [R=301,L]
RewriteCond %{HTTP_HOST} ^example\.software$ [OR]
RewriteCond %{HTTP_HOST} ^www\.example\.software$
RewriteRule ^/?$ "https\:\/\/example\.kiwi\/" [R=301,L]

RewriteCond %{HTTPS} !=on
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301,NE]
Header always set Content-Security-Policy "upgrade-insecure-requests;"
Header always setifempty Strict-Transport-Security "max-age=31536000" env=HTTPS
Header append X-Frame-Options: "SAMEORIGIN"

不幸的是,它会影响 mail.domain.com(以及其他)之类的东西。如何停止升级 any/all 个子域?

假设您只想将 www 子域和域顶点重定向到 HTTPS,那么您可以在 RewriteCond 指令中检查 Host header。

例如:

RewriteCond %{HTTP_HOST} ^(www\.)?example\.com [NC]
RewriteCond %{HTTPS} !=on 
RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301,NE]

以上只会重定向www.example.comexample.com

我已经删除了 RewriteRule 模式 中的捕获组(即 ^(.*)$),因为这里没有使用它。

使用 302(临时)重定向进行测试以避免缓存问题。

您需要在测试前清除浏览器缓存。

同时考虑在重定向中规范化主机名(www 与 non-www)。

Header always set Content-Security-Policy "upgrade-insecure-requests;"

但是,由于现在并非所有内容都是 HTTPS,如果您通过 HTTP 从子域加载资源,那么应该根据是否有条件地发送此 header请求是通过 HTTPS 开始的。

例如,在 Apache 2.4.10+ 上,您可以在 Header 指令中使用 Apache 表达式语法:

Header always set Content-Security-Policy "upgrade-insecure-requests;" "expr=%{HTTPS} == 'on'"

更新:

I want different suffixes to work such as example.software and example.app, so should I replace the ".com" with ".?"

您可以简单地删除第一个 条件 中正则表达式中的 TLD。例如:

RewriteCond %{HTTP_HOST} ^(www\.)?example\. [NC]

这将匹配 example.comexample.softwarewww.example.app 等。但如果您碰巧有一个与域本身同名的子域(例如 example.example.com) - 但应该避免这种情况。

I have edited the post to show my whole file, in case there are side-effects. I have a number of domains that are all being redirected for the moment while the website is getting constructed.

这不会影响 HTTP 到 HTTPS 的重定向。这些指令将所有其他域重定向到 https://example.kiwi - 因此,当处理这些指令时,后面的 HTTP 到 HTTPS 重定向无论如何都会被绕过(不需要)。

但是,这些重定向存在一些问题。

  • “暂时重定向”- 您暗示这些重定向是临时的,但您使用的是 301(永久)响应。这会导致重定向被永久缓存,这是不可能撤消的。如果这是临时的,那么它应该是 302(临时)重定向。
  • ^/?$ - 您只是重定向对文档根目录(即主页)的请求。 example.nz/foo 的请求不会被重定向。这进一步看起来像一个错误,因为您在 substitution 字符串中使用了 </code> 反向引用,因此该字符串将始终为空。</li> </ul> <p>这些重定向指令也可以大大简化。如果您“暂时”将所有其他域重定向到 <code>https://example.kiwi/<url>,那么您可以使用这样的单个规则来完成:

    RewriteCond %{HTTP_HOST} !=example.kiwi
    RewriteRule ^ https://example.kiwi%{REQUEST_URI} [R=302,L]
    

    其中 !=example.kiwinegated 精确匹配字符串比较(不是正则表达式)。 条件成功则Hostheader不匹配example.kiwi.


    旁白:

    Header always setifempty Strict-Transport-Security "max-age=31536000" env=HTTPS
    

    您不应该在开发和更改域时实施 HSTS。但是,您似乎没有在发布的代码中设置 HTTPS env var,所以这很可能会被忽略。 (?)

    注意:env=HTTPS 没有检查同名的 server 变量。