我希望 Apache 上的域名纯粹作为重定向存在。为此,我创建了/etc/apache2/sites-available/redirect.example.info.conf以下内容:

<VirtualHost *:80>
    ServerName redirect.example.info
    ServerAdmin webmaster@localhost
    Redirect / https://example.com/

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

当我运行时certbot --apache,它被重写为:

<VirtualHost *:80>
    ServerName redirect.example.info
    ServerAdmin webmaster@localhost
    Redirect / https://example.com/

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined

RewriteEngine on
RewriteCond %{SERVER_NAME} =redirect.example.info
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>

/etc/apache2/sites-available/redirect.example.info-le-ssl.conf并创建一个新文件:

<IfModule mod_ssl.c>
<VirtualHost *:443>
    ServerName redirect.example.info
    ServerAdmin webmaster@localhost
    Redirect / https://example.com/

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined

SSLCertificateFile /etc/letsencrypt/live/ca-webs.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/ca-webs.com/privkey.pem
Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
</IfModule>

这确实按预期工作。重定向运行http://redirect.example.infohttps://redirect.example.infohttps://example.com。但我不清楚它是如何工作的。重写的文件既有Redirect命令,又有RewriteRule命令,我本以为Redirect(先来)会优先。这个文件实际上是如何评估的?


最佳答案
1

据我所知,certbot --apache它不会对现有的 HTTP VirtualHost 进行严格检查,它只是复制所有现有指令并添加 TLS 指令以生成新的 HTTPS VirtualHost。

然后修改普通的 HTTP VirtualHost 以包含条件 HTTP –> HTTPS 重定向(仅重定向 certbot 已为其配置证书的 URI)。

生成的配置适用于大多数用例,但对于您而言,结果并不理想,我建议您手动编辑纯 HTTP 虚拟主机。删除Rewrite*certbot 添加的指令并恢复到原始配置,将访问者直接从 发送到 ,http://redirect.example.infohttps://example.com防止中间重复访问https://redirect.example.info


至于为什么Rewrite*指令虽然出现在Redirect指令之后却具有优先权:这是因为有效的 apache httpd 配置不仅仅是配置指令放置和分组的位置、顺序和容器的结果,还取决于指令属于哪个模块。

的“合并”部分中并不明显

模块和配置节之间的关系

在阅读配置部分如何合并后,经常会出现的一个问题与特定模块(如 mod_rewrite)的指令如何以及何时处理有关。答案并不简单,需要一些背景知识。每个 httpd 模块管理自己的配置,并且其每个指令在httpd.conf特定上下文中指定一个配置。httpd 在读取命令时不会执行命令。

在运行时,httpd 的核心会按照上述顺序迭代已定义的配置部分,以确定哪些配置部分适用于当前请求。当第一个部分匹配时,它将被视为此请求的当前配置。如果后续部分也匹配,则每个在任一部分中具有指令的模块都有机会将其配置合并到两个部分之间。结果是第三个配置,并且该过程继续进行,直到评估了所有配置部分。

完成上述步骤后,HTTP 请求的“真正”处理就开始了:每个模块都有机会运行并执行它们想要的任何任务。它们可以从 httpd 的核心中检索自己的最终合并配置,以确定它们应该如何行动。

对于 mod_rewrite 来说,微妙的细节可能在于这句话“每个模块都有机会运行并执行它们喜欢的任何任务”

模块可以/必须通过
注册自己 ,以便能够在正确的时刻“做它们喜欢的事情”,mod_rewrite 使用它来首先(或至少提前)使用APR_HOOK_FIRST钩子

据我所知,这就是Rewrite*指令优先于其他指令的方式,无论其他指令的排序方式和位置如何。

来了解钩子和所有启用的模块及其顺序(不要忘记将 ACL 添加到服务器信息 URL)。