我正在尝试使用自己的 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>