mod_rewrite 配置未排除路径

mod_rewrite 配置未排除路径

我正在尝试使用自己的 vhost 配置来处理 certbot/letsencrypt。我想将除对 /.well-known 的请求之外的所有内容重定向到 HTTPS。但 .well-known 的例外不起作用;对http://www.example.com/.well-known/返回 301 重定向到 https。我已在下面的代码中匿名化了主机名。

请注意我遇到了这篇文章/答案在这里发布之前 - 并且那里接受的答案描述了(我相信)我在下面尝试过的第一个配置 - 这让我认为这不是重复的。

<VirtualHost *:80>
    DocumentRoot "/var/www/html"
    ServerName www.example.com

    RewriteEngine on
    RewriteCond %{HTTPS} !=on
    # RewriteRule ^(\.well-known) - [END]
    RewriteCond %{REQUEST_URI} !^\.well-known
    RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]

    # additional auth config elsewhere, hence....
    <Location /.well-known/ >
        Require all granted
    </Location>
</VirtualHost>

如上面的注释所示,我也尝试过:

    RewriteRule ^(\.well-known) - [END]
    # RewriteCond %{REQUEST_URI} !^\.well-known
    RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]

路径上没有 .htaccess 文件,但为了确保万无一失,我禁用了所有重写指令,并获得了 /.well-known/ 和其他请求的 HTTP 200 响应。我正在使用curl -I浏览器进行测试,因此 301 的缓存不是考虑因素。每次更改后,我都会完全重新启动 httpd,而不仅仅是重新加载。

这是 Centos 7 上的 httpd-tools-2.4.6-99。

我如何覆盖默认重定向?

答案1

您缺少前导/,即您使用!^\.well-known而不是!^/\.well-known。最好/也添加尾随 ,以匹配该目录中的内容:!^/\.well-known/

不过,Daniel Ferradal 的回答中的例子是实现相同目标的更正确方法。

另一方面,因为这是 Let's Encrypt 的HTTP-01 挑战,你根本不需要这个条件:

我们对 HTTP-01 挑战的实现遵循重定向——当重定向到 HTTPS URL 时,它不会验证证书(因为此挑战旨在引导有效证书,因此它可能会在此过程中遇到自签名或过期的证书)。

答案2

我会尝试让它变得更简单。

加载 mod_alias 后(您的示例中不需要 mod_rewrite,我倾向于不使用 mod_rewrite,除非真的有必要),并且使用目录而不是位置作为真实目录路径,同样不需要引用路径。

我相信一个更简单的例子就可以满足你的要求:

<VirtualHost *:80>
    DocumentRoot /var/www/html
    ServerName www.example.com

    RedirectMatch ^/(?!\.well-known)(.*) https://yourdomain.example.com/$1
    <Directory /var/www/html/.well-known>
        Require all granted
    </Directory>
</VirtualHost>

相关内容